import type { AxiosRequestConfig, Method } from 'axios'
import axios from 'axios'
import { ElLoading, ElNotification, type LoadingOptions } from 'element-plus'
import { lnRefreshToken, lnRefreshTokenTo, refreshToken } from '@/api/user-boot/user'
import router from '@/router/index'
import { useAdminInfo } from '@/stores/adminInfo'
import { debounce } from 'lodash-es'
const IS_LN_VERSION = import.meta.env.VITE_NAME === 'LNqr'
let loginExpireTimer: any = null
window.requests = []
window.tokenRefreshing = false
const pendingMap = new Map()
const loadingInstance: LoadingInstance = {
    target: null,
    count: 0
}
const VITE_FLAG = import.meta.env.VITE_NAME == 'removeMode'
// console.log('🚀 ~ import.meta.env.VITE_NAME:', import.meta.env.VITE_NAME)
/**
 * 根据运行环境获取基础请求URL
 */
export const getUrl = (): string => {
    return '/api'
}
function removeBeforeSecondSlash(str: string) {
    // 找到第一个斜杠的位置
    const firstSlashIndex = str.indexOf('/')
    if (firstSlashIndex === -1) {
        // 如果没有斜杠，返回原字符串
        return str
    }
    // 从第一个斜杠之后开始找第二个斜杠
    const secondSlashIndex = str.indexOf('/', firstSlashIndex + 1)
    if (secondSlashIndex === -1) {
        // 如果只有一个斜杠，返回原字符串
        return str
    }
    // 返回第二个斜杠及之后的内容
    return str.substring(secondSlashIndex)
}
/**
 * 创建`Axios`
 * 默认开启`reductDataFormat(简洁响应)`,返回类型为`ApiPromise`
 * 关闭`reductDataFormat`,返回类型则为`AxiosPromise`
 */
function createAxios<Data = any, T = ApiPromise<Data>>(
    axiosConfig: AxiosRequestConfig,
    options: Options = {},
    loading: LoadingOptions = {}
): T {
    const adminInfo = useAdminInfo()

    const Axios = axios.create({
        baseURL: getUrl(),
        timeout: 1000 * 60 * 5,
        headers: {},
        responseType: 'json'
    })

    options = Object.assign(
        {
            CancelDuplicateRequest: true, // 是否开启取消重复请求, 默认为 true
            loading: false, // 是否开启loading层效果, 默认为false
            reductDataFormat: true, // 是否开启简洁的数据结构响应, 默认为true
            showErrorMessage: true, // 是否开启接口错误信息展示,默认为true
            showCodeMessage: true, // 是否开启code不为1时的信息提示, 默认为true
            showSuccessMessage: false, // 是否开启code为1时的信息提示, 默认为false
            anotherToken: '' // 当前请求使用另外的用户token
        },
        options
    )

    // 请求拦截
    Axios.interceptors.request.use(
        async (config: any) => {
            //嵌入去除所有请求头
            if (VITE_FLAG) {
                config.url = await removeBeforeSecondSlash(config.url)
            }

            // 取消重复请求

            if (
                !(
                    config.url == '/system-boot/file/upload' ||
                    config.url == '/harmonic-boot/grid/getAssessOverview' ||
                    config.url == '/system-boot/file/getFileVO' ||
                    config.url == '/harmonic-boot/gridDiagram/getGridDiagramAreaData' ||
                    config.url == '/supervision-boot/userReport/bindAssessmentId'
                )
            )
                removePending(config)

            options.CancelDuplicateRequest && addPending(config)
            // 创建loading实例
            if (options.loading) {
                loadingInstance.count++
                if (loadingInstance.count === 1) {
                    loadingInstance.target = ElLoading.service(loading)
                }
            }
            // 自动携带token
            if (config.headers) {
                const token = adminInfo.getToken()
                if (token) {
                    ;(config.headers as anyObj).Authorization = token
                } else {
                    config.headers.Authorization = 'Basic bmpjbjpuamNucHFz'
                }
            }
            if (
                config.url == '/user-boot/user/generateSm2Key' ||
                config.url == '/pqs-auth/oauth/token' ||
                config.url == '/pqs-auth/oauth/lnLogin' ||
                config.url == '/pqs-auth/oauth/lnRefreshToken'
            ) {
                config.headers.Authorization = 'Basic bmpjbjpuamNucHFz'
            }

            return config
        },
        error => {
            return Promise.reject(error)
        }
    )

    // 响应拦截
    Axios.interceptors.response.use(
        response => {
            removePending(response.config)
            options.loading && closeLoading(options) // 关闭loading

            if (
                response.data.code === 'A0000' ||
                response.data.type === 'application/json' ||
                Array.isArray(response.data) ||
                response.data.size ||
                response.config.url == '/harmonic-boot/exportmodel/exportModelJB' ||
                response.config.url == '/system-boot/file/download' ||
                response.config.url == '/harmonic-boot/powerStatistics/exportExcelListTemplate' ||
                response.config.url == '/harmonic-boot/powerStatistics/exportExcelRangTemplate'
                // ||
                // response.data.type === 'application/octet-stream' ||
                // response.data.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
            ) {
                return options.reductDataFormat ? response.data : response
            } else if (response.data.code == 'A0202') {
                if (!window.tokenRefreshing) {
                    window.tokenRefreshing = true

                    if (IS_LN_VERSION) {
                        //辽宁版本
                        return lnRefreshTokenTo()
                            .then(res => {
                                adminInfo.setToken(res.data.access_token, 'auth')
                                adminInfo.setToken(res.data.refresh_token, 'refresh')
                                window.requests.forEach(cb => cb(res.data.access_token))
                                window.requests = []

                                return Axios(response.config)
                            })
                            .catch(err => {
                                // refresh_token + CAS 都过期 → 重新走CAS登录
                                //window.location.href = '/api/pqs-auth/oauth/lnCheck'
                                return Promise.reject(err)
                            })
                            .finally(() => {
                                window.tokenRefreshing = false
                            })
                    } else {
                        //通用版本
                        return refreshToken()
                            .then(res => {
                                adminInfo.setToken(res.data.access_token, 'auth')
                                adminInfo.setToken(res.data.refresh_token, 'refresh')
                                window.requests.forEach(cb => cb(res.data.access_token))
                                window.requests = []

                                return Axios(response.config)
                            })
                            .catch(err => {
                                adminInfo.removeToken()
                                router.push({ name: 'login' })
                                return Promise.reject(err)
                            })
                            .finally(() => {
                                window.tokenRefreshing = false
                            })
                    }
                } else {
                    return new Promise(resolve => {
                        // 用函数形式将 resolve 存入，等待刷新后再执行
                        window.requests.push((token: string) => {
                            response.headers.Authorization = `${token}`
                            resolve(Axios(response.config))
                        })
                    })
                }
            } else if (response.data.code == 'A0024' || response.data.code == 'null') {
                // // 登录失效
                // 清除上一次的定时器
                if (loginExpireTimer) {
                    clearTimeout(loginExpireTimer)
                }
                loginExpireTimer = setTimeout(() => {
                    ElNotification({
                        type: 'error',
                        message: response.data.message
                    })
                    adminInfo.removeToken()
                    router.push({ name: 'login' })
                    loginExpireTimer = null // 执行后清空定时器
                }, 100) // 可根据实际情况调整延迟时间
                return Promise.reject(response.data)
            } else if (response.data.code == 'A0121') {
                //统一认证过期
                //const casLogoutUrl = 'http://privilege-epri.dcloud.ln.dc.sgcc.com.cn/cas/login?service=http://PQMonitoring.dcloud.ln.dc.sgcc.com.cn'
                // 1. 清空本地失效token、用户信息
                adminInfo.removeToken()
                adminInfo.reset()
                // 2. 跳转统一鉴权中转接口
                const authCheckUrl = '/api/pqs-auth/oauth/lnCheck'
                window.location.href = authCheckUrl
                // 中断请求
                return Promise.reject(response.data)
            } else {
                if (options.showCodeMessage) {
                    ElNotification({
                        type: 'error',
                        message: response.data.message || '未知错误'
                    })
                }
                return Promise.reject(response.data)
            }
        },
        error => {
            error.config && removePending(error.config)
            options.loading && closeLoading(options) // 关闭loading
            return Promise.reject(error) // 错误继续返回给到具体页面
        }
    )
    return Axios(axiosConfig) as T
}

/** 发起请求并直接返回业务 data 字段 */
export async function requestData<T = any>(
    axiosConfig: AxiosRequestConfig,
    options?: Options,
    loading?: LoadingOptions
): Promise<T> {
    const res = await createAxios<any, ApiPromise<T>>(axiosConfig, options, loading)
    return (res as ApiResponse<T>)?.data as T
}

/** 下载文件，返回原始 axios 响应 */
export function requestDownload(
    axiosConfig: AxiosRequestConfig,
    options?: Options,
    loading?: LoadingOptions
) {
    return createAxios(axiosConfig, { ...options, reductDataFormat: false }, loading)
}

export default createAxios

/**
 * 关闭Loading层实例
 */
function closeLoading(options: Options) {
    if (options.loading && loadingInstance.count > 0) loadingInstance.count--
    if (loadingInstance.count === 0) {
        loadingInstance.target.close()
        loadingInstance.target = null
    }
}

/**
 * 储存每个请求的唯一cancel回调, 以此为标识
 */
function addPending(config: AxiosRequestConfig) {
    const pendingKey = getPendingKey(config)
    config.cancelToken =
        config.cancelToken ||
        new axios.CancelToken(cancel => {
            if (!pendingMap.has(pendingKey)) {
                pendingMap.set(pendingKey, cancel)
            }
        })
}

/**
 * 删除重复的请求
 */
function removePending(config: AxiosRequestConfig) {
    const pendingKey = getPendingKey(config)
    if (pendingMap.has(pendingKey)) {
        const cancelToken = pendingMap.get(pendingKey)
        cancelToken(pendingKey)
        pendingMap.delete(pendingKey)
    }
}

/**
 * 生成每个请求的唯一key
 */
function getPendingKey(config: AxiosRequestConfig) {
    let { data } = config
    const { url, method, params, headers } = config
    if (typeof data === 'string') data = JSON.parse(data) // response里面返回的config.data是个字符串对象
    return [
        url,
        method,
        headers && (headers as anyObj).Authorization ? (headers as anyObj).Authorization : '',
        headers && (headers as anyObj)['ba-user-token'] ? (headers as anyObj)['ba-user-token'] : '',
        JSON.stringify(params),
        JSON.stringify(data)
    ].join('&')
}

/**
 * 根据请求方法组装请求数据/参数
 */
export function requestPayload(method: Method, data: anyObj, paramsPOST: boolean) {
    if (method == 'GET') {
        return {
            params: data
        }
    } else if (method == 'POST') {
        if (paramsPOST) {
            return { params: data }
        } else {
            return { data: data }
        }
    }
}
// 适配器, 用于适配不同的请求方式
export function baseRequest(url, value = {}, method = 'post', options = {}) {
    url = sysConfig.API_URL + url
    if (method === 'post') {
        return service.post(url, value, options)
    } else if (method === 'get') {
        return service.get(url, { params: value, ...options })
    } else if (method === 'formdata') {
        // form-data表单提交的方式
        return service.post(url, qs.stringify(value), {
            headers: {
                'Content-Type': 'multipart/form-data'
            },
            ...options
        })
    } else {
        // 其他请求方式，例如：put、delete
        return service({
            method: method,
            url: url,
            data: value,
            ...options
        })
    }
}
// 模块内的请求, 会自动加上模块的前缀
export const moduleRequest =
    moduleUrl =>
    (url, ...arg) => {
        return baseRequest(moduleUrl + url, ...arg)
    }

interface LoadingInstance {
    target: any
    count: number
}

interface Options {
    // 是否开启取消重复请求, 默认为 true
    CancelDuplicateRequest?: boolean
    // 是否开启loading层效果, 默认为false
    loading?: boolean
    // 是否开启简洁的数据结构响应, 默认为true
    reductDataFormat?: boolean
    // 是否开启code不为A0000时的信息提示, 默认为true
    showCodeMessage?: boolean
    // 是否开启code为0时的信息提示, 默认为false
    showSuccessMessage?: boolean
    // 当前请求使用另外的用户token
    anotherToken?: string
}
