"use client";

import React, { createContext, useContext, useEffect, useState } from "react";
import { getCookiesDecrypt } from "@/lib/utils";
import { getUserLevelModuleAccessesByUserLevelId } from "@/service/user-level-module-accesses";
import { getUserLevelMenuActionAccesses } from "@/service/user-level-menu-action-accesses";
import { getUserInfo } from "@/service/user";

type ModuleAccessMap = Record<string, boolean>;
type ActionAccessMap = Record<string, string[]>;

interface PermissionContextType {
  canModule: (moduleCode: string) => boolean;
  canAction: (actionCode: string) => boolean;
  can: (moduleCode: string, actionCode: string) => boolean;
  loading: boolean;
}

const PermissionContext = createContext<PermissionContextType | null>(null);

export const PermissionProvider = ({
  children,
}: {
  children: React.ReactNode;
}) => {
  const [moduleAccess, setModuleAccess] = useState<ModuleAccessMap>({});
  const [actionCodes, setActionCodes] = useState<string[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const loadPermissions = async () => {
      try {
        // ✅ SUMBER KEBENARAN: API USER INFO
        const userRes = await getUserInfo();
        const userLevelId = userRes?.data?.data?.userLevelId;

        console.log("USER LEVEL ID FROM API:", userLevelId);

        if (!userLevelId) {
          console.error("userLevelId not found from users/info");
          return;
        }

        const [moduleRes, actionRes] = await Promise.all([
          getUserLevelModuleAccessesByUserLevelId(userLevelId),
          getUserLevelMenuActionAccesses({
            userLevelId,
            canAccess: true,
            limit: 10000,
          }),
        ]);

        console.log("ACTION ACCESS RAW:", actionRes?.data?.data);

        // 🔹 MODULE ACCESS
        // MODULE ACCESS
        const moduleMap: Record<string, boolean> = {};
        moduleRes?.data?.data?.forEach((item: any) => {
          if (
            item.module?.code &&
            item.canAccess === true &&
            item.isActive !== false
          ) {
            moduleMap[item.module.code] = true;
          }
        });

        // ACTION ACCESS
        const actions =
          actionRes?.data?.data
            ?.filter(
              (item: any) =>
                Number(item.userLevelId) === Number(userLevelId) &&
                item.canAccess === true &&
                item.isActive === true,
            )
            .map((item: any) => item.actionCode) ?? [];

        setModuleAccess(moduleMap);
        setActionCodes(actions);
      } catch (error) {
        console.error("Failed to load permissions", error);
      } finally {
        setLoading(false);
      }
    };

    loadPermissions();
  }, []);

  const canModule = (moduleCode: string) => moduleAccess[moduleCode] === true;

  const canAction = (actionCode: string) => actionCodes.includes(actionCode);

  /**
   * FINAL GUARD
   * - harus punya module
   * - harus punya action
   */
  const can = (moduleCode: any, actionCode: any) =>
    canModule(moduleCode) && canAction(actionCode);

  return (
    <PermissionContext.Provider value={{ canModule, canAction, can, loading }}>
      {children}
    </PermissionContext.Provider>
  );
};

export const usePermission = () => {
  const ctx = useContext(PermissionContext);
  if (!ctx) {
    throw new Error("usePermission must be used inside PermissionProvider");
  }
  return ctx;
};
