// EL ENRUTADOR DEL QR.
//
// Regla de Gilberto (2026-07-28): "que el QR choque contra un enrutador y envie
// a donde vaya, nunca choque directo con lo que solicita". Esto es ese
// enrutador.
//
// El QR impreso lleva SOLO un token opaco. Aca se resuelve por dentro: se
// consulta la base por la puerta de servicio y se devuelve lo justo para
// comprobar que la factura es real. Nunca el detalle de lo que consumio el
// cliente (000102 art. 25: confidencialidad).
//
// Por que importa que sea asi y no un enlace directo: un QR impreso en papel NO
// se puede cambiar nunca. Si apuntara directo a un archivo o a un proveedor,
// quedariamos amarrados a esa direccion para siempre. Con enrutador, se cambia
// lo que sea por detras y los papeles viejos siguen sirviendo.

interface Entorno {
  SUPABASE_URL: string;
  SUPABASE_SERVICE_KEY: string;
}

interface Factura {
  valido: boolean;
  rif_emisor: string | null;
  razon_social: string | null;
  tipo: string | null;
  numero_documento: number | null;
  numero_control: number | null;
  fecha_emision: string | null;
  total_bs: number | null;
}

const TIPO: Record<string, string> = {
  factura: 'Factura',
  nota_credito: 'Nota de crédito',
  nota_debito: 'Nota de débito',
};

function escapar(s: string): string {
  return s.replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[c] as string);
}

function pagina(cuerpo: string, estado = 200): Response {
  const html = `<!doctype html><html lang="es"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="robots" content="noindex,nofollow">
<title>Comprobación de documento</title>
<style>
:root{color-scheme:light dark}
body{margin:0;font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;background:#0D0F1E;color:#fff;
display:flex;min-height:100vh;align-items:center;justify-content:center;padding:24px}
.caja{width:100%;max-width:420px;background:#161A33;border-radius:20px;padding:24px;box-shadow:0 10px 40px rgba(0,0,0,.35)}
.ok{color:#4ADE80}.mal{color:#F87171}
h1{font-size:19px;margin:0 0 4px}
p.sub{margin:0 0 18px;color:#9aa0b5;font-size:14px}
dl{margin:0;display:grid;grid-template-columns:auto 1fr;gap:8px 14px;font-size:15px}
dt{color:#9aa0b5}dd{margin:0;text-align:right;font-weight:600}
.total{font-size:22px;font-weight:800}
.pie{margin-top:18px;padding-top:14px;border-top:1px solid rgba(255,255,255,.12);color:#9aa0b5;font-size:12px;line-height:1.5}
</style></head><body><div class="caja">${cuerpo}</div></body></html>`;
  return new Response(html, {
    status: estado,
    headers: {
      'content-type': 'text/html; charset=utf-8',
      'cache-control': 'no-store',
      'x-content-type-options': 'nosniff',
      'referrer-policy': 'no-referrer',
    },
  });
}

export const onRequestGet: PagesFunction<Entorno> = async (ctx) => {
  const token = String(ctx.params.token ?? '');

  // Filtro barato antes de tocar la base: el token real es hexadecimal de 32
  // (se aceptan tambien los de 48 de las primeras pruebas). Asi quien ande
  // probando direcciones al azar ni siquiera nos hace consultar.
  if (!/^[0-9a-f]{32}$|^[0-9a-f]{48}$/.test(token)) {
    return pagina(
      `<h1 class="mal">No pudimos comprobar este documento</h1>
       <p class="sub">El código no tiene el formato de un documento válido. Revisa que hayas escaneado bien.</p>`,
      404,
    );
  }

  const desde = ctx.request.headers.get('cf-connecting-ip') ?? null;
  const r = await fetch(`${ctx.env.SUPABASE_URL}/rest/v1/rpc/fn_validar_factura`, {
    method: 'POST',
    headers: {
      apikey: ctx.env.SUPABASE_SERVICE_KEY,
      Authorization: `Bearer ${ctx.env.SUPABASE_SERVICE_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ p_token: token, p_desde: desde }),
  });

  if (!r.ok) {
    return pagina(
      `<h1 class="mal">No pudimos comprobarlo ahora</h1>
       <p class="sub">Vuelve a intentarlo en un momento, por favor.</p>`,
      503,
    );
  }

  const filas = (await r.json()) as Factura[];
  const f = filas?.[0];

  if (!f?.valido) {
    return pagina(
      `<h1 class="mal">Este documento no aparece</h1>
       <p class="sub">No encontramos ningún documento con ese código. Si lo escaneaste de un papel, pídele ayuda al negocio que te atendió.</p>`,
      404,
    );
  }

  const fecha = f.fecha_emision
    ? new Date(f.fecha_emision).toLocaleString('es-VE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', hour12: true })
    : '';
  const monto = Number(f.total_bs ?? 0).toLocaleString('es-VE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });

  return pagina(`
    <h1 class="ok">Documento comprobado</h1>
    <p class="sub">Este documento fue emitido y numerado por nuestra imprenta digital.</p>
    <dl>
      <dt>Emitido por</dt><dd>${escapar(f.razon_social ?? '')}</dd>
      <dt>RIF</dt><dd>${escapar(f.rif_emisor ?? '')}</dd>
      <dt>Tipo</dt><dd>${escapar(TIPO[f.tipo ?? ''] ?? f.tipo ?? '')}</dd>
      <dt>Número</dt><dd>${f.numero_documento ?? ''}</dd>
      <dt>Número de control</dt><dd>${f.numero_control ?? ''}</dd>
      <dt>Fecha</dt><dd>${escapar(fecha)}</dd>
      <dt>Total</dt><dd class="total">Bs ${escapar(monto)}</dd>
    </dl>
    <p class="pie">Por resguardo de tus datos, aquí no se muestra el detalle de lo consumido.
    Si necesitas el documento completo, pídeselo al negocio que te lo emitió.</p>
  `);
};
