import { NextResponse } from "next/server";
import { eq } from "drizzle-orm";
import { db, schema } from "@/lib/db";
import { requireAdmin } from "@/lib/guards";
import {
  computeHtCents,
  formatEurFromCents,
  isLineItemArray,
  resolveEmitter,
} from "@/lib/invoices";
import type {
  InvoiceClientInfo,
  InvoiceLineItem,
} from "@/lib/db/schema";

/**
 * Page facture imprimable / téléchargeable (HTML qui se print en PDF
 * via Cmd/Ctrl+P du browser). Pas de dep PDF côté server pour rester
 * léger.
 *
 * Gère deux cas :
 *  - Facture auto issue d'un dossier (ligne unique, pas de TVA).
 *  - Facture manuelle (lineItems + TVA optionnelle + override émetteur/client).
 *
 * Admin uniquement.
 */
export async function GET(
  _req: Request,
  { params }: { params: Promise<{ id: string }> }
) {
  await requireAdmin();
  const { id } = await params;

  const inv = (
    await db
      .select()
      .from(schema.invoice)
      .where(eq(schema.invoice.id, id))
      .limit(1)
  )[0];
  if (!inv) {
    return NextResponse.json({ error: "Facture introuvable" }, { status: 404 });
  }

  const client = inv.clientId
    ? (
        await db
          .select()
          .from(schema.user)
          .where(eq(schema.user.id, inv.clientId))
          .limit(1)
      )[0]
    : null;

  const profile = inv.clientId
    ? (
        await db
          .select()
          .from(schema.clientProfile)
          .where(eq(schema.clientProfile.userId, inv.clientId))
          .limit(1)
      )[0]
    : null;

  const dossier = inv.dossierId
    ? (
        await db
          .select()
          .from(schema.dossier)
          .where(eq(schema.dossier.id, inv.dossierId))
          .limit(1)
      )[0]
    : null;

  const emitter = resolveEmitter(
    inv.emitterInfo as Parameters<typeof resolveEmitter>[0]
  );

  /* Détermination du bloc client effectif :
     - override en DB → on l'utilise tel quel
     - sinon → on assemble depuis user + clientProfile */
  const clientInfo: InvoiceClientInfo = (inv.clientInfo as InvoiceClientInfo) ?? {
    name: client?.name ?? "Client supprimé",
    company: profile?.company ?? null,
    email: client?.email ?? null,
    addressStreet: profile?.addressStreet ?? null,
    addressZip: profile?.addressZip ?? null,
    addressCity: profile?.addressCity ?? null,
    addressCountry: profile?.addressCountry ?? null,
    siret: profile?.siret ?? null,
  };

  /* Lignes : soit la liste détaillée (factures manuelles), soit une ligne
     unique reconstruite depuis description + amountCents (factures auto). */
  const lineItems: InvoiceLineItem[] = isLineItemArray(inv.lineItems)
    ? inv.lineItems
    : [
        {
          description: inv.description,
          quantity: 1,
          unitPriceHtCents: inv.amountCents,
        },
      ];

  const htCents = isLineItemArray(inv.lineItems)
    ? computeHtCents(inv.lineItems)
    : inv.amountCents;
  const vatRateBps = inv.vatRateBps;
  const vatCents =
    vatRateBps != null ? Math.round((htCents * vatRateBps) / 10_000) : 0;
  const ttcCents = htCents + vatCents;

  const issuedAt = inv.issuedAt
    ? new Date(inv.issuedAt).toLocaleDateString("fr-FR", {
        day: "numeric",
        month: "long",
        year: "numeric",
      })
    : "—";
  const dueAt = inv.dueAt
    ? new Date(inv.dueAt).toLocaleDateString("fr-FR", {
        day: "numeric",
        month: "long",
        year: "numeric",
      })
    : "—";

  const statusLabels: Record<string, string> = {
    brouillon: "Brouillon",
    envoyee: "À régler",
    payee: "Payée",
    annulee: "Annulée",
  };

  const emitterAddressHtml = emitter.addressLines?.length
    ? emitter.addressLines
        .map((l) => `<p>${escapeHtml(l)}</p>`)
        .join("")
    : "";

  const lineRowsHtml = lineItems
    .map((li) => {
      const totalLineHt = li.quantity * li.unitPriceHtCents;
      return `<tr>
        <td>${escapeHtml(li.description)}</td>
        <td class="num">${formatQty(li.quantity)}</td>
        <td class="amount">${formatEurFromCents(li.unitPriceHtCents)}</td>
        <td class="amount">${formatEurFromCents(totalLineHt)}</td>
      </tr>`;
    })
    .join("");

  const vatLineHtml =
    vatRateBps != null
      ? `<tr>
          <td>TVA (${formatPercent(vatRateBps)})</td>
          <td class="amount">${formatEurFromCents(vatCents)}</td>
        </tr>`
      : `<tr>
          <td>TVA non applicable, art. 293 B du CGI</td>
          <td class="amount">—</td>
        </tr>`;

  const html = /* html */ `<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<title>Facture ${escapeHtml(inv.number)}</title>
<style>
  @page { size: A4; margin: 24mm 22mm; }
  * { box-sizing: border-box; }
  body {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    color: #141c25;
    background: #fff;
    margin: 0;
    padding: 40px 56px;
    line-height: 1.5;
  }
  h1, h2, h3 { font-family: 'Noto Serif', Georgia, serif; font-weight: 500; margin: 0; }
  .header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    border-bottom: 1px solid #c6c6cb;
    padding-bottom: 28px;
    margin-bottom: 40px;
  }
  .brand h1 { font-size: 32px; letter-spacing: -0.02em; }
  .brand p { font-size: 11px; text-transform: uppercase; letter-spacing: 0.1em; color: #45474b; margin-top: 4px; }
  .brand .address p { font-size: 12px; text-transform: none; letter-spacing: 0; color: #45474b; margin-top: 2px; }
  .meta { text-align: right; font-size: 13px; }
  .meta .num { font-family: 'Courier New', monospace; font-size: 16px; color: #141c25; font-weight: 700; }
  .meta .label { text-transform: uppercase; font-size: 10px; letter-spacing: 0.12em; color: #45474b; margin-top: 12px; }
  .meta .value { font-size: 13px; color: #141c25; }
  .status {
    display: inline-block;
    padding: 4px 10px;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin-top: 8px;
  }
  .status.payee { background: #fed488; color: #775a19; }
  .status.envoyee { background: #141c25; color: #fff; }
  .status.annulee { background: #c6c6cb; color: #45474b; }
  .status.brouillon { background: #e6effa; color: #45474b; }
  .grid { display: grid; grid-template-columns: 1fr 1fr; gap: 32px; margin-bottom: 40px; }
  .grid h3 { font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em; color: #45474b; margin-bottom: 8px; }
  .grid p { font-size: 14px; margin: 0; }
  .grid .name { font-family: 'Noto Serif', Georgia, serif; font-size: 18px; font-weight: 500; margin-bottom: 4px; }
  table { width: 100%; border-collapse: collapse; margin: 24px 0; }
  th, td { padding: 14px 12px; text-align: left; }
  th { font-size: 10px; text-transform: uppercase; letter-spacing: 0.12em; color: #45474b; border-bottom: 1px solid #c6c6cb; }
  td { font-size: 14px; border-bottom: 1px solid #e6effa; vertical-align: top; }
  td.amount, th.amount { text-align: right; font-family: 'Courier New', monospace; }
  td.num, th.num { text-align: right; font-family: 'Courier New', monospace; }
  .totals { margin-top: 24px; display: flex; justify-content: flex-end; }
  .totals table { width: auto; min-width: 320px; }
  .totals td { border: none; padding: 6px 12px; }
  .totals .total td { border-top: 2px solid #141c25; padding-top: 14px; font-weight: 700; }
  .totals .total td:last-child { font-family: 'Noto Serif', Georgia, serif; font-size: 22px; color: #775a19; }
  .footer {
    margin-top: 80px;
    padding-top: 24px;
    border-top: 1px solid #c6c6cb;
    font-size: 11px;
    color: #45474b;
    line-height: 1.7;
  }
  .footer strong { color: #141c25; }
  .print-btn {
    position: fixed;
    top: 16px;
    right: 16px;
    padding: 12px 20px;
    background: #141c25;
    color: #fff;
    text-transform: uppercase;
    font-family: 'Noto Serif', Georgia, serif;
    font-size: 11px;
    letter-spacing: 0.12em;
    cursor: pointer;
    border: none;
  }
  @media print {
    .print-btn { display: none; }
    body { padding: 0; }
  }
</style>
</head>
<body>
  <button class="print-btn" onclick="window.print()">Imprimer / PDF</button>

  <div class="header">
    <div class="brand">
      <h1>${escapeHtml(emitter.name)}</h1>
      ${emitter.tagline ? `<p>${escapeHtml(emitter.tagline)}</p>` : ""}
      <div class="address">${emitterAddressHtml}</div>
      ${emitter.email ? `<p class="address" style="margin-top:8px"><span style="font-size:12px;color:#45474b">${escapeHtml(emitter.email)}</span></p>` : ""}
      ${emitter.siret ? `<p style="font-family: monospace; font-size: 11px; margin-top: 6px; color:#45474b">SIRET ${escapeHtml(emitter.siret)}</p>` : ""}
    </div>
    <div class="meta">
      <div class="label">Facture</div>
      <div class="num">${escapeHtml(inv.number)}</div>
      <div class="label">Émise le</div>
      <div class="value">${issuedAt}</div>
      <div class="label">Échéance</div>
      <div class="value">${dueAt}</div>
      <span class="status ${inv.status}">${statusLabels[inv.status] ?? inv.status}</span>
    </div>
  </div>

  <div class="grid">
    <div>
      <h3>Émetteur</h3>
      <p class="name">${escapeHtml(emitter.name)}</p>
      ${emitter.email ? `<p>${escapeHtml(emitter.email)}</p>` : ""}
    </div>
    <div>
      <h3>Client</h3>
      <p class="name">${escapeHtml(clientInfo.name)}</p>
      ${clientInfo.company ? `<p>${escapeHtml(clientInfo.company)}</p>` : ""}
      ${clientInfo.addressStreet ? `<p>${escapeHtml(clientInfo.addressStreet)}</p>` : ""}
      ${
        clientInfo.addressZip || clientInfo.addressCity
          ? `<p>${escapeHtml(clientInfo.addressZip ?? "")} ${escapeHtml(clientInfo.addressCity ?? "")}</p>`
          : ""
      }
      ${clientInfo.addressCountry && clientInfo.addressCountry !== "France" && clientInfo.addressCountry !== "FR" ? `<p>${escapeHtml(clientInfo.addressCountry)}</p>` : ""}
      ${clientInfo.email ? `<p>${escapeHtml(clientInfo.email)}</p>` : ""}
      ${clientInfo.siret ? `<p style="font-family: monospace; font-size: 11px; margin-top: 8px;">SIRET ${escapeHtml(clientInfo.siret)}</p>` : ""}
    </div>
  </div>

  <table>
    <thead>
      <tr>
        <th>Désignation</th>
        <th class="num">Quantité</th>
        <th class="amount">Prix unitaire HT</th>
        <th class="amount">Total HT</th>
      </tr>
    </thead>
    <tbody>
      ${lineRowsHtml}
      ${
        dossier
          ? `<tr><td colspan="4" style="font-size:11px;color:#45474b;font-family:monospace">Dossier lié : ${escapeHtml(dossier.reference)}</td></tr>`
          : ""
      }
    </tbody>
  </table>

  <div class="totals">
    <table>
      <tr>
        <td>Sous-total HT</td>
        <td class="amount">${formatEurFromCents(htCents)}</td>
      </tr>
      ${vatLineHtml}
      <tr class="total">
        <td>Total TTC</td>
        <td class="amount">${formatEurFromCents(ttcCents)}</td>
      </tr>
    </table>
  </div>

  <div class="footer">
    <p><strong>Coordonnées de paiement :</strong> communiquées par email. Pour toute question, contactez <strong>${escapeHtml(emitter.email ?? "contact@socialex.pro")}</strong>.</p>
    <p>Conformément à l'article L441-10 du Code de commerce, en cas de retard de paiement, des pénalités égales au taux directeur de la BCE majoré de 10 points seront appliquées, ainsi qu'une indemnité forfaitaire de 40 € pour frais de recouvrement.</p>
  </div>

  <script>
    // Auto-déclenche la boîte de dialogue d'impression à l'ouverture si query ?print=1
    if (new URLSearchParams(location.search).get("print") === "1") {
      setTimeout(() => window.print(), 200);
    }
  </script>
</body>
</html>`;

  return new NextResponse(html, {
    status: 200,
    headers: {
      "Content-Type": "text/html; charset=utf-8",
      "Cache-Control": "private, no-store",
    },
  });
}

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

function formatQty(q: number): string {
  // Affiche les quantités entières sans décimales.
  return Number.isInteger(q) ? String(q) : q.toFixed(2).replace(".", ",");
}

function formatPercent(bps: number): string {
  const pct = bps / 100;
  return Number.isInteger(pct) ? `${pct} %` : `${pct.toFixed(2).replace(".", ",")} %`;
}
