// API_BASE now uses relative path for proxy, or falls back to direct API URL
export const API_BASE = process.env.NEXT_PUBLIC_WATCH_FINISHED_API || "/api";

function buildUrl(path: string, params?: any) {
  // If API_BASE starts with http, use it as absolute URL
  // Otherwise, use it as relative path (for proxy)
  const base = API_BASE.startsWith("http") ? API_BASE : "";
  const fullPath = API_BASE.startsWith("http") ? path : `${API_BASE}${path}`;

  const url = base
    ? new URL(fullPath, base)
    : new URL(fullPath, window.location.origin);
  if (params && typeof params === "object") {
    Object.entries(params).forEach(([k, v]) => {
      if (v !== undefined && v !== null) url.searchParams.append(k, String(v));
    });
  }
  return url.toString();
}

export async function get<T = any>(path: string, params?: any): Promise<T> {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout

  try {
    const res = await fetch(buildUrl(path, params), {
      method: "GET",
      credentials: "same-origin",
      headers: { Accept: "application/json" },
      signal: controller.signal
    });
    clearTimeout(timeoutId);
    if (!res.ok) throw new Error(await res.text());
    return res.json();
  } catch (error) {
    clearTimeout(timeoutId);
    if (error instanceof Error && error.name === "AbortError") {
      throw new Error("Request timeout");
    }
    throw error;
  }
}

export async function post<T = any>(path: string, data?: any): Promise<T> {
  // const controller = new AbortController();
  // const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout

  try {
    const res = await fetch(buildUrl(path), {
      method: "POST",
      credentials: "same-origin",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: data ? JSON.stringify(data) : undefined
      // signal: controller.signal
    });
    // clearTimeout(timeoutId);
    if (!res.ok) throw new Error(await res.text());
    return res.json();
  } catch (error) {
    // clearTimeout(timeoutId);
    // if (error.name === "AbortError") {
    //   throw new Error("Request timeout");
    // }
    throw error;
  }
}

export async function put<T = any>(path: string, data?: any): Promise<T> {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout

  try {
    const res = await fetch(buildUrl(path), {
      method: "PUT",
      credentials: "same-origin",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json"
      },
      body: data ? JSON.stringify(data) : undefined,
      signal: controller.signal
    });
    clearTimeout(timeoutId);
    if (!res.ok) throw new Error(await res.text());
    return res.json();
  } catch (error) {
    clearTimeout(timeoutId);
    if (error instanceof Error && error.name === "AbortError") {
      throw new Error("Request timeout");
    }
    throw error;
  }
}

export async function del<T = any>(path: string, params?: any): Promise<T> {
  const controller = new AbortController();
  const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout

  try {
    const res = await fetch(buildUrl(path, params), {
      method: "DELETE",
      credentials: "same-origin",
      headers: { Accept: "application/json" },
      signal: controller.signal
    });
    clearTimeout(timeoutId);
    if (!res.ok) throw new Error(await res.text());

    // Handle empty response body (common for DELETE operations)
    const contentLength = res.headers.get("content-length");
    const contentType = res.headers.get("content-type");

    if (
      contentLength === "0" ||
      res.status === 204 ||
      !contentType?.includes("application/json")
    ) {
      return {} as T;
    }

    const text = await res.text();
    if (!text.trim()) {
      return {} as T;
    }

    return JSON.parse(text);
  } catch (error) {
    clearTimeout(timeoutId);
    if (error instanceof Error && error.name === "AbortError") {
      throw new Error("Request timeout");
    }
    throw error;
  }
}
