import { create } from 'zustand'
import type { SystemUser, SystemMenu } from '@/api/system'
import { getUserInfo, logout as apiLogout } from '@/api/system/auth'

const TOKEN_KEY = 'token'
const USER_KEY = 'user'

interface AuthState {
  user: SystemUser | null
  token: string | null
  isAuthenticated: boolean
  menus: SystemMenu[]
  permissions: string[]
  hasFetchedMenus: boolean
  login: (user: SystemUser, token: string) => void
  logout: () => Promise<void>
  refreshMenus: () => Promise<void>
  hasPermission: (permission: string) => boolean
}

function extractPermissions(menus: SystemMenu[]): string[] {
  const perms: string[] = []
  const traverse = (m: SystemMenu) => {
    if (m.permission) perms.push(m.permission)
    m.children?.forEach(traverse)
  }
  menus.forEach(traverse)
  return perms
}

function getStoredAuth() {
  try {
    const token = localStorage.getItem(TOKEN_KEY)
    const userStr = localStorage.getItem(USER_KEY)
    if (token && userStr) {
      return { user: JSON.parse(userStr) as SystemUser, token, isAuthenticated: true }
    }
  } catch { /* ignore */ }
  return { user: null, token: null, isAuthenticated: false }
}

const initial = getStoredAuth()

export const useAuthStore = create<AuthState>((set, get) => ({
  user: initial.user,
  token: initial.token,
  isAuthenticated: initial.isAuthenticated,
  menus: [],
  permissions: [],
  hasFetchedMenus: false,

  login: (user, token) => {
    localStorage.setItem(TOKEN_KEY, token)
    localStorage.setItem(USER_KEY, JSON.stringify(user))
    set({ user, token, isAuthenticated: true, menus: [], permissions: [], hasFetchedMenus: false })
  },

  logout: async () => {
    try { await apiLogout() } catch { /* ignore */ }
    localStorage.removeItem(TOKEN_KEY)
    localStorage.removeItem(USER_KEY)
    set({ user: null, token: null, isAuthenticated: false, menus: [], permissions: [], hasFetchedMenus: false })
  },

  refreshMenus: async () => {
    if (!get().isAuthenticated) return
    try {
      const userInfo = await getUserInfo()
      const menus = userInfo.menus || []
      set({ menus, permissions: extractPermissions(menus), hasFetchedMenus: true })
    } catch (e) { 
      console.error('获取菜单失败:', e)
      set({ hasFetchedMenus: true })
    }
  },

  hasPermission: (permission) => {
    const { user, permissions } = get()
    if (user?.account === 'admin') return true
    return permissions.includes(permission)
  },
}))
