import axios, {AxiosInstance, AxiosResponse, AxiosError} from 'axios';

interface ErrorResponse {
  status: number;
  data: any | null;
  message: string;
}

export class HttpClient {
  private client: AxiosInstance;

  constructor(baseURL: string) {
    this.client = axios.create({
      baseURL,
      timeout: 5000, // timeout in ms
    });
  }

  public async get<T>(
    url: string,
    headers: Record<string, string> = {},
  ): Promise<T | ErrorResponse> {
    try {
      const response: AxiosResponse<T> = await this.client.get(url, {headers});
      return response.data;
    } catch (error) {
      return this.handleError(error);
    }
  }

  public async post<T>(
    url: string,
    data: any,
    headers: Record<string, string> = {},
  ): Promise<T | ErrorResponse> {
    try {
      const response: AxiosResponse<T> = await this.client.post(url, data, {
        headers,
      });
      return response.data;
    } catch (error) {
      return this.handleError(error);
    }
  }

  public async put<T>(
    url: string,
    data: any,
    headers: Record<string, string> = {},
  ): Promise<T | ErrorResponse> {
    try {
      const response: AxiosResponse<T> = await this.client.put(url, data, {
        headers,
      });
      return response.data;
    } catch (error) {
      return this.handleError(error);
    }
  }

  public async delete<T>(
    url: string,
    headers: Record<string, string> = {},
  ): Promise<T | ErrorResponse> {
    try {
      const response: AxiosResponse<T> = await this.client.delete(url, {
        headers,
      });
      return response.data;
    } catch (error) {
      return this.handleError(error);
    }
  }

  private handleError(error: AxiosError): ErrorResponse {
    if (error.response) {
      return {
        status: error.response.status,
        data: error.response.data,
        message: error.response.statusText || 'Unknown Error',
      };
    } else if (error.request) {
      return {
        status: 0,
        data: null,
        message: 'No response received from the server',
      };
    } else {
      return {
        status: 0,
        data: null,
        message: error.message,
      };
    }
  }
}

export default HttpClient;
