import axios, { type InternalAxiosRequestConfig } from "axios";

/**
 * DTNews API client — NO auth token, all APIs are public.
 * CLAUDE.md rule: never add Authorization headers.
 *
 * user_id is injected automatically into every POST body as "0" for guests
 * and as the stored user's id for logged-in users.
 */
const apiClient = axios.create({
  // Support both CLAUDE.md (NEXT_PUBLIC_API_URL) and legacy .env (NEXT_PUBLIC_API_BASE_URL)
  baseURL: process.env.NEXT_PUBLIC_API_URL ?? process.env.NEXT_PUBLIC_API_BASE_URL,
  headers: {
    "Content-Type": "application/json",
    Accept: "application/json",
  },
  // ❌ NO auth interceptor — this app has no token auth
});

// ── Read user id from localStorage (client-side only) ──────────────────────
function getStoredUserId(): string {
  if (typeof window === "undefined") return "0";
  try {
    const stored = localStorage.getItem("dt_auth_user");
    if (stored) {
      const user = JSON.parse(stored) as { id?: number };
      if (user?.id) return String(user.id);
    }
  } catch {
    // parse error — treat as guest
  }
  return "0";
}

// ── Request interceptor — inject user_id into every POST ──────────────────
// Backend uses user_id (not tokens) for user-specific responses.
// Guests get user_id = "0"; logged-in users get their actual id.
apiClient.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    if (config.method?.toLowerCase() === "post" && config.data) {
      const userId = getStoredUserId();

      if (config.data instanceof FormData) {
        if (!config.data.has("user_id")) {
          config.data.append("user_id", userId);
        }
      } else if (
        typeof config.data === "object" &&
        !Array.isArray(config.data) &&
        !("user_id" in config.data)
      ) {
        config.data = { ...config.data, user_id: userId };
      }
    }
    return config;
  },
  (error) => Promise.reject(error),
);

// ── Response interceptor — normalise API errors ────────────────────────────
// The API uses a body-level `status` field alongside the HTTP status.
// HTTP 200 + body status 4xx + "Data Not Found" → treat as empty result.
apiClient.interceptors.response.use(
  (response) => {
    const bodyStatus = response.data?.status;
    const bodyMessage: string = response.data?.message ?? "";

    if (typeof bodyStatus === "number" && bodyStatus >= 400) {
      if (
        bodyMessage.toLowerCase().includes("not found") ||
        bodyMessage.toLowerCase().includes("data not found")
      ) {
        response.data = { status: 200, message: bodyMessage, result: [] };
        return response;
      }
      return Promise.reject(new Error(bodyMessage || "API error"));
    }
    return response;
  },
  (error) => {
    const msg: string =
      error.response?.data?.message ||
      error.message ||
      "Network error. Please try again.";
    console.error("API Error:", msg);
    return Promise.reject(error);
  },
);

export default apiClient;
