import { type RequestOptions, type ResponseData } from './types'
import { BASE_URL, REQUEST_TIMEOUT } from './config'
import { requestInterceptor, responseInterceptor, errorInterceptor } from './interceptor'
import obj from '@/utils/obj'

class HttpRequest {
  private baseURL: string
  private timeout: number

  constructor() {
    this.baseURL = BASE_URL
    this.timeout = REQUEST_TIMEOUT
  }

  public async http<T>(options: RequestOptions): Promise<T> {
    try {
      obj.clearNullProps(options.data)
      const interceptedOptions = await requestInterceptor(options)
      // URL处理
      let url = this.baseURL + interceptedOptions.url
      const response = (await uni.request({
        ...interceptedOptions,
        url,
        timeout: this.timeout,
      })) as unknown as ResponseData<T>

      return (await responseInterceptor(response)).data
    } catch (error) {
      return errorInterceptor(error) as any
    }
  }

  public async get<T>(url: string, data?: any, options: Partial<RequestOptions> = {}): Promise<T> {
    return this.http<T>({
      url,
      data,
      method: 'GET',
      ...options,
    })
  }

  // 默认是json格式
  public async post<T>(url: string, data?: any, options: Partial<RequestOptions> = {}): Promise<T> {
    return this.http<T>({
      url,
      data,
      method: 'POST',
      ...options,
      header: {
        'Content-Type': 'application/json',
        ...options.header,
      },
    })
  }

  // 表单格式
  public async postForm<T>(
    url: string,
    data?: any,
    options: Partial<RequestOptions> = {},
  ): Promise<T> {
    return this.http<T>({
      url,
      data,
      method: 'POST',
      ...options,
      header: {
        'Content-Type': 'application/x-www-form-urlencoded',
        ...options.header,
      },
    })
  }
}

export const request = new HttpRequest()
