"use strict";
const jsxRuntime = require("./jsx-runtime-B6vEU3CM.js");
const React = require("react");
const hooks = require("./hooks-DsdahmnZ.js");
const common = require("./common-B47boGYI.js");
const reactRouterDom = require("react-router-dom");
const api = require("./api-BygscvSz.js");
const routePageMap = require("./route-page-map-CPeFCmDL.js");
const _ = require("lodash");
const material = require("@mui/material");
const notification = require("./notification-lAbbtOBF.js");
const notistack = require("notistack");
const reactI18next = require("react-i18next");
const useAuth = require("./useAuth-vPRkzGjO.js");
const ALLOWED_MODULES = ["hrms", "inventory", "sales", "rental", "manufacturing", "purchase", "accounts-and-finance"];
const HRMS_CRUD_FLAG_MAP = {
  r: { ":nop": "canView", ":param": "canViewById" },
  w: { ":nop": "canAdd", ":param": "canAdd" },
  u: { ":nop": "canEdit", ":param": "canEdit" },
  d: { ":nop": "canDelete", ":param": "canDelete" },
  e: { ":nop": "canEdit", ":param": "canEdit" }
};
function toCamelCase(str) {
  return str.replace(/[^a-zA-Z0-9\s-]/g, " ").split(/[-\s]+/).filter(Boolean).join("");
}
function joinCamelParts(parts) {
  return parts.map((p, i) => i === 0 ? p : p.charAt(0).toUpperCase() + p.slice(1)).join("");
}
function isParamSegment(seg) {
  return seg.startsWith(":");
}
function resolveOperation(operation) {
  if (!operation || operation === ":nop") {
    return { subRoute: null, action: null, hasParam: false };
  }
  const segments = operation.split("/");
  const leadingNamed = [];
  const trailingNamed = [];
  let passedParam = false;
  let hasParam = false;
  for (const seg of segments) {
    if (isParamSegment(seg)) {
      passedParam = true;
      hasParam = true;
    } else {
      const part = toCamelCase(seg);
      if (part) {
        if (!passedParam) {
          leadingNamed.push(part);
        } else {
          trailingNamed.push(part);
        }
      }
    }
  }
  if (leadingNamed.length === 0 && trailingNamed.length === 0) {
    return { subRoute: null, action: null, hasParam };
  }
  const subRoute = leadingNamed.length > 0 ? joinCamelParts(leadingNamed) : null;
  const action = trailingNamed.length > 0 ? joinCamelParts(trailingNamed) : null;
  return { subRoute, action, hasParam };
}
function buildHrmsPermissionTree(raw) {
  var _a, _b, _c, _d;
  const tree = {};
  if (!raw) {
    return tree;
  }
  for (const [rawModuleKey, crudBlock] of Object.entries(raw)) {
    const formattedModule = common.formatLabel(
      rawModuleKey.split("/")[0].replace(/p$/gi, "").replace(/-p-/gi, "-").replace(/-+$/g, "")
      // clean leftover trailing dashes
    ).replace(/[^a-zA-Z0-9]/gi, "");
    const parts = formattedModule.split(/(?=[A-Z])/);
    const moduleKey = parts.slice(0, 2).join("");
    const moduleSubName = parts.slice(2).join("");
    if (!tree[moduleKey]) tree[moduleKey] = {};
    if (!crudBlock || typeof crudBlock !== "object") continue;
    for (const [shortKey, entries] of Object.entries(crudBlock)) {
      const flagMap = HRMS_CRUD_FLAG_MAP[shortKey];
      if (!flagMap) continue;
      const list = Array.isArray(entries) ? entries : [{ ...entries, identity: null }];
      for (const entry of list) {
        const entryModule = (_a = entry == null ? void 0 : entry.identity) == null ? void 0 : _a.module;
        if (entryModule && !ALLOWED_MODULES.includes(entryModule)) continue;
        const operation = ((_b = entry == null ? void 0 : entry.identity) == null ? void 0 : _b.operation) ?? ":nop";
        const { subRoute, action, hasParam } = resolveOperation(operation);
        let targetNode;
        if (moduleSubName) {
          if (!tree[moduleKey][moduleSubName]) {
            tree[moduleKey][moduleSubName] = {};
          }
          const subNameNode = tree[moduleKey][moduleSubName];
          if (subRoute) {
            const subKey = subRoute.charAt(0).toLowerCase() + subRoute.slice(1);
            if (!subNameNode[subKey]) subNameNode[subKey] = {};
            targetNode = subNameNode[subKey];
          } else {
            targetNode = subNameNode;
          }
        } else if (subRoute) {
          const subKey = subRoute.charAt(0).toLowerCase() + subRoute.slice(1);
          if (!tree[moduleKey][subKey]) {
            tree[moduleKey][subKey] = {};
          }
          targetNode = tree[moduleKey][subKey];
        } else {
          targetNode = tree[moduleKey];
        }
        if (action) {
          if (!targetNode.actions) targetNode.actions = {};
          targetNode.actions[action] = true;
        } else {
          const opKey = hasParam ? ":param" : ":nop";
          const flag = flagMap[opKey];
          if (!flag) continue;
          targetNode[flag] = true;
          if (shortKey === "r") {
            const isParamRead = hasParam && !action;
            if (Array.isArray((_c = entry == null ? void 0 : entry.attributes) == null ? void 0 : _c.not_allowed)) {
              if (isParamRead || !targetNode.notAllowedAttributes) {
                targetNode.notAllowedAttributes = entry.attributes.not_allowed;
              }
            }
            if (Array.isArray((_d = entry == null ? void 0 : entry.filters) == null ? void 0 : _d.not_allowed)) {
              if (isParamRead || !targetNode.notAllowedFilters) {
                targetNode.notAllowedFilters = entry.filters.not_allowed;
              }
            }
          }
        }
      }
    }
  }
  return tree;
}
const PermissionsContext = React.createContext(null);
const ROLE_PERMISSION_STORAGE_KEY = "role-permission";
const parseStoredPermissions = (rawValue) => {
  if (!rawValue) {
    return {};
  }
  try {
    const parsedPermissions = JSON.parse(rawValue);
    return parsedPermissions;
  } catch (error) {
    localStorage.removeItem(ROLE_PERMISSION_STORAGE_KEY);
    return {};
  }
};
const PermissionsProvider = ({ children }) => {
  const { setIsPermissionLoaded = false } = hooks.useAppSelector(
    (store) => store.roles ?? {}
  );
  const [storagePermission, setStoragePermission] = React.useState(() => {
    if (typeof window === "undefined") {
      return null;
    }
    return window.localStorage.getItem(ROLE_PERMISSION_STORAGE_KEY);
  });
  React.useEffect(() => {
    if (typeof window === "undefined") {
      return;
    }
    const syncPermissions = () => {
      const latestPermission = window.localStorage.getItem(ROLE_PERMISSION_STORAGE_KEY);
      setStoragePermission(latestPermission);
    };
    const handleStorageChange = (event) => {
      if (!event.key || event.key === ROLE_PERMISSION_STORAGE_KEY) {
        syncPermissions();
      }
    };
    syncPermissions();
    window.addEventListener("storage", handleStorageChange);
    window.addEventListener("role-permission-changed", syncPermissions);
    return () => {
      window.removeEventListener("storage", handleStorageChange);
      window.removeEventListener("role-permission-changed", syncPermissions);
    };
  }, []);
  const permissions = React.useMemo(() => {
    return parseStoredPermissions(storagePermission);
  }, [setIsPermissionLoaded, storagePermission]);
  const computedPermissions = React.useMemo(() => {
    return buildHrmsPermissionTree(permissions);
  }, [permissions]);
  return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(PermissionsContext.Provider, { value: computedPermissions, children });
};
const Loader = notification.styled(material.CircularProgress)(({ theme }) => {
  var _a, _b;
  return {
    color: ((_b = (_a = theme.palette) == null ? void 0 : _a.theme) == null ? void 0 : _b.primary[500]) || "#1976d2"
  };
});
const ErpLoader = (props) => {
  return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(material.Box, { position: "fixed", left: "50%", top: "50%", children: /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(Loader, { size: 50, ...props }) });
};
const initialFilter = { combinator: "and", rules: [] };
const defaultPageState = {
  _id: "",
  name: "",
  page_size: 10,
  column_order: ["id"],
  visible_columns: [],
  views: [],
  active_view: "",
  filters: initialFilter,
  filterQueryString: "",
  sort: null,
  search: "",
  enabled_views: ["Table", "Grid", "Kanban", "Calendar", "Gantt"],
  isShared: false,
  column_sizes: {}
};
const UpdatePageInfo = () => {
};
const UpdateGeneratedColumns = () => {
};
const PageContext = React.createContext({
  pageTemplateId: "",
  activePage: defaultPageState,
  updatePageInfo: UpdatePageInfo,
  loading: false,
  isSaving: false,
  error: null,
  pages: [],
  sharedPages: [],
  savePages: () => {
  },
  setActivePage: () => {
  },
  setPages: () => {
  },
  schemaFields: [],
  initializeColumns: () => {
  },
  generatedColumns: { columns: [], orderKeys: [] },
  updateGeneratedColumns: UpdateGeneratedColumns
});
function mergeArraysKeepingOrder(array1, array2) {
  const array1Set = new Set(array1);
  const elementsToAdd = array2.filter((item) => !array1Set.has(item));
  return [...array1, ...elementsToAdd];
}
const generateColumnSchema = (defaultColumns, schemaFields, columnOrders, dColumns, t) => {
  try {
    if (dColumns && (dColumns == null ? void 0 : dColumns.length)) {
      defaultColumns = defaultColumns.map((column) => {
        const f = dColumns.find((c) => c.accessorKey == column.accessorKey);
        const merged = f ? { ...column, ...f } : column;
        return merged;
      });
    }
    let orderKeys = columnOrders.length ? columnOrders : defaultColumns.map((column) => column.accessorKey);
    const getAccesorKeyViaField = (field) => field.type === "object" || (field == null ? void 0 : field.join) ? `${field.alias}.${field.accessorKey}` : field.key;
    const updatedFields = schemaFields.map((field) => ({
      ...field,
      key: field.key.replace("__replaceKey", "")
    })).filter((field) => !field.is_inner_join);
    const uniqueFields = _.differenceWith(
      updatedFields,
      updatedFields,
      (fieldA, fieldB) => fieldA.key === (fieldB == null ? void 0 : fieldB.joinKey)
    );
    const unmatchedFields = _.differenceWith(
      uniqueFields,
      defaultColumns,
      (field, column) => getAccesorKeyViaField(field) === column.accessorKey
    );
    const additionalColumns = unmatchedFields.map(
      (field) => {
        var _a, _b, _c;
        return {
          header: t ? common.formatLabel(((_a = t(field == null ? void 0 : field.label)) == null ? void 0 : _a.replace("_data", "")) || "") : common.formatLabel(((_b = field == null ? void 0 : field.label) == null ? void 0 : _b.replace("_data", "")) || ""),
          accessorKey: getAccesorKeyViaField(field),
          visible: false,
          type: (field == null ? void 0 : field.enum) ? "status" : field.type,
          ...field.type === "array" && { typeArrayAccessorKey: field.accessorKey || "" },
          enableSorting: field.type === "array" || field.type === "object" || (field == null ? void 0 : field.join) ? false : true,
          ...(field == null ? void 0 : field.type) === "boolean" ? {
            typeBooleanLabels: ((_c = field == null ? void 0 : field.values) == null ? void 0 : _c.length) ? _.mapValues(_.keyBy(
              field == null ? void 0 : field.values.map((item) => ({
                key: item.name,
                value: item.label
              })),
              "key"
            ), "value") : { 0: "Inactive", 1: "Active", false: "Inactive", true: "Active" }
          } : {}
        };
      }
    );
    const updatedDefaultColumns = defaultColumns == null ? void 0 : defaultColumns.map((column) => {
      const field = schemaFields.find((field2) => getAccesorKeyViaField(field2) === column.accessorKey);
      return {
        ...column,
        ...(field == null ? void 0 : field.type) === "object" || (field == null ? void 0 : field.joinKey) || column.enableSorting === false ? { enableSorting: false } : {}
      };
    });
    const columns = [...updatedDefaultColumns, ...additionalColumns];
    const nOrderKeys = columns.map((column) => column.accessorKey);
    orderKeys = mergeArraysKeepingOrder(orderKeys, nOrderKeys);
    return { columns, orderKeys };
  } catch (error) {
    return {
      columns: defaultColumns,
      orderKeys: defaultColumns.map((column) => column.accessorKey)
    };
  }
};
const PageProvider = ({ children, routeToColumnsMap: customRouteToColumnsMap, routeToResourceMap: customRouteToResourceMap }) => {
  console.log("🚀 ~ PageProvider ~ customRouteToResourceMap:", customRouteToResourceMap);
  console.log("🚀 ~ PageProvider ~ customRouteToColumnsMap:", customRouteToColumnsMap);
  const location = reactRouterDom.useLocation();
  const [activePage, setActivePageData] = React.useState(defaultPageState);
  const [schemaFields, setSchemaFields] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [isSaving, setIsSaving] = React.useState(false);
  const [error, setError] = React.useState(null);
  const [pages, setPages] = React.useState([]);
  const [sharedPages, setSharedPages] = React.useState([]);
  const [isChanged, setIsChanged] = React.useState(false);
  const [pageTemplateId, setPageTemplateId] = React.useState("");
  const [isInitialLoad, setIsInitialLoad] = React.useState(true);
  const [isCreatePage, setIsCreatePage] = React.useState(false);
  const [formData, setFormData] = React.useState({});
  const [generatedColumns, setGeneratedColumns] = React.useState({ columns: [], orderKeys: [] });
  const { user } = useAuth.useAuth();
  const currentPathnameRef = React.useRef(location.pathname);
  const curPathName = React.useMemo(() => location.pathname, [location.pathname]);
  const defaultColumns = React.useMemo(() => {
    var _a;
    const columns = ((_a = (customRouteToColumnsMap == null ? void 0 : customRouteToColumnsMap[curPathName]) || routePageMap.routeToColumnsMap[curPathName]) == null ? void 0 : _a.defaultColumns) || [];
    return columns;
  }, [curPathName, customRouteToColumnsMap]);
  const resources = React.useMemo(() => {
    const resource = (customRouteToResourceMap == null ? void 0 : customRouteToResourceMap[curPathName]) || routePageMap.routeToResourceMap[curPathName] || null;
    return resource;
  }, [curPathName, customRouteToResourceMap]);
  const { t } = reactI18next.useTranslation();
  const initializeColumns = (columns) => {
    //! Remove the function if not needed
  };
  const fetchPageData = React.useCallback(
    async (currentPath, currentDefaultColumns, currentResources) => {
      var _a, _b, _c, _d, _e, _f, _g, _h, _i;
      console.log("PageContext: Entering fetchPageData", { currentPath, currentDefaultColumnsLength: currentDefaultColumns == null ? void 0 : currentDefaultColumns.length, hasResources: !!currentResources });
      if (currentPathnameRef.current !== currentPath) {
        console.log("Aborting fetchPageData - pathname changed", { ref: currentPathnameRef.current, current: currentPath });
        return;
      }
      setLoading(true);
      setError(null);
      try {
        console.log("PageContext: Resources Check:", { currentDefaultColumns, currentResources });
        if (currentDefaultColumns.length && currentResources) {
          const { pageResource = "", fieldResource = "", formResource = "" } = currentResources;
          console.log("PageContext: Pathname:", currentPath);
          console.log("PageContext: Default Columns:", currentDefaultColumns);
          console.log("PageContext: Resources:", currentResources);
          if (currentPathnameRef.current !== currentPath) {
            return;
          }
          const [pageResponse, fieldResponse, formResponse] = await Promise.all([
            pageResource ? api.getV1PagesResource({ ...common.getToken(), resource: pageResource }) : Promise.resolve(null),
            api.getV1FormBuilderSchemaFieldsName({
              name: fieldResource,
              ...common.getToken(),
              skip: 0,
              limit: 999
            }),
            api.getV1FormBuilder({
              ...common.getToken(),
              filters: `(resource.eq=${formResource}&company_id.eq=${user == null ? void 0 : user.company_id})`
            })
          ]);
          console.log("PageContext: API Responses:", { pageResponse, fieldResponse, formResponse });
          if (currentPathnameRef.current !== currentPath) {
            console.log("Aborting fetchPageData - pathname changed after API call");
            return;
          }
          const fields = (_b = (_a = fieldResponse == null ? void 0 : fieldResponse.data) == null ? void 0 : _a.fields) == null ? void 0 : _b.map((f) => {
            var _a2;
            return { ...f, label: !((_a2 = f == null ? void 0 : f.label) == null ? void 0 : _a2.trim()) ? common.formatLabel(f.key) : f.label };
          });
          const gColumns = generateColumnSchema(currentDefaultColumns, fields, [], [], t);
          console.log("PageContext: Generated Columns:", gColumns);
          const pages2 = ((_d = (_c = pageResponse == null ? void 0 : pageResponse.data) == null ? void 0 : _c.pages) == null ? void 0 : _d.map((p) => {
            var _a2;
            return {
              ...defaultPageState,
              ...p,
              visible_columns: generateColumnSchema(
                ((_a2 = p.visible_columns) == null ? void 0 : _a2.length) ? p.visible_columns : currentDefaultColumns,
                fields,
                p.column_order || [],
                currentDefaultColumns,
                t
              ).columns,
              column_order: mergeArraysKeepingOrder(
                p.column_order || [],
                _.uniq(gColumns.orderKeys)
              )
            };
          })) || [];
          const sharedPages2 = ((_f = (_e = pageResponse == null ? void 0 : pageResponse.data) == null ? void 0 : _e.shared_pages) == null ? void 0 : _f.map((sPages) => ({
            ...sPages.details,
            isShared: true,
            owner: sPages.owner,
            _id: sPages.id
          }))) || [];
          const uPages = [...pages2, ...sharedPages2];
          if (currentPathnameRef.current === currentPath) {
            await Promise.all([
              setSchemaFields(fields),
              setGeneratedColumns(gColumns),
              setPageTemplateId((_g = pageResponse == null ? void 0 : pageResponse.data) == null ? void 0 : _g._id),
              setSharedPages(sharedPages2),
              setPages(uPages || []),
              setFormData(((_i = (_h = formResponse == null ? void 0 : formResponse.data) == null ? void 0 : _h.form) == null ? void 0 : _i[0]) || {}),
              setActivePageData((prev) => ({
                ...prev,
                ...(pages2 == null ? void 0 : pages2[0]) || {}
                // Merge API response with current state
              }))
            ]);
          }
        }
      } catch (err) {
        if (currentPathnameRef.current === currentPath) {
          setError("Failed to load page data");
        }
      } finally {
        if (currentPathnameRef.current === currentPath) {
          setTimeout(() => {
            setLoading(false);
          }, 1e3);
        }
      }
    },
    //eslint-disable-next-line react-hooks/exhaustive-deps
    []
    // Remove dependencies to prevent stale closures
  );
  const updatePageInfo = (updates) => {
    setActivePageData((prev) => ({
      ...prev,
      ...updates
    }));
    !isInitialLoad && setIsChanged(true);
    setIsInitialLoad(false);
  };
  const updateGeneratedColumns = (updates) => {
    setGeneratedColumns((prev) => ({
      ...prev,
      ...updates
    }));
  };
  const setActivePage = (page) => {
    const uPages = pages.map(
      (p) => p._id == (activePage == null ? void 0 : activePage._id) ? activePage : p
    );
    setPages(uPages);
    setActivePageData(page);
  };
  const savePages = async () => {
    setError(null);
    setIsSaving(true);
    await addOrDeletePage();
    setTimeout(() => {
      setIsSaving(false);
    }, 1e3);
  };
  const fetchSavedFilters = async () => {
    await api.getV1FilterResource({ ...common.getToken(), resource: (resources == null ? void 0 : resources.pageResource) || (resources == null ? void 0 : resources.fieldResource) });
  };
  const addOrDeletePage = async (restPages) => {
    var _a, _b, _c;
    try {
      const filteredPages = (restPages == null ? void 0 : restPages.length) ? restPages : pages.filter((page) => !page.isShared);
      const uPages = filteredPages.map(
        (p) => p._id == (activePage == null ? void 0 : activePage._id) && activePage.name == p.name ? activePage : p
      );
      const sanitizedPages = common.removeIdStaticIdsFromMongoObject(uPages);
      const response = await api.patchV1PagesPageId({
        ...common.getToken(),
        ...{ page_id: pageTemplateId, pages: sanitizedPages }
      });
      if (response.status_code === 200) {
        const updatedPages = ((_a = response == null ? void 0 : response.data) == null ? void 0 : _a.pages) || [];
        setPages(updatedPages);
        fetchSavedFilters();
        setActivePageData((prev) => ({
          ...prev,
          ...updatedPages.find((p) => p.name == prev.name) || {}
        }));
        setIsChanged(false);
        setIsCreatePage(false);
        setFormData(((_c = (_b = response == null ? void 0 : response.data) == null ? void 0 : _b.form) == null ? void 0 : _c[0]) || {});
        const msg = (restPages == null ? void 0 : restPages.length) ? t("pages.msg.delete") : t("pages.msg.save");
        notistack.enqueueSnackbar(msg);
      }
      return response;
    } catch (err) {
      setError("Failed to save page data");
    }
  };
  const deletePage = async (pages2) => {
    addOrDeletePage(pages2);
  };
  React.useEffect(() => {
    currentPathnameRef.current = curPathName;
    setLoading(true);
    setIsSaving(false);
    setActivePageData(defaultPageState);
    setIsChanged(false);
    setIsInitialLoad(true);
    setSchemaFields([]);
    setGeneratedColumns({ columns: [], orderKeys: [] });
    setPages([]);
    setSharedPages([]);
    setPageTemplateId("");
    setError(null);
    console.log("PageContext: useEffect Triggered", { curPathName, defaultColumnsLength: defaultColumns == null ? void 0 : defaultColumns.length, hasResources: !!resources });
    fetchPageData(curPathName, defaultColumns, resources);
    return () => {
      setLoading(true);
    };
  }, [curPathName, JSON.stringify(defaultColumns), JSON.stringify(resources)]);
  if ((loading || curPathName != currentPathnameRef.current) && resources) {
    return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(ErpLoader, {});
  }
  if ((loading || curPathName != currentPathnameRef.current) && resources) {
    return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(ErpLoader, {});
  }
  return /* @__PURE__ */ jsxRuntime.jsxRuntimeExports.jsx(
    PageContext.Provider,
    {
      value: {
        pageTemplateId,
        activePage,
        pages,
        sharedPages,
        schemaFields,
        setPages,
        updatePageInfo,
        savePages,
        setActivePage,
        isSaving,
        loading,
        error,
        initializeColumns,
        generatedColumns,
        updateGeneratedColumns,
        isChanged,
        deletePage,
        isCreatePage,
        setIsCreatePage,
        addOrDeletePage,
        setIsChanged,
        formData
      },
      children
    }
  );
};
exports.ErpLoader = ErpLoader;
exports.PageContext = PageContext;
exports.PageProvider = PageProvider;
exports.PermissionsContext = PermissionsContext;
exports.PermissionsProvider = PermissionsProvider;
exports.defaultPageState = defaultPageState;
exports.initialFilter = initialFilter;
//# sourceMappingURL=page-context-PMwS3EGo.js.map
