import { defineStore } from "pinia";
import { ref, computed } from "vue";
import { userStore } from "src/stores/user";
import { getUserPermissions, getGuestPermissions } from "src/api/permission";

export const permissionStore = defineStore("permission", () => {
  const bitwisePermissionTable = Object.freeze({
    view: 1,
    add: 2,
    edit: 4,
    delete: 8,
    print: 16,
    export: 32,
    import: 64,
    limit: 128,
    menu: 256,
  });

  const bitwisePermissions = ref({
    view: 0,
    add: 0,
    edit: 0,
    delete: 0,
    print: 0,
    export: 0,
    import: 0,
    limit: 0,
    menu: 0,
  });

  const originalBitwisePermissions = ref(null);
  const permissions = ref(null);

  const totalBitwisePermissions = computed(() =>
    Object.values(bitwisePermissionTable).reduce((a, b) => a + b),
  );

  const checkTotalPermissions = (permission) => {
    return !!(permission & totalBitwisePermissions.value);
  };

  const checkPermission = (permission, total) => {
    return !!(permission & total);
  };

  const updateBitMasks = (total) => {
    const totalPermissions = totalBitwisePermissions.value;

    const setPermission = (permissionKey, permissionValue) => {
      bitwisePermissions.value[permissionKey] =
        total & permissionValue ? permissionValue : 0;
    };

    if (total & totalPermissions) {
      setPermission("view", bitwisePermissionTable.view);
      setPermission("add", bitwisePermissionTable.add);
      setPermission("edit", bitwisePermissionTable.edit);
      setPermission("delete", bitwisePermissionTable.delete);
      setPermission("print", bitwisePermissionTable.print);
      setPermission("export", bitwisePermissionTable.export);
      setPermission("import", bitwisePermissionTable.import);
      setPermission("limit", bitwisePermissionTable.limit);
      setPermission("menu", bitwisePermissionTable.menu);

      originalBitwisePermissions.value = { ...bitwisePermissions.value };
    } else {
      for (let key in bitwisePermissions.value) {
        bitwisePermissions.value[key] = 0;
      }
      originalBitwisePermissions.value = { ...bitwisePermissions.value };
    }
  };

  const getAccess = (scopeName, permissionType) => {
    const { isAdmin } = userStore();

    if (isAdmin) {
      return true;
    }

    if (permissions.value) {
      let checkPermission = 0;
      const scope = permissions.value.find(
        (permission) => permission.scope === scopeName,
      );

      if (scope) {
        checkPermission = bitwisePermissionTable[permissionType] || 0;
        return scope.bits & checkPermission ? true : false;
      }
    }
    return false;
  };

  const fetchScopes = async () => {
    try {
      const { accessToken } = userStore();
      const response = accessToken
        ? await getUserPermissions()
        : await getGuestPermissions();

      // Rotas bloqueadas para prestador em análise respondem 202 com outro
      // formato de payload; nesse caso o app segue sem escopo algum.
      permissions.value = Array.isArray(response) ? response : null;
    } catch (error) {
      console.error("Error fetching permissions:", error);
    }
  };

  const resetScopes = () => {
    permissions.value = null;
  };

  return {
    bitwisePermissions,
    originalBitwisePermissions,
    totalBitwisePermissions,
    checkTotalPermissions,
    checkPermission,
    updateBitMasks,
    permissions,
    getAccess,
    fetchScopes,
    resetScopes,
  };
});
