import axios, { AxiosInstance, AxiosRequestConfig } from "axios";

const API_URL = process.env.NEXT_PUBLIC_API_URL || "http://localhost:4000";

class ApiClient {
  private client: AxiosInstance;

  constructor() {
    this.client = axios.create({
      baseURL: API_URL,
      headers: {
        "Content-Type": "application/json",
      },
    });

    this.client.interceptors.request.use((config) => {
      const token =
        typeof window !== "undefined"
          ? localStorage.getItem("auth_token")
          : null;
      if (token && token !== "null" && token !== "undefined") {
        config.headers.Authorization = `Bearer ${token}`;
      }
      if (typeof window !== "undefined") {
        config.headers["X-Frontend-Base-URL"] = window.location.origin;
      }
      return config;
    });

    // /fayda/verification/* is used by guests filling out the passenger form, and a 401
    // there just means the user canceled/closed the Fayda popup without completing it (no
    // valid verification session) — that should surface as an inline error on the page,
    // not force-clear the session and redirect to /login out from under them.
    const PUBLIC_PREFIXES = [
      "/config/",
      "/auth/login",
      "/auth/register",
      "/passengers/me",
      "/fayda/verification",
    ];

    this.client.interceptors.response.use(
      (response) => response,
      (error) => {
        if (error.response?.status === 401) {
          const url: string = error.config?.url || "";
          const isPublic = PUBLIC_PREFIXES.some((p) => url.includes(p));
          if (!isPublic && typeof window !== "undefined") {
            localStorage.removeItem("auth_token");
            localStorage.removeItem("auth_user");
            // window.location.href = '/login';
          }
        }
        return Promise.reject(error);
      },
    );
  }

  async get<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
    const response = await this.client.get<any>(url, config);
    // Handle both direct data and wrapped responses
    return response.data?.data || response.data;
  }

  async post<T>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig,
  ): Promise<T> {
    const response = await this.client.post<any>(url, data, config);
    return response.data?.data || response.data;
  }

  async put<T>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig,
  ): Promise<T> {
    const response = await this.client.put<T>(url, data, config);
    return response.data;
  }

  async patch<T>(
    url: string,
    data?: any,
    config?: AxiosRequestConfig,
  ): Promise<T> {
    const response = await this.client.patch<T>(url, data, config);
    return response.data;
  }

  async delete<T>(url: string, config?: AxiosRequestConfig): Promise<T> {
    const response = await this.client.delete<T>(url, config);
    return response.data;
  }
}

export const apiClient = new ApiClient();
