import { montoEnLetras } from '../common/numero-letras';

/**
 * Boleto de compraventa desde plantilla (M115). La plantilla es HTML con variables
 * {{nombre}}; cada empresa puede reemplazar la de abajo en sus parámetros. El texto
 * por defecto es un MODELO: el contenido legal lo define la escribanía del cliente.
 *
 * Los valores se escapan; sólo {{cronograma}} y {{cotitulares}} se insertan como HTML
 * porque los arma este mismo archivo.
 */

export const VARIABLES_BOLETO = [
  'fecha',
  'operacion.numero',
  'empresa.razon_social',
  'empresa.ruc',
  'comprador.nombre',
  'comprador.documento',
  'cotitulares',
  'proyecto.nombre',
  'proyecto.direccion',
  'proyecto.ciudad',
  'unidad.codigo',
  'unidad.descripcion',
  'unidad.cta_catastral',
  'unidad.finca',
  'moneda',
  'precio',
  'precio_letras',
  'ajuste',
  'cronograma',
] as const;

export const PLANTILLA_BOLETO_DEFAULT = `
<h2 style="text-align:center">BOLETO DE COMPRAVENTA</h2>
<p style="text-align:right">Operación {{operacion.numero}}</p>
<p>En la ciudad de {{proyecto.ciudad}}, a {{fecha}}, entre <strong>{{empresa.razon_social}}</strong>, RUC {{empresa.ruc}},
en adelante LA VENDEDORA, y <strong>{{comprador.nombre}}</strong>, documento {{comprador.documento}}, en adelante
EL COMPRADOR{{cotitulares}}, convienen en celebrar el presente boleto de compraventa, sujeto a las siguientes cláusulas:</p>
<p><strong>PRIMERA — Objeto.</strong> LA VENDEDORA vende a EL COMPRADOR la unidad <strong>{{unidad.codigo}}</strong>
({{unidad.descripcion}}) del proyecto <strong>{{proyecto.nombre}}</strong>, ubicado en {{proyecto.direccion}},
cuenta corriente catastral {{unidad.cta_catastral}}, finca {{unidad.finca}}.</p>
<p><strong>SEGUNDA — Precio.</strong> El precio total y convenido es de <strong>{{moneda}} {{precio}}</strong>
({{precio_letras}}), que EL COMPRADOR abonará según el siguiente cronograma:</p>
{{cronograma}}
<p><strong>TERCERA — Ajuste.</strong> {{ajuste}}</p>
<p><strong>CUARTA — Mora.</strong> La falta de pago en término de las cuotas hará incurrir a EL COMPRADOR en mora de
pleno derecho, con los intereses que establezca la ley.</p>
<p><strong>QUINTA — Escritura.</strong> La escritura traslativa de dominio se otorgará ante la escribanía que designe LA VENDEDORA,
una vez cancelado el precio o en las condiciones que las partes acuerden.</p>
<p style="margin-top:48px">En prueba de conformidad se firman dos ejemplares de un mismo tenor y a un solo efecto.</p>
<table style="width:100%;margin-top:64px"><tr>
<td style="text-align:center;border-top:1px solid #000;width:45%">LA VENDEDORA</td><td></td>
<td style="text-align:center;border-top:1px solid #000;width:45%">EL COMPRADOR</td>
</tr></table>
`.trim();

const MESES = [
  'enero',
  'febrero',
  'marzo',
  'abril',
  'mayo',
  'junio',
  'julio',
  'agosto',
  'septiembre',
  'octubre',
  'noviembre',
  'diciembre',
];

export const fechaLarga = (iso: string) => {
  const [y, m, d] = iso.slice(0, 10).split('-').map(Number);
  return `${d} de ${MESES[m - 1]} de ${y}`;
};

export const escapar = (v: string | number | null | undefined) =>
  String(v ?? '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;');

export function fmtMonto(n: number, monedaCodigo: string) {
  const dec = monedaCodigo === 'PYG' ? 0 : 2;
  return new Intl.NumberFormat('es-PY', { minimumFractionDigits: dec, maximumFractionDigits: dec }).format(n);
}

export interface DatosBoleto {
  fecha: string; // AAAA-MM-DD
  operacion: { numero: string };
  empresa: { razon_social: string; ruc: string };
  comprador: { nombre: string; documento: string };
  cotitulares: Array<{ nombre: string; documento: string; rol: string; porcentaje: number }>;
  proyecto: { nombre: string; direccion: string; ciudad: string };
  unidad: { codigo: string; descripcion: string; cta_catastral: string; finca: string };
  moneda: string;
  precio: number;
  ajuste: 'NINGUNO' | 'IPC_BCP';
  cuotas: Array<{
    nro: number;
    descripcion: string;
    fecha_vencimiento: string | null;
    monto: number;
    hito?: string | null;
  }>;
}

export function renderBoleto(plantilla: string | null | undefined, d: DatosBoleto): string {
  const filas = d.cuotas
    .map(
      (c) =>
        `<tr><td>${c.nro}</td><td>${escapar(c.descripcion)}</td><td>${
          c.fecha_vencimiento
            ? escapar(fechaLarga(c.fecha_vencimiento))
            : escapar(c.hito ? `Al cumplirse: ${c.hito}` : 'Contra posesión')
        }</td><td style="text-align:right">${escapar(fmtMonto(c.monto, d.moneda))}</td></tr>`,
    )
    .join('');
  const cronograma = `<table border="1" cellspacing="0" cellpadding="4" style="width:100%;border-collapse:collapse;font-size:12px">
<thead><tr><th>N°</th><th>Concepto</th><th>Vencimiento</th><th>Monto (${escapar(d.moneda)})</th></tr></thead><tbody>${filas}</tbody></table>`;
  const cotitulares = d.cotitulares.length
    ? `, y ${d.cotitulares.map((c) => `<strong>${escapar(c.nombre)}</strong>, documento ${escapar(c.documento)} (${escapar(c.rol.toLowerCase())}, ${c.porcentaje} %)`).join(', ')}`
    : '';
  const ajuste =
    d.ajuste === 'IPC_BCP'
      ? 'Las cuotas expresadas en guaraníes se ajustarán al momento de cada pago según la variación del Índice de Precios al Consumidor publicado por el Banco Central del Paraguay entre el mes de firma del presente y el último índice publicado. El ajuste nunca reducirá el monto de la cuota pactada.'
      : 'El precio es fijo y no está sujeto a ajuste.';

  const valores: Record<string, string> = {
    fecha: escapar(fechaLarga(d.fecha)),
    'operacion.numero': escapar(d.operacion.numero),
    'empresa.razon_social': escapar(d.empresa.razon_social),
    'empresa.ruc': escapar(d.empresa.ruc),
    'comprador.nombre': escapar(d.comprador.nombre),
    'comprador.documento': escapar(d.comprador.documento),
    cotitulares,
    'proyecto.nombre': escapar(d.proyecto.nombre),
    'proyecto.direccion': escapar(d.proyecto.direccion || '—'),
    'proyecto.ciudad': escapar(d.proyecto.ciudad || '—'),
    'unidad.codigo': escapar(d.unidad.codigo),
    'unidad.descripcion': escapar(d.unidad.descripcion),
    'unidad.cta_catastral': escapar(d.unidad.cta_catastral || '—'),
    'unidad.finca': escapar(d.unidad.finca || '—'),
    moneda: escapar(d.moneda),
    precio: escapar(fmtMonto(d.precio, d.moneda)),
    precio_letras: escapar(montoEnLetras(d.precio, d.moneda)),
    ajuste: escapar(ajuste),
    cronograma,
  };
  return (plantilla?.trim() || PLANTILLA_BOLETO_DEFAULT).replace(
    /\{\{\s*([\w.]+)\s*\}\}/g,
    (_, k: string) => valores[k] ?? '',
  );
}
