import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import { authApi } from '@/api/auth'
import { ApiException } from '@/api/types'

export interface User {
  id: string
  email: string
  display_name: string
  is_admin: boolean
}

function safeReadJSON<T>(key: string, fallback: T): T {
  try {
    const raw = localStorage.getItem(key)
    if (raw === null) return fallback
    return JSON.parse(raw) as T
  } catch {
    // 脏数据 / 反序列化失败 → 清掉，回退默认。
    try {
      localStorage.removeItem(key)
    } catch {
      /* noop */
    }
    return fallback
  }
}

function safeReadString(key: string): string | null {
  try {
    return localStorage.getItem(key)
  } catch {
    return null
  }
}

function safeWrite(key: string, value: string) {
  try {
    localStorage.setItem(key, value)
  } catch {
    /* QuotaExceeded / disabled */
  }
}

function safeRemove(key: string) {
  try {
    localStorage.removeItem(key)
  } catch {
    /* noop */
  }
}

export const useAuthStore = defineStore('auth', () => {
  const token = ref<string | null>(safeReadString('token'))
  const user = ref<User | null>(safeReadJSON<User | null>('user', null))

  const isAuthenticated = computed(() => !!token.value)
  const isAdmin = computed(() => !!user.value?.is_admin)

  function setSession(t: string, u: User) {
    token.value = t
    user.value = u
    safeWrite('token', t)
    safeWrite('user', JSON.stringify(u))
  }

  function clearSession() {
    token.value = null
    user.value = null
    safeRemove('token')
    safeRemove('user')
  }

  // setUser 仅更新当前用户信息（不改动 token），用于服务端回填最新资料。
  function setUser(u: User) {
    user.value = u
    safeWrite('user', JSON.stringify(u))
  }

  // refreshUser 调用 /auth/me 拉取最新用户信息并同步进 store。
  // 调用方负责处理异常（如需）。
  async function refreshUser(): Promise<void> {
    const u = await authApi.me()
    setUser(u)
  }

  // validateSession 在应用启动时校验本地 token 是否仍然有效：
  // 有 token 才校验；成功则同步最新用户信息，遇到 401 则登出。
  async function validateSession(): Promise<void> {
    if (!token.value) return
    try {
      await refreshUser()
    } catch (e: unknown) {
      if (e instanceof ApiException && e.status === 401) {
        clearSession()
      }
      // 其它错误（网络等）保留本地会话，避免误登出。
    }
  }

  return {
    token,
    user,
    isAuthenticated,
    isAdmin,
    setSession,
    clearSession,
    setUser,
    refreshUser,
    validateSession,
  }
})
