import { ref, computed } from 'vue';

export type StaffUserType = 'ADMIN' | 'AGENT';

export interface StaffUser {
  id: string;
  username: string;
  userType: StaffUserType;
  locale?: string;
  role?: string;
  permissions?: string[];
  agentLevel?: number | null;
  maxAgentLevel?: number | null;
  canManageSubAgents?: boolean;
  inviteCode?: string | null;
  visibleMenus?: string | null;
}

const TOKEN_KEY = 'manage_token';
const USER_KEY = 'manage_user';

function decodeJwtStaffClaims(rawToken: string): Partial<StaffUser> | null {
  try {
    const segment = rawToken.split('.')[1];
    if (!segment) return null;
    const padded = segment.replace(/-/g, '+').replace(/_/g, '/');
    const payload = JSON.parse(atob(padded)) as {
      sub?: string;
      username?: string;
      userType?: string;
      role?: string;
    };
    if (payload.userType !== 'ADMIN' && payload.userType !== 'AGENT') return null;
    if (!payload.sub || !payload.username) return null;
    return {
      id: payload.sub,
      username: payload.username,
      userType: payload.userType as StaffUserType,
      role: payload.role,
    };
  } catch {
    return null;
  }
}

function loadUser(): StaffUser | null {
  try {
    const raw = localStorage.getItem(USER_KEY);
    if (!raw) return null;
    const parsed = JSON.parse(raw) as Partial<StaffUser>;
    if (!parsed.id || !parsed.username || !parsed.userType) return null;
    return parsed as StaffUser;
  } catch {
    return null;
  }
}

function migrateLegacyTokens() {
  if (localStorage.getItem(TOKEN_KEY)) return;
  const legacyAdmin = localStorage.getItem('admin_token');
  const legacyAgent = localStorage.getItem('agent_token');
  if (legacyAdmin) {
    localStorage.setItem(TOKEN_KEY, legacyAdmin);
    localStorage.removeItem('admin_token');
    localStorage.removeItem(USER_KEY);
    return;
  }
  if (legacyAgent) {
    localStorage.setItem(TOKEN_KEY, legacyAgent);
    localStorage.removeItem('agent_token');
    localStorage.removeItem(USER_KEY);
  }
}

migrateLegacyTokens();

const token = ref(localStorage.getItem(TOKEN_KEY) || '');
const user = ref<StaffUser | null>(loadUser());

/** Align manage_user.userType with JWT when localStorage is stale (common after account switch). */
export function reconcileStaffSessionFromToken(): boolean {
  if (!token.value) return false;
  const claims = decodeJwtStaffClaims(token.value);
  if (!claims?.userType || !claims.id || !claims.username) return false;

  if (
    user.value?.id === claims.id &&
    user.value.username === claims.username &&
    user.value.userType === claims.userType
  ) {
    return true;
  }

  const next: StaffUser = {
    id: claims.id,
    username: claims.username,
    userType: claims.userType,
    locale: user.value?.locale,
    role: claims.role ?? user.value?.role,
    permissions: user.value?.permissions,
    inviteCode: user.value?.inviteCode,
    visibleMenus: user.value?.visibleMenus,
  };
  user.value = next;
  localStorage.setItem(USER_KEY, JSON.stringify(next));
  return true;
}

reconcileStaffSessionFromToken();

if (typeof window !== 'undefined') {
  window.addEventListener('storage', () => {
    token.value = localStorage.getItem(TOKEN_KEY) || '';
    user.value = loadUser();
    reconcileStaffSessionFromToken();
  });
}

export function clearStaffSession() {
  token.value = '';
  user.value = null;
  localStorage.removeItem(TOKEN_KEY);
  localStorage.removeItem(USER_KEY);
  localStorage.removeItem('admin_token');
  localStorage.removeItem('agent_token');
  void import('../utils/session-hydrate').then((m) => m.resetStaffSessionHydration());
}

function resolveUserType(): StaffUserType | null {
  return user.value?.userType ?? decodeJwtStaffClaims(token.value)?.userType ?? null;
}

export function useAuthStore() {
  const isAdmin = computed(() => resolveUserType() === 'ADMIN');
  const isAgent = computed(() => resolveUserType() === 'AGENT');
  const isTier1Agent = computed(() => isAgent.value && user.value?.agentLevel === 1);
  const isTier2Agent = computed(() => isAgent.value && user.value?.agentLevel === 2);
  const canManageSubAgents = computed(() => {
    if (!isAgent.value) return false;
    if (user.value?.canManageSubAgents != null) return user.value.canManageSubAgents;
    const level = user.value?.agentLevel;
    const max = user.value?.maxAgentLevel;
    if (level == null || level < 1) return false;
    if (max == null || max === 0) return true;
    return level < max;
  });
  const portalLabel = computed(() => (isAdmin.value ? '平台后台' : '代理后台'));

  function setSession(newToken: string, newUser: StaffUser) {
    token.value = newToken;
    user.value = newUser;
    localStorage.setItem(TOKEN_KEY, newToken);
    localStorage.setItem(USER_KEY, JSON.stringify(newUser));
    localStorage.removeItem('admin_token');
    localStorage.removeItem('agent_token');
  }

  function logout() {
    clearStaffSession();
  }

  return {
    token,
    user,
    isAdmin,
    isAgent,
    isTier1Agent,
    isTier2Agent,
    canManageSubAgents,
    portalLabel,
    setSession,
    logout,
    clearStaffSession,
    reconcileStaffSessionFromToken,
  };
}
