/**
 * Web Request Adapter
 *
 * 基于 axios 的请求适配器实现
 */

import type {
  IRequestAdapter,
  RequestConfig,
  RequestResponse,
  RequestInterceptor,
} from './interface';

export class WebRequestAdapter implements IRequestAdapter {
  private axios: any;
  private instance: any;
  private interceptors: RequestInterceptor[] = [];

  constructor(axios: any) {
    this.axios = axios;
    this.instance = axios.create({
      timeout: 30000,
      headers: {
        'Content-Type': 'application/json',
      },
    });

    this.setupInterceptors();
  }

  private setupInterceptors() {
    // 请求拦截器
    this.instance.interceptors.request.use(
      async (config: any) => {
        let modifiedConfig = config;
        for (const interceptor of this.interceptors) {
          if (interceptor.onRequest) {
            modifiedConfig = await interceptor.onRequest(modifiedConfig);
          }
        }
        return modifiedConfig;
      },
      async (error: any) => {
        for (const interceptor of this.interceptors) {
          if (interceptor.onRequestError) {
            await interceptor.onRequestError(error);
          }
        }
        return Promise.reject(error);
      }
    );

    // 响应拦截器
    this.instance.interceptors.response.use(
      async (response: any) => {
        let modifiedResponse = response;
        for (const interceptor of this.interceptors) {
          if (interceptor.onResponse) {
            modifiedResponse = await interceptor.onResponse(modifiedResponse);
          }
        }
        return modifiedResponse;
      },
      async (error: any) => {
        for (const interceptor of this.interceptors) {
          if (interceptor.onResponseError) {
            await interceptor.onResponseError(error);
          }
        }
        return Promise.reject(error);
      }
    );
  }

  async request<T = any>(config: RequestConfig): Promise<RequestResponse<T>> {
    const response = await this.instance.request(config);
    return response;
  }

  async get<T = any>(
    url: string,
    params?: Record<string, any>,
    config?: Partial<RequestConfig>
  ): Promise<RequestResponse<T>> {
    return this.request<T>({
      url,
      method: 'GET',
      params,
      ...config,
    });
  }

  async post<T = any>(
    url: string,
    data?: any,
    config?: Partial<RequestConfig>
  ): Promise<RequestResponse<T>> {
    return this.request<T>({
      url,
      method: 'POST',
      data,
      ...config,
    });
  }

  async put<T = any>(
    url: string,
    data?: any,
    config?: Partial<RequestConfig>
  ): Promise<RequestResponse<T>> {
    return this.request<T>({
      url,
      method: 'PUT',
      data,
      ...config,
    });
  }

  async delete<T = any>(url: string, config?: Partial<RequestConfig>): Promise<RequestResponse<T>> {
    return this.request<T>({
      url,
      method: 'DELETE',
      ...config,
    });
  }

  addInterceptor(interceptor: RequestInterceptor): void {
    this.interceptors.push(interceptor);
  }

  setBaseURL(baseURL: string): void {
    this.instance.defaults.baseURL = baseURL;
  }

  setHeader(key: string, value: string): void {
    this.instance.defaults.headers.common[key] = value;
  }
}
