import { Alpine } from "./alpine";
import { getToken } from "./storage";

let endpointPath = "";
let exampleResponse: unknown = null;

function initAPIExplorerDoc(path: string, response: string): void {
  endpointPath = path;
  exampleResponse = JSON.parse(response);
}

function showDocMode(mode: "mock" | "real"): void {
  const mockBtn = document.getElementById("mock-btn");
  const realBtn = document.getElementById("real-btn");
  const responseBody = document.getElementById("response-body");
  const responseStatus = document.getElementById("response-status");
  const responseTime = document.getElementById("response-time");
  const apiResponse = document.querySelector(".api-response");
  const requestBody = document.getElementById(
    "request-body",
  ) as HTMLTextAreaElement;
  const tryItOut = document.getElementById("try-it-out");

  if (
    !mockBtn ||
    !realBtn ||
    !responseBody ||
    !responseStatus ||
    !responseTime ||
    !apiResponse ||
    !requestBody ||
    !tryItOut
  )
    return;

  if (mode === "mock") {
    mockBtn.classList.add("bg-accent", "text-white");
    mockBtn.classList.remove("bg-background-primary", "text-text-primary");
    realBtn.classList.remove("bg-accent", "text-white");
    realBtn.classList.add("bg-background-primary", "text-text-primary");

    apiResponse.classList.remove("hidden");
    requestBody.readOnly = true;
    tryItOut.classList.add("hidden");
    responseBody.textContent = JSON.stringify(exampleResponse, null, 2);
    responseStatus.textContent = "200 OK";
    responseTime.textContent = "Mock";
  } else {
    realBtn.classList.add("bg-accent", "text-white");
    realBtn.classList.remove("bg-background-primary", "text-text-primary");
    mockBtn.classList.remove("bg-accent", "text-white");
    mockBtn.classList.add("bg-background-primary", "text-text-primary");

    apiResponse.classList.add("hidden");
    requestBody.readOnly = false;
    tryItOut.classList.remove("hidden");
  }
}

async function tryDocEndpoint(): Promise<void> {
  const methodSelect = document.getElementById(
    "http-method",
  ) as HTMLSelectElement;
  const requestBody = document.getElementById(
    "request-body",
  ) as HTMLTextAreaElement;
  const responseBody = document.getElementById("response-body");
  const responseStatus = document.getElementById("response-status");
  const responseTime = document.getElementById("response-time");
  const apiResponse = document.querySelector(".api-response");

  if (
    !methodSelect ||
    !requestBody ||
    !responseBody ||
    !responseStatus ||
    !responseTime ||
    !apiResponse
  )
    return;

  const method = methodSelect.value;
  const body = requestBody.value;

  const startTime = Date.now();
  try {
    const token = getToken();
    if (!token) {
      throw new Error("No authentication token found");
    }

    const response = await fetch(endpointPath, {
      method: method,
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${token}`,
      },
      body: ["GET", "DELETE"].includes(method) ? undefined : body,
    });

    const duration = Date.now() - startTime;
    const data = await response.json();

    responseStatus.textContent = `${response.status} (${response.statusText})`;
    responseTime.textContent = `${duration}ms`;
    responseBody.textContent = JSON.stringify(data, null, 2);
    apiResponse.classList.remove("hidden");
  } catch (error) {
    responseStatus.textContent = "Error";
    responseBody.textContent = (error as Error).message;
    apiResponse.classList.remove("hidden");
  }
}

function copyDocRequest(): void {
  const requestBody = document.getElementById(
    "request-body",
  ) as HTMLTextAreaElement;
  if (requestBody) {
    navigator.clipboard.writeText(requestBody.value);
  }
}

function copyDocResponse(): void {
  const responseBody = document.getElementById("response-body");
  if (responseBody) {
    navigator.clipboard.writeText(responseBody.textContent || "");
  }
}

function generateDocCURL(): void {
  const methodSelect = document.getElementById(
    "http-method",
  ) as HTMLSelectElement;
  const requestBody = document.getElementById(
    "request-body",
  ) as HTMLTextAreaElement;

  if (!methodSelect || !requestBody) return;

  const method = methodSelect.value;
  const body = requestBody.value;
  const token = getToken();

  let curl = `curl -X ${method} \\n  -H "Content-Type: application/json" \\n  -H "Authorization: Bearer ${token}"`;

  if (!["GET", "DELETE"].includes(method) && body.trim()) {
    curl += ` \\n  -d '${body}'`;
  }

  curl += ` \\n  ${endpointPath}`;

  navigator.clipboard.writeText(curl);
}

export {
  copyDocRequest,
  copyDocResponse,
  generateDocCURL,
  initAPIExplorerDoc,
  showDocMode,
  tryDocEndpoint,
};

Alpine.data("apiExplorerDoc", () => ({
  copyDocRequest,
  copyDocResponse,
  generateDocCURL,
  initAPIExplorerDoc,
  showDocMode,
  tryDocEndpoint,
}));
