/*
 * @Author: weisheng
 * @Date: 2025-04-17 15:58:11
 * @LastEditTime: 2025-06-15 21:47:22
 * @LastEditors: weisheng
 * @Description: Alova response and error handlers
 * @FilePath: /wot-starter/src/api/core/handlers.ts
 */
import type { Method } from 'alova'
import { triggerUnauthorizedRedirect } from '@/router/authRedirect'
import { clearMiniAuthSession } from '@/store/auth'

// Custom error class for API errors
export class ApiError extends Error {
  code: number
  data?: any

  constructor(message: string, code: number, data?: any) {
    super(message)
    this.name = 'ApiError'
    this.code = code
    this.data = data
  }
}

// Define a type for the expected API response structure
interface ApiResponse {
  code: number
  message?: string
  result?: any
  success?: boolean
  total?: number
}

let redirectingToLogin = false

function handleUnauthorized(message?: string, code = 401, data?: any) {
  clearMiniAuthSession()
  if (!redirectingToLogin) {
    redirectingToLogin = true
    const globalToast = useGlobalToast()
    globalToast.error({ msg: message || '登录已过期，请重新登录！', duration: 1200 })
    const timer = setTimeout(() => {
      clearTimeout(timer)
      redirectingToLogin = false
      triggerUnauthorizedRedirect()
    }, 300)
  }
  throw new ApiError(message || '登录已过期，请重新登录！', code, data)
}

// Handle successful responses
export async function handleAlovaResponse(
  response: UniApp.RequestSuccessCallbackResult | UniApp.UploadFileSuccessCallbackResult | UniApp.DownloadSuccessData,
) {
  const globalToast = useGlobalToast()
  // Extract status code and data from UniApp response
  const { statusCode, data } = response as UniNamespace.RequestSuccessCallbackResult

  if (statusCode === 401 || statusCode === 403) {
    handleUnauthorized('登录已过期，请重新登录！', statusCode, data)
  }

  // Handle HTTP error status codes
  if (statusCode >= 400) {
    globalToast.error(`Request failed with status: ${statusCode}`)
    throw new ApiError(`Request failed with status: ${statusCode}`, statusCode, data)
  }

  // The data is already parsed by UniApp adapter
  const json = data as ApiResponse
  // Log response in development
  if (import.meta.env.MODE === 'development') {
    console.log('[Alova Response]', json)
  }

  if (json.code === 401 || json.code === 403) {
    handleUnauthorized(json.message, json.code, json)
  }

  // Return data for successful responses
  return json
}

// Handle request errors
export function handleAlovaError(error: any, method: Method) {
  const globalToast = useGlobalToast()
  // Log error in development
  if (import.meta.env.MODE === 'development') {
    console.error('[Alova Error]', error, method)
  }

  if (error instanceof ApiError && (error.code === 401 || error.code === 403)) {
    throw error
  }

  // Handle different types of errors
  if (error.name === 'NetworkError') {
    globalToast.error('网络错误，请检查您的网络连接')
  }
  else if (error.name === 'TimeoutError') {
    globalToast.error('请求超时，请重试')
  }
  else if (error instanceof ApiError) {
    globalToast.error(error.message || '请求失败')
  }
  else {
    globalToast.error('发生意外错误')
  }

  throw error
}
