const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || "http://localhost:8000/api";
const SESSION_KEY = "forgeflow.erp.session";

async function parseResponse(response) {
  const contentType = response.headers.get("content-type") || "";
  const isJson = contentType.includes("application/json");
  const data = isJson ? await response.json() : await response.text();

  if (!response.ok) {
    const detail = typeof data === "object" && data?.detail ? data.detail : `Request failed: ${response.status}`;
    throw new Error(detail);
  }

  return data;
}

function isSessionExpired(session) {
  if (!session?.access_token || !session?.expires_at) {
    return true;
  }

  const expiresAt = Date.parse(session.expires_at);
  if (Number.isNaN(expiresAt)) {
    return true;
  }

  return expiresAt <= Date.now();
}

export async function requestJson(path, options = {}) {
  const { skipAuthRedirect = false, headers = {}, ...fetchOptions } = options;
  const session = readSession();
  const authHeaders =
    session?.access_token && !isSessionExpired(session)
      ? { Authorization: `Bearer ${session.access_token}` }
      : {};
  const response = await fetch(`${API_BASE_URL}${path}`, {
    headers: {
      "Content-Type": "application/json",
      ...authHeaders,
      ...headers
    },
    ...fetchOptions
  });

  if ((response.status === 401 || response.status === 403) && !skipAuthRedirect) {
    clearSession();
    if (typeof window !== "undefined" && window.location.pathname !== "/login") {
      window.location.href = "/login";
    }
  }

  return parseResponse(response);
}

export async function fetchResource(path, fallbackData) {
  try {
    return await requestJson(path, { method: "GET" });
  } catch (error) {
    return fallbackData;
  }
}

export async function postResource(path, payload) {
  return requestJson(path, {
    method: "POST",
    body: JSON.stringify(payload)
  });
}

export async function uploadResource(path, formData) {
  const session = readSession();
  const authHeaders =
    session?.access_token && !isSessionExpired(session)
      ? { Authorization: `Bearer ${session.access_token}` }
      : {};
  const response = await fetch(`${API_BASE_URL}${path}`, {
    method: "POST",
    headers: authHeaders,
    body: formData
  });

  if ((response.status === 401 || response.status === 403) && typeof window !== "undefined" && window.location.pathname !== "/login") {
    clearSession();
    window.location.href = "/login";
  }

  return parseResponse(response);
}

function getDownloadFilename(response, fallbackFilename) {
  const disposition = response.headers.get("content-disposition") || "";
  const encodedMatch = disposition.match(/filename\*=UTF-8''([^;]+)/i);
  if (encodedMatch?.[1]) {
    try {
      return decodeURIComponent(encodedMatch[1]);
    } catch (error) {
      return fallbackFilename;
    }
  }

  const plainMatch = disposition.match(/filename="?([^";]+)"?/i);
  return plainMatch?.[1] || fallbackFilename;
}

export async function downloadResource(path, fallbackFilename = "download.xlsx") {
  const session = readSession();
  const authHeaders =
    session?.access_token && !isSessionExpired(session)
      ? { Authorization: `Bearer ${session.access_token}` }
      : {};
  const response = await fetch(`${API_BASE_URL}${path}`, {
    method: "GET",
    headers: authHeaders
  });

  if ((response.status === 401 || response.status === 403) && typeof window !== "undefined" && window.location.pathname !== "/login") {
    clearSession();
    window.location.href = "/login";
  }

  if (!response.ok) {
    return parseResponse(response);
  }

  const blob = await response.blob();
  const filename = getDownloadFilename(response, fallbackFilename);
  const url = window.URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  link.remove();
  window.URL.revokeObjectURL(url);
  return { filename };
}

export async function postDownloadResource(path, payload, fallbackFilename = "download.zip") {
  const session = readSession();
  const authHeaders =
    session?.access_token && !isSessionExpired(session)
      ? { Authorization: `Bearer ${session.access_token}` }
      : {};
  const response = await fetch(`${API_BASE_URL}${path}`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      ...authHeaders
    },
    body: JSON.stringify(payload)
  });

  if ((response.status === 401 || response.status === 403) && typeof window !== "undefined" && window.location.pathname !== "/login") {
    clearSession();
    window.location.href = "/login";
  }

  if (!response.ok) {
    return parseResponse(response);
  }

  const blob = await response.blob();
  const filename = getDownloadFilename(response, fallbackFilename);
  const url = window.URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = filename;
  document.body.appendChild(link);
  link.click();
  link.remove();
  window.URL.revokeObjectURL(url);
  return { filename };
}

export async function openResource(path) {
  const session = readSession();
  const authHeaders =
    session?.access_token && !isSessionExpired(session)
      ? { Authorization: `Bearer ${session.access_token}` }
      : {};
  const response = await fetch(`${API_BASE_URL}${path}`, {
    method: "GET",
    headers: authHeaders
  });

  if ((response.status === 401 || response.status === 403) && typeof window !== "undefined" && window.location.pathname !== "/login") {
    clearSession();
    window.location.href = "/login";
  }

  if (!response.ok) {
    return parseResponse(response);
  }

  const blob = await response.blob();
  const url = window.URL.createObjectURL(blob);
  window.open(url, "_blank", "noopener,noreferrer");
  window.setTimeout(() => window.URL.revokeObjectURL(url), 60_000);
  return { opened: true };
}

export async function putResource(path, payload) {
  return requestJson(path, {
    method: "PUT",
    body: JSON.stringify(payload)
  });
}

export async function deleteResource(path) {
  return requestJson(path, {
    method: "DELETE"
  });
}

export function saveSession(user) {
  localStorage.setItem(SESSION_KEY, JSON.stringify(user));
}

export function readSession() {
  const raw = localStorage.getItem(SESSION_KEY);
  if (!raw) {
    return null;
  }

  try {
    const session = JSON.parse(raw);
    if (isSessionExpired(session)) {
      localStorage.removeItem(SESSION_KEY);
      return null;
    }
    return session;
  } catch (error) {
    console.warn("Failed to parse session", error);
    localStorage.removeItem(SESSION_KEY);
    return null;
  }
}

export function clearSession() {
  localStorage.removeItem(SESSION_KEY);
}

export function isAuthenticated() {
  return Boolean(readSession());
}

export async function login(username, password) {
  return requestJson("/auth/login", {
    method: "POST",
    body: JSON.stringify({ username, password }),
    skipAuthRedirect: true
  });
}

export function buildApiUrl(path) {
  return `${API_BASE_URL}${path}`;
}
