import axios, {
  AxiosInstance,
  AxiosResponse,
  InternalAxiosRequestConfig,
  AxiosError,
  FormData,
  AxiosRequestHeaders,
  AxiosRequestConfig
} from '@ohos/axios';
import { DEBUG_BASE_URL, RELEASE_BASE_URL } from '../constants/AppConstants';
import { BaseResponse } from './BaseResponse';
import { HeaderInterceptor } from './HeaderInterceptor';
import { EncryptConfig, RequestInterceptor } from './RequestInterceptor';
import { ResponseInterceptor } from './ResponseInterceptor';
import { AppUtil } from '@pura/harmony-utils';
import { Logger } from '../utils/Logger';

/**
 * 模拟 Android 的 ApiManager
 */
export class ApiManager {
  private static instance: ApiManager | null = null;
  private retrofit: AxiosInstance | null = null;
  private unsafeRetrofit: AxiosInstance | null = null;

  private constructor() {
    this.initialize();
  }

  public static getInstance(): ApiManager {
    if (ApiManager.instance === null) {
      ApiManager.instance = new ApiManager();
    }
    return ApiManager.instance;
  }

  /**
   * 集成的泛型请求方法（简单通用的普通请求）
   * @param url 请求路径
   * @param params GET请求的Query参数 (对应 Android 的 @Query)
   * @param method 请求方法
   * @param data 可选的 Body 数据
   */
  public async request<T>(
    url: string,
    params?: Record<string, Object>,
    method: string = 'get',
    data?: Object
  ): Promise<BaseResponse<T>> {
    const service = this.getUnsafeService();

    const response: AxiosResponse<BaseResponse<T>> = await service.request({
      url: url,
      method: method,
      params: params,
      data: data
    });

    return response.data;
  }
  /**
   * 集成的泛型请求方法(特殊处理需要映射字段问题)
   * @param url 请求路径
   * @param params GET请求的Query参数 (对应 Android 的 @Query)
   * @param mapper 可选转换函数
   * @param method 请求方法
   * @param data 可选的 Body 数据
   */
  public async requestForMapper<T>(
    url: string,
    params?: Record<string, Object>,
    mapper?: (raw: Record<string, Object>) => T,
    method: string = 'get', // 新增：默认为 get
    data?: Object           // 新增：用于 POST 的 Body 数据
  ): Promise<T> {
    const service = this.getUnsafeService();

    // 1. 使用通用的 request 方法，根据参数自动切换 GET/POST
    const response: AxiosResponse<BaseResponse<Object>> = await service.request({
      url: url,
      method: method, // 传入 'get' 或 'post'
      params: params, // URL 上的参数（nonce, timestamp, signature 都在这）
      data: data      // Body 里的参数（phone 在这）
    });

    // 2. 提取业务数据 data 部分
    const rawData = (response.data.data ?? {}) as Record<string, Object>;

    // 3. 逻辑转换
    if (mapper !== undefined) {
      return mapper(rawData);
    }

    // 4. 强转逻辑
    return rawData as T;
  }

  /**
   * 文件上传方法
   * @param url 请求路径
   * @param formData FormData 实例
   * @param params Query 参数 (用于签名)
   */
  public async upload<T>(
    url: string,
    formData: FormData,
    params?: Record<string, Object>
  ): Promise<T> {
    const service = this.getUnsafeService();

    // 构造配置对象，避免使用 any
    const config: AxiosRequestConfig = {
      params: params,
      context: getContext(),
      onUploadProgress: (progressEvent) => {
        if (progressEvent.total) {
          Logger.info(RequestInterceptor.TAG, `[上传进度] 已传: ${progressEvent.loaded} Bytes/ 总计: ${progressEvent.total} Bytes`);
        }
      }
    };

    const response: AxiosResponse<BaseResponse<Object>> = await service.post(url, formData, config);
    const rawData = (response.data.data ?? {}) as Record<string, Object>;
    return rawData as T;
  }

  private initialize(): void {
    const isDebug: boolean = AppUtil.debug();
    const baseUrl: string = isDebug ? DEBUG_BASE_URL : RELEASE_BASE_URL;

    // 1. 初始化标准实例
    if (this.retrofit === null) {
      this.retrofit = axios.create({
        baseURL: baseUrl,
        timeout: 10000
      });
      // 基础请求拦截器
      this.retrofit.interceptors.request.use(this.requestInterceptor);
    }

    // 2. 初始化不安全实例
    if (this.unsafeRetrofit === null) {
      this.unsafeRetrofit = axios.create({
        baseURL: baseUrl,
        timeout: 60000,
        // 这里的 data 类型使用 Object, headers 使用 AxiosRequestHeaders
        transformRequest: [(data: Object, headers: AxiosRequestHeaders): Object => {
          // 1. 判断是否为 FormData
          if (data instanceof FormData) {
            headers.set('Content-Type', 'multipart/form-data');
            return data;
          }

          // 2. 判断是否为普通对象 (非空)
          if (data !== null && typeof data === 'object') {
            headers.set('Content-Type', 'application/json');
            return JSON.stringify(data);
          }

          // 3. 其他情况原样返回 (转为 Object 兼容类型)
          return data;
        }]
      });


      // --- 添加请求拦截器链 (注意执行顺序：从下往上/链式触发) ---

      // 添加 Header 拦截器 (注入 Token, 设备信息等)
      this.unsafeRetrofit.interceptors.request.use(HeaderInterceptor);

      // 添加 RequestInterceptor (处理签名、UUID、Nonce、MD5 日志)
      // 注意：因为 onPrepare 是 async，Axios 会自动等待它执行完
      this.unsafeRetrofit.interceptors.request.use(
        (config: InternalAxiosRequestConfig): Promise<InternalAxiosRequestConfig> => {
          return RequestInterceptor.onPrepare(config as EncryptConfig);
        },
        (error: AxiosError): Promise<AxiosError> => Promise.reject(error)
      );

      // --- 添加响应拦截器链 ---

      // 添加 ResponseInterceptor (处理解密、状态码修正、响应日志)
      this.unsafeRetrofit.interceptors.response.use(
        (response: AxiosResponse): Promise<AxiosResponse> => {
          // 先执行解密逻辑
          return ResponseInterceptor.responseHandler(response);
        },
        (error: AxiosError): Promise<AxiosError> => {
          return Promise.reject(error);
        }
      );

      // 可以在这里继续添加统一的错误处理拦截器
      this.unsafeRetrofit.interceptors.response.use(
        (response: AxiosResponse): AxiosResponse => {
          // 执行日志打印
          return RequestInterceptor.onResponse(response);
        },
        this.responseErrorInterceptor
      );
    }
  }


  /**
   * 重新初始化 (对应 Android 的 reinitialize)
   */
  public reinitialize(): void {
    this.retrofit = null;
    this.unsafeRetrofit = null;
    this.initialize();
  }

  // --- 强类型拦截器实现 ---

  private requestInterceptor(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
    // 类似于 Android 的 RequestInterceptor
    config.headers.set('Content-Type', 'application/json');
    return config;
  }

  private responseErrorInterceptor(error: AxiosError): Promise<AxiosError> {
    // 错误处理逻辑
    return Promise.reject(error);
  }

  // --- 获取 Service 实例 ---

  /**
   * 获取不安全/特殊配置的请求实例
   * 在 ArkTS 中直接返回 AxiosInstance 进行调用
   */
  public getUnsafeService(): AxiosInstance {
    if (this.unsafeRetrofit === null) {
      this.initialize();
    }
    return this.unsafeRetrofit as AxiosInstance;
  }
}
