import axios, {
  AxiosInstance,
  AxiosResponse,
  AxiosRequestConfig
} from "axios";
import { Des3Util } from "./Des3Util";
import { ApiResponse } from "./Dto";
import * as crypto from "uuid";

export type Options = {
  url: string;

  /**
   * 是否加密
   */
  secure?: boolean;
  key?: string;
  iv?: string;

  /**
   * 默认1.0.0
   */
  version?: string;

  timeout?: number;
};

/**
 * 非标接口客户端
 */
export class ApiClient {
  public readonly axiosInstance: AxiosInstance;

  constructor(opts: Options) {
    let axiosInstance = axios.create({
      baseURL: opts.url,
      timeout: opts.timeout || 10000,
      headers: {
        "Content-Type": "application/json;charset=utf-8",
        version: opts.version || "1.0.0",
      },
    });

    axiosInstance.interceptors.request.use((config) => {
      let headers = config.headers || {};
      if (!headers["trace-id"]) headers["trace-id"] = crypto.v4();
      config.headers = headers;

      if (!opts.secure) return config;

      let data = config.data || {};
      let new_data = {
        data: Des3Util.encrypt(data, opts.key, opts.iv),
      };

      if (data.imageInfo) new_data["imageInfo"] = data.imageInfo;

      config.data = new_data;

      return config;
    });

    this.axiosInstance = axiosInstance;
  }

  async post<T = any, D = any>(
    url: string,
    data?: D,
    config?: AxiosRequestConfig & { apiDesc?: string }
  ) {
    let res = await this.axiosInstance.post<
      ApiResponse<T>,
      AxiosResponse<ApiResponse<T>>
    >(url, data, config);
    return res.data;
  }
}
