import type { uniappRequestAdapter } from '@alova/adapter-uniapp'
import type { IResponse } from './types'
import AdapterUniapp from '@alova/adapter-uniapp'
import { createAlova } from 'alova'
import { createServerTokenAuthentication } from 'alova/client'
import VueHook from 'alova/vue'
import { useTokenStore } from '@/store/token'
import { toLoginPage } from '@/utils/toLoginPage'
import { ContentTypeEnum, ResultEnum, ShowMessage } from './tools/enum'

// 配置动态Tag
export const API_DOMAINS = {
    DEFAULT: import.meta.env.VITE_SERVER_BASEURL,
    SECONDARY: import.meta.env.VITE_SERVER_BASEURL_SECONDARY,
}

/**
 * 创建请求实例
 */
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication<
    typeof VueHook,
    typeof uniappRequestAdapter
>({
    // 如果下面拦截不到，请使用 refreshTokenOnSuccess by 群友@琛
    refreshTokenOnError: {
        isExpired: (error) => {
            console.log('error', error)
            return error.response?.status === ResultEnum.Unauthorized
        },
        handler: async () => {
            try {
                // await authLogin();
                console.log('拦截token失效')
            }
            catch (error) {
                // 切换到登录页
                // toLoginPage({ mode: 'reLaunch' })
                console.log('刷新token失败', error)
                throw error
            }
        },
    },
})

/**
 * alova 请求实例
 */
const alovaInstance = createAlova({
    baseURL: API_DOMAINS.DEFAULT,
    ...AdapterUniapp(),
    // timeout: 7000,
    statesHook: VueHook,

    beforeRequest: (method) => {
        // 设置默认 Content-Type
        method.config.headers = {
            ContentType: ContentTypeEnum.JSON,
            // #ifndef MP-WEIXIN
            responseType: 'json',
            // #endif
            Accept: 'application/json, text/plain, */*',
            ...method.config.headers,
        }

        const { config } = method
        const ignoreAuth = !config.meta?.ignoreAuth
        console.log('ignoreAuth===>', ignoreAuth)
        // 处理认证信息   自行处理认证问题
        if (ignoreAuth) {
            const tokenStore = useTokenStore()
            const token = tokenStore.validToken
            // const token = 'getToken()'
            if (!token) {
                throw new Error('[请求错误]：未登录')
            }
            method.config.headers['X-Access-Token'] = `${token}`
            method.config.headers.AppType = '7'
            // method.config.headers.token = token;
        }

        // 处理动态域名
        if (config.meta?.domain) {
            method.baseURL = config.meta.domain
            console.log('当前域名', method.baseURL)
        }
    },

    responded: {
        onSuccess: (response, method) => {
            const { config } = method
            const { requestType } = config
            const {
                statusCode,
                data: rawData,
                errMsg,
            } = response as UniNamespace.RequestSuccessCallbackResult

            // 处理特殊请求类型（上传/下载）
            if (requestType === 'upload' || requestType === 'download') {
                return response
            }

            // 处理 HTTP 状态码错误
            if (statusCode !== 200) {
                // 直接处理401错误，跳转到登录页面
                if (statusCode === 401) {
                    uni.showToast({
                        title: '登录已过期，请重新登录',
                        icon: 'error',
                        duration: 1500,
                    })
                    useTokenStore().cleanToken()
                    setTimeout(() => {
                        toLoginPage({ mode: 'reLaunch' })
                    }, 1500)
                    throw new Error('登录已过期')
                }

                const errorMessage = ShowMessage(statusCode) || `HTTP请求错误[${statusCode}]`
                console.error('errorMessage===>', errorMessage)
                uni.showToast({
                    title: errorMessage,
                    icon: 'error',
                })
                throw new Error(`${errorMessage}：${errMsg}`)
            }

            // 处理业务逻辑错误
            const { code, message, result: data } = rawData as IResponse
            // 0和200当做成功都很普遍，这里直接兼容两者，见 ResultEnum
            if (code !== ResultEnum.Success0 && code !== ResultEnum.Success200) {
                if (config.meta?.toast !== false) {
                    uni.showToast({
                        title: message,
                        icon: 'none',
                    })
                }
                throw new Error(`请求错误[${code}]：${message}`)
            }
            // 处理成功响应，返回业务数据
            return data
        },
        // 添加网络错误处理
        onError: (error, method) => {
            // 处理网络错误（断网、超时、DNS解析失败等）
            console.error('网络错误:', error)

            // 避免重复提示
            if (error.message?.includes('HTTP请求错误') || error.message?.includes('请求错误[')) {
                return
            }

            let errorMessage = '网络错误，请检查网络连接'
            if (error.message?.includes('timeout')) {
                errorMessage = '请求超时，请稍后重试'
            }

            uni.showToast({
                title: errorMessage,
                icon: 'error',
            })
        }
    },
})

export const http = alovaInstance
