import { AxiosInstance, AxiosRequestConfig, AxiosError } from 'axios';
import { Ref } from 'vue';


/** 请求工具配置项 */
export type CurringConfig = AxiosRequestConfig & {
  /** 请求实例 */
  axiosInstance?: AxiosInstance

  /** 请求方法 */
  method?: Method

  /** 请求的body数据 */
  data?: any

  /** 请求的query数据 */
  params?: any

  /** 接口地址前缀 */
  urlPrefix?: string

  /** 标记为公共接口，不需要鉴权，默认为false */
  public?: boolean

  /** 请求成功执行的回调 */
  onSuccess?: (res: any, config: CurringConfig) => Promise<any>

  /** 请求失败执行的回调 */
  onError?: (error: any, config: CurringConfig) => Promise<any>

  /** 自定义处理请求失败执行的回调 */
  onCustomError?: (error: any, config: CurringConfig) => Promise<any>

  /** 不管请求成功或失败都会执行的回调 */
  finally?: (config: CurringConfig) => any

  /** 每次请求之前都会执行的函数 */
  beforeRun?: (config: CurringConfig) => Promise<CurringConfig>

  /** 自定义错误信息 */
  customErrorMessage?: (
    /** 原始错误信息 */
    message: string,

    /** 原始错误对象 */
    error: any,
  ) => string | null | undefined

  /** 忽略错误提示 */
  ignoreErrorMessage?: boolean

  /** 接口401是否重定向到登录页 */
  noRedireLogin?: boolean

  /** 开启CSRF安全选项 */
  csrf?: boolean
}

export type Method = 'get' | 'post' | 'put' | 'delete' | 'patch'

export type CurringConfigFun = (config: CurringConfig) => CurringConfig | Promise<CurringConfig>

export type CurringRes = {
  /** 请求时返回的接口数据 */
  data: Ref<any>

  /** 请求时的错误信息 */
  error: Ref<any>

  /** 请求时的loading */
  loading: Ref<boolean>

  /** 发起请求 返回格式 [ error, data ] */
  run: (payload?: any, config?: CurringConfig) => CurringRunRes

  /** 取消请求控制器 */
  abortController: Ref<AbortController | null>
}

/** 返回为数组 [error, data], 请求成功error为null，请求失败data为null */
export type CurringRunRes = Promise<
  [
    /** 请求返回的错误信息，请求成功时为null，请求失败时为错误信息 */
    error: { code: string | number; msg: string; error: AxiosError } | null,

    /** 请求返回的接口数据，请求成功时为后端数据，请求失败时为null */
    data: any | null,
  ]
>
