import { create } from 'zustand';
import { persist } from 'zustand/middleware';
import apiClient from './api-client';

// Supported region IDs for multi-region deployment
export type RegionId = 'CN' | 'US' | 'UAE';

interface User {
  id: string;
  username: string;
  email: string;
  displayName: string;
  avatar?: string;
  // /users/me 返回的角色是富对象（[{ role: { code, permissions: [...] } }]），
  // 而登录响应里只是 string[]。两种 shape 都允许，类型用 any 兜底；
  // 业务通过 hasRole(code) / hasPermission(code) 访问，不要直接读 user.roles
  roles?: any;
  defaultRegion?: RegionId;           // 用户默认区域
  accessibleRegions?: RegionId[];     // 用户可访问的区域列表
  regionPermissions?: Record<RegionId, string[]>;  // 各区域的权限映射
}

// Default region for development (can be overridden by user's defaultRegion)
export const DEFAULT_REGION_ID: RegionId = 'CN';

interface AuthState {
  user: User | null;
  token: string | null;
  isAuthenticated: boolean;

  // 派生权限/角色（来自 /users/me，通过 reload() 刷新）— issue #159 合并自原 AuthContext
  permissions: string[];   // string[]（不是 Set）以便 zustand persist 正常 JSON 序列化
  roles: string[];
  isAdmin: boolean;
  loading: boolean;

  // 基础动作
  login: (token: string, user: User) => void;
  logout: () => void;
  setUser: (user: User) => void;
  /** 拉 /users/me 刷新 permissions/roles/isAdmin。app 启动 + 切组织后调 */
  reload: () => Promise<void>;

  // 区域工具
  getDefaultRegion: () => RegionId;
  getAccessibleRegions: () => RegionId[];
  getPermissionsForRegion: (region: RegionId) => string[];
  getCurrentRegionPermissions: () => string[];

  // 权限工具（来自原 AuthContext，业务组件统一调这些）
  hasPermission: (permission: string) => boolean;
  hasAnyPermission: (perms: string[]) => boolean;
  hasAllPermissions: (perms: string[]) => boolean;
  hasRole: (role: string) => boolean;
  hasAnyRole: (roleList: string[]) => boolean;
}

export const useAuth = create<AuthState>()(
  persist(
    (set, get) => ({
      user: null,
      token: null,
      isAuthenticated: false,
      permissions: [],
      roles: [],
      isAdmin: false,
      loading: false,

      login: (token, user) => {
        // 同时保存到 localStorage 和 Zustand 持久化存储
        localStorage.setItem('token', token);

        // 保存区域信息到 localStorage（供 RegionContext 使用）
        const defaultRegion = user.defaultRegion || DEFAULT_REGION_ID;
        const accessibleRegions = user.accessibleRegions || [defaultRegion];

        localStorage.setItem('ffoa_default_region', defaultRegion);
        localStorage.setItem('ffoa_accessible_regions', JSON.stringify(accessibleRegions));

        // 保存各区域权限
        if (user.regionPermissions) {
          localStorage.setItem('ffoa_region_permissions', JSON.stringify(user.regionPermissions));
        }

        // 如果当前没有选择区域，设置为默认区域
        if (!localStorage.getItem('ffoa_current_region')) {
          localStorage.setItem('ffoa_current_region', defaultRegion);
        }

        set({ token, user, isAuthenticated: true });
        console.log('Login successful, token saved:', token.substring(0, 20) + '...');

        // 异步拉 /users/me 拿权限/角色（fire-and-forget，错误自己 console）
        get().reload().catch(() => undefined);
      },

      logout: () => {
        localStorage.removeItem('token');
        localStorage.removeItem('refresh_token');
        localStorage.removeItem('auth-storage');
        localStorage.removeItem('ffoa_current_region');
        localStorage.removeItem('ffoa_default_region');
        localStorage.removeItem('ffoa_accessible_regions');
        localStorage.removeItem('ffoa_region_permissions');
        set({
          token: null,
          user: null,
          isAuthenticated: false,
          permissions: [],
          roles: [],
          isAdmin: false,
          loading: false,
        });
        console.log('Logout successful, all auth data cleared');
      },

      setUser: (user) => set({ user }),

      reload: async () => {
        const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null;
        if (!token) {
          set({ loading: false });
          return;
        }
        set({ loading: true });
        try {
          // 走 apiClient：401 自动 refresh + 重放，refresh 失败时跳登录页
          const userData: any = await apiClient.get('/users/me');

          const userRoleCodes: string[] =
            userData.roles?.map((r: any) => r.role?.code || r.roleId) || [];
          const isAdmin = userRoleCodes.includes('Administrator');

          let perms: string[];
          if (isAdmin) {
            // Administrator → 通配（hasPermission 短路返回 true）
            perms = ['*'];
          } else {
            const collected = new Set<string>();
            userData.roles?.forEach((ur: any) => {
              ur.role?.permissions?.forEach((rp: any) => {
                const perm = rp.permission;
                if (perm) collected.add(`${perm.resource}:${perm.action}`);
              });
            });
            perms = Array.from(collected);
          }

          set((s) => ({
            // 选择性合并 /users/me 字段到 user。
            // 不直接 spread userData：/users/me 的 roles 是富对象，
            // 而 user.roles（旧 zustand 风格）可能被 Navigation/devtracker 等
            // 当 string[] 用，覆盖会回归。store-level roles 有自己的字段。
            user: s.user
              ? {
                  ...s.user,
                  id: userData.id ?? s.user.id,
                  username: userData.username ?? s.user.username,
                  email: userData.email ?? s.user.email,
                  displayName: userData.displayName ?? s.user.displayName,
                  avatar: userData.avatar ?? s.user.avatar,
                }
              : userData,
            permissions: perms,
            roles: userRoleCodes,
            isAdmin,
          }));
        } catch (error) {
          // 401 已由 apiClient 拦截器处理（refresh→retry / refresh 失败跳登录），
          // 这里只兜底其他错误，不再吞 401 留下空权限
          console.error('[useAuth.reload] Failed to load /users/me:', error);
        } finally {
          set({ loading: false });
        }
      },

      getDefaultRegion: () => {
        const state = get();
        return state.user?.defaultRegion || DEFAULT_REGION_ID;
      },
      getAccessibleRegions: () => {
        const state = get();
        const defaultRegion = state.user?.defaultRegion || DEFAULT_REGION_ID;
        return state.user?.accessibleRegions || [defaultRegion];
      },
      getPermissionsForRegion: (region: RegionId) => {
        const state = get();
        return state.user?.regionPermissions?.[region] || [];
      },
      getCurrentRegionPermissions: () => {
        const state = get();
        const currentRegion =
          (typeof window !== 'undefined'
            ? (localStorage.getItem('ffoa_current_region') as RegionId)
            : null) ||
          state.user?.defaultRegion ||
          DEFAULT_REGION_ID;
        return state.user?.regionPermissions?.[currentRegion] || [];
      },

      hasPermission: (permission: string) => {
        const s = get();
        if (s.isAdmin) return true;
        return s.permissions.includes(permission);
      },
      hasAnyPermission: (perms: string[]) => {
        const s = get();
        if (s.isAdmin) return true;
        return perms.some((p) => s.permissions.includes(p));
      },
      hasAllPermissions: (perms: string[]) => {
        const s = get();
        if (s.isAdmin) return true;
        return perms.every((p) => s.permissions.includes(p));
      },
      hasRole: (role: string) => get().roles.includes(role),
      hasAnyRole: (roleList: string[]) => {
        const codes = get().roles;
        return roleList.some((r) => codes.includes(r));
      },
    }),
    {
      name: 'auth-storage',
      // 持久化字段：除方法外都持久化，方法不需持久（每次 hydrate 时重新绑定）
      partialize: (state) => ({
        user: state.user,
        token: state.token,
        isAuthenticated: state.isAuthenticated,
        permissions: state.permissions,
        roles: state.roles,
        isAdmin: state.isAdmin,
      }),
      onRehydrateStorage: () => (state) => {
        if (state) {
          console.log('Auth rehydrated:', {
            hasToken: !!state.token,
            hasUser: !!state.user,
            isAuthenticated: state.isAuthenticated,
            isAdmin: state.isAdmin,
            roleCount: state.roles?.length ?? 0,
          });

          if (state.token && state.user && !state.isAuthenticated) {
            state.isAuthenticated = true;
          }

          if (state.user) {
            const defaultRegion = state.user.defaultRegion || DEFAULT_REGION_ID;
            const accessibleRegions = state.user.accessibleRegions || [defaultRegion];

            localStorage.setItem('ffoa_default_region', defaultRegion);
            localStorage.setItem('ffoa_accessible_regions', JSON.stringify(accessibleRegions));

            if (state.user.regionPermissions) {
              localStorage.setItem('ffoa_region_permissions', JSON.stringify(state.user.regionPermissions));
            }

            if (!localStorage.getItem('ffoa_current_region')) {
              localStorage.setItem('ffoa_current_region', defaultRegion);
            }
          }
        }
      },
    },
  ),
);
