import { toaster } from "@/components/ui/feedback/toaster";

import axios, { AxiosError, AxiosInstance } from "axios";
import { getSession, signOut } from "next-auth/react";
import { extractApiErrorMessage } from "./api-error-utils";
import type { ApiResponse } from "@/types/api-response";

// const MESSAGES = {
//   tr: {
//     title: 'Oturum Süresi Doldu',
//     description: 'Güvenliğiniz için çıkış yapıldı. Lütfen tekrar giriş yapınız.',
//   },
//   en: {
//     title: 'Session Expired',
//     description: 'You have been logged out for security reasons. Please log in again.',
//   },
// };

/**
 * Custom error class for API errors with extracted message
 */
export class ApiError extends Error {
  status: number;
  originalResponse: unknown;

  constructor(message: string, status: number, originalResponse?: unknown) {
    super(message);
    this.name = "ApiError";
    this.status = status;
    this.originalResponse = originalResponse;
  }
}

// Throttle 429 toaster - only show once per 5 seconds
let last429ToastTime = 0;
const TOAST_THROTTLE_MS = 5000;

const show429Toast = (message: string) => {
  const now = Date.now();
  if (now - last429ToastTime > TOAST_THROTTLE_MS) {
    last429ToastTime = now;
    toaster.error({
      title: "Too Many Requests",
      description: message || "Lütfen bekleyiniz.",
      duration: 5000,
    });
  }
};

export function createApiClient(baseURL: string): AxiosInstance {
  const client = axios.create({ baseURL });

  // Helper to get locale from cookie or URL
  const getLocale = (): string => {
    if (typeof window !== "undefined") {
      // Try to get from cookie first (NEXT_LOCALE is the default cookie name)
      const cookieLocale = document.cookie
        .split("; ")
        .find((row) => row.startsWith("NEXT_LOCALE="))
        ?.split("=")[1];

      if (cookieLocale) return cookieLocale;

      // Fallback: get from URL path (e.g., /tr/generator -> tr)
      const pathLocale = window.location.pathname.split("/")[1];
      if (["en", "tr", "de"].includes(pathLocale)) return pathLocale;
    }
    return "tr"; // Default locale
  };

  client.interceptors.request.use(async (config) => {
    const session = await getSession();
    const token = session?.accessToken;

    if (token) {
      config.headers.set("Authorization", `Bearer ${token}`);
    }

    // Set Accept-Language header based on current locale
    const locale = getLocale();
    config.headers.set("Accept-Language", locale);

    if (!(config.data instanceof FormData)) {
      config.headers.set("Content-Type", "application/json");
    }

    return config;
  });

  client.interceptors.response.use(
    (response) => {
      // Check for API-level errors (success: false) even on 200 responses
      const data = response.data;
      if (
        data &&
        typeof data === "object" &&
        "success" in data &&
        data.success === false
      ) {
        const errorMessage = extractApiErrorMessage(data, "Bir hata oluştu");

        const errorStatus =
          "status" in data && typeof data.status === "number"
            ? data.status
            : response.status;

        // Handle 429 in success: false body
        if (errorStatus === 429) {
          show429Toast(errorMessage);
        }

        if (errorStatus === 401 && typeof window !== "undefined") {
          const isAuthPath =
            window.location.pathname.includes("/api/auth") ||
            window.location.pathname === "/";

          if (!isAuthPath) {
            void signOut({ redirect: true, callbackUrl: "/" });
          }
        }

        const apiError = new ApiError(errorMessage, errorStatus, data);
        return Promise.reject(apiError);
      }
      return response;
    },
    async (error: AxiosError) => {
      // Handle 429 Too Many Requests
      if (error.response?.status === 429) {
        const responseData = error.response?.data as Partial<ApiResponse>;
        const message =
          responseData?.message || "Too many requests. Please wait a moment.";
        show429Toast(message);
      }

      // Handle 401 Unauthorized
      if (error.response?.status === 401) {
        if (typeof window !== "undefined") {
          const isAuthPath =
            window.location.pathname.includes("/api/auth") ||
            window.location.pathname === "/";

          if (!isAuthPath) {
            await signOut({ redirect: true, callbackUrl: "/" });
          }
        }
      }

      // Extract error message from API response
      const responseData = error.response?.data;
      if (responseData && typeof responseData === "object") {
        const errorMessage = extractApiErrorMessage(
          responseData as Partial<ApiResponse>,
          error.message,
        );
        const apiError = new ApiError(
          errorMessage,
          error.response?.status || 500,
          responseData,
        );
        return Promise.reject(apiError);
      }

      return Promise.reject(error);
    },
  );

  return client;
}
