/**
 * 用户状态管理
 *
 * 基于 Pinia 的用户信息 Store，管理当前登录用户的
 * 个人信息、登录/退出逻辑以及权限相关数据。
 *
 * @module stores/user
 */

import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { useTokenStore } from './token'
import {
  login as loginApi,
  logout as logoutApi,
  getUserInfo as getUserInfoApi,
  type LoginParams,
  type UserInfo,
} from '@/api'

/**
 * 用户 Store
 *
 * 管理当前登录用户的完整生命周期：
 * - userInfo：用户基本信息（响应式）
 * - roles：角色列表
 * - permissions：权限标识列表
 * - hasUserInfo：是否已加载用户信息（计算属性）
 * - login：调用登录接口并存储 Token
 * - logout：调用退出接口并清除状态
 * - getUserInfo：获取当前用户详细信息
 */
export const useUserStore = defineStore('user', () => {
  // ══════════════════════════════════════════════
  // State
  // ══════════════════════════════════════════════

  /** 当前登录用户信息 */
  const userInfo = ref<UserInfo | null>(null)

  /** 用户角色列表 */
  const roles = ref<string[]>([])

  /** 用户权限标识列表 */
  const permissions = ref<string[]>([])

  // ══════════════════════════════════════════════
  // Getters
  // ══════════════════════════════════════════════

  /**
   * 是否已加载用户信息
   * @returns 用户信息对象存在则返回 true
   */
  const hasUserInfo = computed<boolean>(() => {
    return userInfo.value !== null
  })

  /**
   * 当前用户名
   * @returns 用户名称，未登录时返回空字符串
   */
  const userName = computed<string>(() => {
    return userInfo.value?.userName ?? ''
  })

  /**
   * 当前用户昵称
   * @returns 用户昵称，未登录时返回空字符串
   */
  const nickName = computed<string>(() => {
    return userInfo.value?.nickName ?? ''
  })

  /**
   * 当前用户头像
   * @returns 头像地址，未登录时返回空字符串
   */
  const avatar = computed<string>(() => {
    return userInfo.value?.avatar ?? ''
  })

  /**
   * 当前用户 ID
   * @returns 用户 ID，未登录时返回空字符串
   */
  const userId = computed<string | number>(() => {
    return userInfo.value?.userId ?? ''
  })

  // ══════════════════════════════════════════════
  // Actions
  // ══════════════════════════════════════════════

  /**
   * 用户登录
   *
   * 调用登录接口获取 Token，并写入 Token Store。
   * 登录成功后自动调用 getUserInfo 获取用户详细信息。
   *
   * @param params - 登录参数（用户名、密码、验证码等）
   * @returns 登录成功后返回的 Token
   */
  async function login(params: LoginParams): Promise<string> {
    const tokenStore = useTokenStore()
    const res = await loginApi(params)
    tokenStore.setToken(res.token)
    await getUserInfo()
    return res.token
  }

  /**
   * 获取当前登录用户信息
   *
   * 调用后端接口获取用户详细信息，同时更新
   * roles 和 permissions 列表。
   */
  async function getUserInfo(): Promise<void> {
    const info = await getUserInfoApi()
    userInfo.value = info
    roles.value = info.roles ?? []
    permissions.value = info.permissions ?? []
  }

  /**
   * 退出登录
   *
   * 调用后端退出接口，清除 Token Store 中的 Token，
   * 并将当前 Store 状态重置为初始值。
   */
  async function logout(): Promise<void> {
    const tokenStore = useTokenStore()
    try {
      await logoutApi()
    } finally {
      // 无论接口调用成功与否，前端都必须清除登录状态
      tokenStore.clearToken()
      $reset()
    }
  }

  /**
   * 判断当前用户是否拥有指定权限
   *
   * @param permission - 权限标识字符串
   * @returns 拥有该权限返回 true，否则返回 false
   */
  function hasPermission(permission: string): boolean {
    return permissions.value.includes(permission)
  }

  /**
   * 判断当前用户是否拥有指定角色
   *
   * @param role - 角色标识字符串
   * @returns 拥有该角色返回 true，否则返回 false
   */
  function hasRole(role: string): boolean {
    return roles.value.includes(role)
  }

  /**
   * 重置 Store 状态
   *
   * 将 userInfo、roles、permissions 全部恢复为初始值。
   * 通过 Pinia 的 $reset 方法可调用此逻辑。
   */
  function $reset(): void {
    userInfo.value = null
    roles.value = []
    permissions.value = []
  }

  return {
    // State
    userInfo,
    roles,
    permissions,
    // Getters
    hasUserInfo,
    userName,
    nickName,
    avatar,
    userId,
    // Actions
    login,
    getUserInfo,
    logout,
    hasPermission,
    hasRole,
    $reset,
  }
})
