import "server-only";

import { chromium } from "playwright";
import type { ProposalWorkflowState } from "@/lib/proposals/workflow-state";

export type ProposalPdfKind = "technical" | "economic" | "summary";

export type ProposalPdfInput = {
  kind: ProposalPdfKind;
  proposal: {
    title: string;
    issuingEntity: string;
    summary: string;
    status: string;
    currentStep: number;
    completionPercent: number;
    updatedAtIso: string;
  };
  workflow: ProposalWorkflowState;
};

function escapeHtml(value: string) {
  return value
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;");
}

function formatDateTime(value: string) {
  const parsed = new Date(value);
  if (Number.isNaN(parsed.getTime())) {
    return value;
  }

  return parsed.toLocaleString("es-MX", {
    year: "numeric",
    month: "long",
    day: "2-digit",
    hour: "2-digit",
    minute: "2-digit",
  });
}

function formatCurrency(value: number) {
  return value.toLocaleString("es-MX", {
    style: "currency",
    currency: "MXN",
    maximumFractionDigits: 2,
  });
}

function renderHeader(input: ProposalPdfInput) {
  return `
    <header class="header">
      <h1>${escapeHtml(input.proposal.title)}</h1>
      <p><strong>Entidad:</strong> ${escapeHtml(input.proposal.issuingEntity || "Por definir")}</p>
      <p><strong>Estatus:</strong> ${escapeHtml(input.proposal.status)} · <strong>Progreso:</strong> ${input.proposal.completionPercent}%</p>
      <p><strong>Actualizada:</strong> ${escapeHtml(formatDateTime(input.proposal.updatedAtIso))}</p>
    </header>
  `;
}

function renderTechnicalSections(input: ProposalPdfInput) {
  const rows = input.workflow.technicalSections
    .map((item, index) => {
      return `
        <tr>
          <td>${index + 1}</td>
          <td>${escapeHtml(item.title)}</td>
          <td>${escapeHtml(item.description)}</td>
          <td>${item.completed ? "Completada" : "Pendiente"}</td>
        </tr>
      `;
    })
    .join("");

  return `
    <section>
      <h2>Propuesta Tecnica</h2>
      <table>
        <thead>
          <tr>
            <th>#</th>
            <th>Seccion</th>
            <th>Descripcion</th>
            <th>Estatus</th>
          </tr>
        </thead>
        <tbody>
          ${rows || '<tr><td colspan="4">Sin secciones registradas.</td></tr>'}
        </tbody>
      </table>
    </section>
  `;
}

function renderEconomicItems(input: ProposalPdfInput) {
  const rows = input.workflow.economicItems
    .map((item, index) => {
      const lineTotal = item.quantity * item.unitPrice;
      return `
        <tr>
          <td>${index + 1}</td>
          <td>${escapeHtml(item.concept)}</td>
          <td>${escapeHtml(item.unit)}</td>
          <td>${item.quantity}</td>
          <td>${formatCurrency(item.unitPrice)}</td>
          <td>${formatCurrency(lineTotal)}</td>
        </tr>
      `;
    })
    .join("");

  const subtotal = input.workflow.economicItems.reduce((acc, item) => acc + item.quantity * item.unitPrice, 0);
  const iva = subtotal * 0.16;
  const total = subtotal + iva;

  return `
    <section>
      <h2>Propuesta Economica</h2>
      <table>
        <thead>
          <tr>
            <th>#</th>
            <th>Concepto</th>
            <th>Unidad</th>
            <th>Cantidad</th>
            <th>P. Unitario</th>
            <th>Subtotal</th>
          </tr>
        </thead>
        <tbody>
          ${rows || '<tr><td colspan="6">Sin conceptos registrados.</td></tr>'}
        </tbody>
      </table>

      <div class="totals">
        <p><span>Subtotal:</span> <strong>${formatCurrency(subtotal)}</strong></p>
        <p><span>IVA (16%):</span> <strong>${formatCurrency(iva)}</strong></p>
        <p><span>Total:</span> <strong>${formatCurrency(total)}</strong></p>
      </div>
    </section>
  `;
}

function renderSummary(input: ProposalPdfInput) {
  const requirements = input.workflow.requirements
    .map((item) => `<li><strong>${escapeHtml(item.title)}</strong> — ${escapeHtml(item.status)}</li>`)
    .join("");
  const milestones = input.workflow.milestones
    .map((item) => `<li><strong>${escapeHtml(item.title)}</strong> — ${escapeHtml(item.dateIso ? formatDateTime(item.dateIso) : "Sin fecha")}</li>`)
    .join("");

  return `
    <section>
      <h2>Resumen de la Licitacion</h2>
      <p>${escapeHtml(input.workflow.info.description || input.proposal.summary || "Sin descripcion disponible.")}</p>
      <p><strong>Tipo/Jurisdiccion:</strong> ${escapeHtml(input.workflow.info.procedureType)} · ${escapeHtml(input.workflow.info.jurisdiction)}</p>
      <p><strong>Ubicacion:</strong> ${escapeHtml(input.workflow.info.state)} · ${escapeHtml(input.workflow.info.municipality)}</p>
    </section>

    <section>
      <h3>Checklist</h3>
      <ul>${requirements || "<li>Sin requisitos registrados.</li>"}</ul>
    </section>

    <section>
      <h3>Fechas importantes</h3>
      <ul>${milestones || "<li>Sin fechas registradas.</li>"}</ul>
    </section>
  `;
}

function renderBody(input: ProposalPdfInput) {
  if (input.kind === "technical") {
    return renderTechnicalSections(input);
  }

  if (input.kind === "economic") {
    return renderEconomicItems(input);
  }

  return renderSummary(input);
}

function renderHtml(input: ProposalPdfInput) {
  const title =
    input.kind === "technical"
      ? "PDF - Propuesta Tecnica"
      : input.kind === "economic"
        ? "PDF - Propuesta Economica"
        : "PDF - Resumen de Licitacion";

  return `
    <!doctype html>
    <html lang="es">
      <head>
        <meta charset="utf-8" />
        <title>${escapeHtml(title)}</title>
        <style>
          * { box-sizing: border-box; }
          body { font-family: Arial, sans-serif; color: #1c2b46; margin: 0; padding: 30px; font-size: 12px; }
          h1 { font-size: 24px; margin: 0 0 8px; }
          h2 { font-size: 18px; margin: 20px 0 10px; }
          h3 { font-size: 14px; margin: 16px 0 8px; }
          p { margin: 4px 0; line-height: 1.4; }
          .header { border-bottom: 1px solid #d6deeb; padding-bottom: 10px; }
          table { width: 100%; border-collapse: collapse; margin-top: 8px; }
          th, td { border: 1px solid #d6deeb; padding: 8px; vertical-align: top; text-align: left; }
          thead th { background: #eef2f8; }
          .totals { margin-top: 12px; width: 280px; margin-left: auto; }
          .totals p { display: flex; justify-content: space-between; }
          ul { margin: 8px 0 0 18px; padding: 0; }
          li { margin: 4px 0; }
        </style>
      </head>
      <body>
        ${renderHeader(input)}
        ${renderBody(input)}
      </body>
    </html>
  `;
}

export function buildPdfFilename(args: { kind: ProposalPdfKind; title: string }) {
  const suffix = args.kind === "technical" ? "propuesta-tecnica" : args.kind === "economic" ? "propuesta-economica" : "resumen-licitacion";
  const safeTitle =
    args.title
      .trim()
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, "-")
      .replace(/^-+|-+$/g, "") || "propuesta";

  return `${safeTitle}-${suffix}.pdf`;
}

export async function generateProposalPdf(input: ProposalPdfInput) {
  const browser = await chromium.launch({
    headless: true,
  });

  try {
    const page = await browser.newPage();
    await page.setContent(renderHtml(input), { waitUntil: "load" });
    const buffer = await page.pdf({
      format: "A4",
      printBackground: true,
      margin: {
        top: "16mm",
        right: "12mm",
        bottom: "16mm",
        left: "12mm",
      },
    });

    return buffer;
  } finally {
    await browser.close();
  }
}

