import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { login as loginApi, type UserInfo } from '@/api/auth'
import request from '@/api/request'

function safeJsonParse<T>(key: string): T | null {
  try {
    const raw = localStorage.getItem(key)
    if (!raw) return null
    return JSON.parse(raw)
  } catch {
    localStorage.removeItem(key)
    return null
  }
}

export const useAuthStore = defineStore('auth', () => {
  const accessToken = ref<string>(localStorage.getItem('accessToken') || '')
  const refreshToken = ref<string>(localStorage.getItem('refreshToken') || '')
  const userInfo = ref<UserInfo | null>(safeJsonParse<UserInfo>('userInfo'))
  const permissions = ref<string[]>(safeJsonParse<string[]>('userPermissions') || [])
  const roleNames = ref<string[]>(safeJsonParse<string[]>('userRoleNames') || [])

  const isLoggedIn = computed(() => !!accessToken.value)
  const nickname = computed(() => userInfo.value?.nickname || '管理员')
  const username = computed(() => userInfo.value?.username || '')
  const isAdmin = computed(() => userInfo.value?.id === 1)
  const roleDisplay = computed(() => roleNames.value.length > 0 ? roleNames.value.join('、') : '管理员')
  const hasPermission = (code: string) => {
    return permissions.value.some((p) => p === code || p.startsWith(code + ':'))
  }

  async function login(username: string, password: string) {
    const res = await loginApi({ username, password })
    // 兼容两种响应格式：{ code, message, data } 包裹 或 直接返回 login data
    const data = res.data ?? res
    accessToken.value = data.accessToken
    refreshToken.value = data.refreshToken
    userInfo.value = data.userInfo

    localStorage.setItem('accessToken', accessToken.value)
    localStorage.setItem('refreshToken', refreshToken.value)
    localStorage.setItem('userInfo', JSON.stringify(userInfo.value))

    // 登录后获取用户权限
    await fetchPermissions()
  }

  async function fetchPermissions() {
    if (!userInfo.value?.id) return
    try {
      const roles: any[] = await request.get(`/api/users/${userInfo.value.id}/roles`)
      if (!roles.length) return
      const allCodes: string[] = []
      const names: string[] = []
      for (const role of roles) {
        if (role.roleName) names.push(role.roleName)
        try {
          const perms: any[] = await request.get(`/api/roles/${role.id}/permissions`)
          for (const p of perms) {
            if (p.permissionCode && !allCodes.includes(p.permissionCode)) {
              allCodes.push(p.permissionCode)
            }
          }
        } catch { /* skip */ }
      }
      permissions.value = allCodes
      roleNames.value = names
      localStorage.setItem('userPermissions', JSON.stringify(allCodes))
      localStorage.setItem('userRoleNames', JSON.stringify(names))
    } catch { /* ignore */ }
  }

  function logout() {
    accessToken.value = ''
    refreshToken.value = ''
    userInfo.value = null
    permissions.value = []
    roleNames.value = []
    localStorage.removeItem('accessToken')
    localStorage.removeItem('refreshToken')
    localStorage.removeItem('userInfo')
    localStorage.removeItem('userPermissions')
    localStorage.removeItem('userRoleNames')
  }

  return { accessToken, refreshToken, userInfo, permissions, roleNames, isLoggedIn, nickname, username, isAdmin, roleDisplay, hasPermission, login, fetchPermissions, logout }
})