import { create } from 'zustand';
import { getRolePermissionMatrix, getPermissionMenuUrlMap } from '@/lib/permissions/actions';
import {
  buildMenuIdToUrlMap,
  convertMatrixToPermissionMap,
  findMatchingUrl,
  mergePermissionMaps,
} from '@/lib/permissions/utils';
import { ALL_DENIED_PERMS } from '@/lib/permissions/types';
import type { PermissionMap, PermissionAction } from '@/lib/permissions/types';

interface PermissionState {
  permissionMap: PermissionMap | null;
  isLoading: boolean;
  can: (url: string, action: PermissionAction) => boolean;
  loadPermissions: () => Promise<void>;
}

/** localStorage 'user' 키에서 역할 ID 배열 + menuId→URL 매핑 추출 */
function getUserData(): { roleIds: number[]; menuIdToUrl: Record<string, string> } | null {
  if (typeof window === 'undefined') return null;
  try {
    const raw = localStorage.getItem('user');
    if (!raw) return null;

    const parsed = JSON.parse(raw);

    const roleIds = Array.isArray(parsed.roles)
      ? parsed.roles.map((r: { id: number }) => r.id).filter(Boolean)
      : [];

    const menuIdToUrl = Array.isArray(parsed.menu)
      ? buildMenuIdToUrlMap(parsed.menu)
      : {};

    return { roleIds, menuIdToUrl };
  } catch {
    return null;
  }
}

export const usePermissionStore = create<PermissionState>((set, get) => ({
  permissionMap: null,
  isLoading: true,

  can: (url: string, action: PermissionAction): boolean => {
    const { permissionMap } = get();
    if (!permissionMap) return true;
    const matchedUrl = findMatchingUrl(url, permissionMap);
    if (!matchedUrl) return true;
    const perms = permissionMap[matchedUrl];
    return perms?.[action] ?? true;
  },

  loadPermissions: async () => {
    const userData = getUserData();
    if (!userData || userData.roleIds.length === 0) {
      set({ isLoading: false });
      return;
    }

    const { roleIds, menuIdToUrl } = userData;
    set({ isLoading: true });

    try {
      // 사이드바 메뉴에 없는 권한 메뉴의 URL 매핑 보완
      const [permMenuUrlMap, ...results] = await Promise.all([
        getPermissionMenuUrlMap(),
        ...roleIds.map((id) => getRolePermissionMatrix(id)),
      ]);

      // 권한 메뉴 URL을 베이스로, 사이드바 메뉴 URL로 덮어쓰기 (사이드바 우선)
      const mergedMenuIdToUrl = { ...permMenuUrlMap, ...menuIdToUrl };

      const maps = results
        .filter((r) => r.success && r.data?.permissions)
        .map((r) => convertMatrixToPermissionMap(r.data.permissions, mergedMenuIdToUrl));

      if (maps.length > 0) {
        const merged = mergePermissionMaps(maps);

        // 권한 메뉴에 등록되어 있지만 매트릭스 응답에 없는 메뉴 처리
        for (const [, url] of Object.entries(permMenuUrlMap)) {
          if (url && !merged[url]) {
            merged[url] = { ...ALL_DENIED_PERMS };
          }
        }

        set({ permissionMap: merged, isLoading: false });
      } else {
        set({ permissionMap: null, isLoading: false });
      }
    } catch (error) {
      console.error('[Permission] 권한 로드 실패:', error);
      set({ permissionMap: null, isLoading: false });
    }
  },
}));
