import { SHA1, enc } from 'crypto-js'
import { sessionStorage } from '@/plugins/storage'
import { typeOf } from '@/utils/common'
import type { Method, AxiosRequestConfig } from 'axios'
import type { ExtractApiResponse } from '@/api/api'

interface SignTokenParams {
  url?: string
  method?: Method | string
  sessionId: string
  accessToken: string
}

/**
 * @description Http请求签名
 */
export const signToken = ({ sessionId, accessToken, url = '/', method = 'post' }: SignTokenParams) => {
  const timestamp = Date.now()
  const token = `Token ${sessionId}:${enc.Base64.stringify(
    SHA1(`${method?.toLowerCase() || 'post'}&${url}&${timestamp}&${accessToken}`)
  )}`
  return { token, timestamp }
}

/**
 * @description 设置Http请求签名信息
 */
export const setupAuthSign = (config: AxiosRequestConfig) => {
  config.headers = config.headers || {}
  if (!config.noAuth) {
    const { sessionId, accessToken } = (sessionStorage.get('LOGIN_RESULT') as ExtractApiResponse<'userLogin'>) || {}
    const { token, timestamp } = signToken({
      url: config.url,
      method: config.method,
      sessionId: sessionId,
      accessToken: accessToken,
    })
    config.headers['Authorization'] = token
    config.headers['time'] = timestamp
  }
  return config
}

/**
 * @description 除了文件上传以外, 其它默认使用表单形式提交数据
 */
export const transformRequestData = (config: AxiosRequestConfig) => {
  config.headers = config.headers || {}
  if (config.headers['Content-Type']?.toString().includes('application/x-www-form-urlencoded')) {
    config.data = new URLSearchParams(config.data)
  }
  return config
}

/**
 * @description 添加examId参数
 */
export const appendExamId = (config: AxiosRequestConfig) => {
  config.params ??= {}
  config.params.examId = sessionStorage.get('EXAM_ID')
  return config
}

/**
 * @description get请求数组参数转换
 */

export const transformGetParams = (config: AxiosRequestConfig) => {
  if (config.method?.toLowerCase() === 'get') {
    config.params ??= {}
    for (const k in config.params) {
      if (typeOf(config.params[k]) === 'array') {
        config.params[k] = config.params[k].join(',')
      }
    }
  }
  return config
}
