import axios from 'axios'
import type { AxiosResponse, AxiosError, AxiosRequestConfig } from 'axios'
import type { ApiResponse } from '@/api/types'
import { ElNotification } from 'element-plus'
import { getStorage, setStorage, removeStorage } from '@/utils/storage'
import router from '../router'

// 扩展 AxiosRequestConfig，添加 showMessage 属性
export interface RequestConfig<T = unknown> extends AxiosRequestConfig<T> {
  showMessage?: boolean
}

// 记录当前请求数量，用于控制顶部进度条
let requestCount = 0

// 获取 TopLoading 实例
const getTopLoading = () => {
  // @ts-ignore
  return window.__topLoading__
}

// 显示顶部进度条
const showLoading = () => {
  if (requestCount === 0) {
    getTopLoading()?.start()
  }
  requestCount++
}

// 关闭顶部进度条
const hideLoading = () => {
  requestCount--
  if (requestCount <= 0) {
    getTopLoading()?.complete()
    requestCount = 0
  }
}

// 1. 环境自动识别 + 配置读取（核心修改：适配Vite环境变量）
const env = import.meta.env
const baseURL = env.VITE_API_BASE_URL || ''
const timeout = Number(env.VITE_REQUEST_TIMEOUT) || 10000

// 2. 创建axios实例
const service = axios.create({
  baseURL,
  timeout,
  headers: { 'Content-Type': 'application/json;charset=utf-8' },
})

// 3. 请求拦截器：直接使用 axios 内置类型
const requestInterceptor = (config: RequestConfig) => {
  console.log('请求配置', config)

  // 显示顶部进度条
  showLoading()
  // 添加token到请求头
  const token = getStorage('token')
  if (token && config.headers) {
    config.headers.token = token
  }
  return config
}

const requestErrorInterceptor = (error: AxiosError) => {
  // 请求拦截器出错时也要关闭loading
  ElNotification({
    message: error.message || '未知的请求错误！',
    type: 'error',
    duration: 2000,
  })
  hideLoading()

  return Promise.reject(error)
}

service.interceptors.request.use(requestInterceptor, requestErrorInterceptor)

// 4. 响应拦截器
const responseInterceptor = <T = unknown>(response: AxiosResponse<ApiResponse<T>>) => {
  //关闭loading（无论成功失败都要关）
  hideLoading()
  const config = response.config as RequestConfig
  // axios 会将响应头规范化为小写，同时尝试大小写版本以兼容不同服务器
  const newToken = response.headers['new-token'] || response.headers['New-Token']
  if (newToken) {
    setStorage('token', newToken as string, 'local')
    console.log('Token 已更新:', newToken)
  }
  
  console.log('响应response', response)
  const { data } = response
  console.log('响应数据data', data)
  // 判断业务状态码
  if (data.code == 200 || data.code == 0) {
     if (config.showMessage !== false) {
      ElNotification({
        message: data.msg || '操作成功！',
        type: 'success',
        duration: 2000,
        customClass: 'global-notification'
      })
    }
    return data.data
  } else {
    switch (data.code) {
      case 1:
        // 跳转到注册页
        window.location.href = '/user/register'
        throw new Error(data.msg || '未知的错误！')
      case -100:
        // 退出登录
        data.msg = 'token过期！'
        removeStorage('token')
        removeStorage('userInfo')
        removeStorage('menusInfo')
        removeStorage('permissionsInfo')
        setTimeout(()=>{ 
          window.location.href = '/user/login'
        }, 1000)
        break
      case -101:
        data.msg = 'token错误！'
        removeStorage('token')
        setTimeout(()=>{ 
          window.location.href = '/user/login'
        }, 1000)
        break
      default:
        ElNotification({
          message: data.msg,
          type: 'error',
          duration: 2000,
          customClass: 'global-notification'
        })
        throw new Error(data.msg || '操作失败！')
    }

    // 其他业务失败：弹错误提示并拒绝Promise
    ElNotification({
      message: data.msg || '未知的错误！',
      type: 'error',
      duration: 2000,
      customClass: 'global-notification',
    })
    return Promise.reject(data)
  }
}

const responseErrorInterceptor = (error: AxiosError) => {
  // 响应失败，关闭loading
  hideLoading()

  // 分类处理不同类型的网络错误
  let errMsg = ''
  if (error.message === 'Network Error') {
    errMsg = '网络异常，请检查您的网络连接！'
  } else if (error.code === 'ECONNABORTED') {
    errMsg = `请求超时！请求耗时超过 ${timeout / 1000} 秒`
  } else if (error.response) {
    // 有响应状态码的错误
    const status = error.response.status
    switch (status) {
      case 401:
        errMsg = '登录状态过期，请重新登录！'
        // 可在此处添加跳转到登录页的逻辑
        break
      case 403:
        errMsg = '您没有权限访问该资源！'
        break
      case 404:
        errMsg = '请求的资源不存在！'
        break
      case 500:
        errMsg = '服务器内部错误，请稍后重试！'
        break
      default:
        errMsg = (error.response?.data as ApiResponse)?.msg || `请求失败：${status}`
    }
  } else {
    errMsg = error.message || '服务器错误'
  }

   if ((error.config as RequestConfig)?.showMessage !== false) {
    ElNotification({
      message: errMsg,
      type: 'error',
      duration: 2000,
      customClass: 'global-notification'
    })
   }
  return Promise.reject(error)
}

service.interceptors.response.use(responseInterceptor, responseErrorInterceptor)

// 5. 封装通用请求方法
export const request = {
  get<T = unknown>(url: string, params?: unknown, config?: RequestConfig): Promise<T> {
    return service.get<ApiResponse<T>>(url, { params, ...config }).then((res) => {
      return res as T;
    });
  },
  post<T = unknown>(url: string, data?: unknown, config?: RequestConfig): Promise<T> {
    return service.post<ApiResponse<T>>(url, data, config).then((res) => {
      return res as T;
    });
  },
}

export default service
