import { apiEndpoints } from "@/lib/api/endpoints";
import type { LoginResponse } from "@/types/api";

const API_PREFIX = "/api/proxy";

function isHardAuthFailure(error: unknown) {
  const message = String(error);
  return message.includes("400") || message.includes("401");
}

function extractErrorMessage(payload: unknown): string | null {
  if (!payload || typeof payload !== "object") {
    return null;
  }

  const candidate = payload as { message?: unknown; error?: unknown };
  if (Array.isArray(candidate.message)) {
    return candidate.message.map((item) => String(item)).join(", ");
  }
  if (typeof candidate.message === "string" && candidate.message.trim()) {
    return candidate.message.trim();
  }
  if (typeof candidate.error === "string" && candidate.error.trim()) {
    return candidate.error.trim();
  }
  return null;
}

async function request<T>(path: string, init?: RequestInit): Promise<T> {
  const isFormDataRequest =
    typeof FormData !== "undefined" && init?.body instanceof FormData;

  const res = await fetch(`${API_PREFIX}${path}`, {
    ...init,
    credentials: "include",
    headers: {
      ...(isFormDataRequest ? {} : { "Content-Type": "application/json" }),
      ...(init?.headers ?? {}),
    },
  });

  if (!res.ok) {
    const contentType = res.headers.get("content-type") ?? "";
    let detail = "";

    if (contentType.includes("application/json")) {
      const payload = (await res.json()) as unknown;
      const message = extractErrorMessage(payload);
      detail = message ? ` - ${message}` : ` - ${JSON.stringify(payload)}`;
    } else {
      const text = await res.text();
      detail = text ? ` - ${text}` : "";
    }

    throw new Error(`Request failed: ${res.status}${detail}`);
  }

  if (res.status === 204) {
    return undefined as T;
  }

  return res.json() as Promise<T>;
}

export async function loginSuperAdmin(email: string, password: string): Promise<void> {
  await request<LoginResponse>(apiEndpoints.auth.superAdminLogin, {
    method: "POST",
    body: JSON.stringify({ email, password }),
  });
}

export async function refreshSuperAdmin(): Promise<boolean> {
  try {
    await request<LoginResponse>(apiEndpoints.auth.superAdminRefresh, {
      method: "POST",
      body: JSON.stringify({}),
    });
    return true;
  } catch (error) {
    if (isHardAuthFailure(error)) {
      return false;
    }
    throw error;
  }
}

export async function logoutSuperAdmin(): Promise<void> {
  await request<void>(apiEndpoints.auth.superAdminLogout, {
    method: "POST",
    body: JSON.stringify({}),
  });
}

export async function fetchWithAuth<T>(path: string, init?: RequestInit): Promise<T> {
  const makeRequest = async () => request<T>(path, init);

  try {
    return await makeRequest();
  } catch (error) {
    if (String(error).includes("401")) {
      const refreshed = await refreshSuperAdmin();
      if (refreshed) {
        return makeRequest();
      }
    }
    throw error;
  }
}
