import * as XLSX from 'xlsx';
import { ResultadoConciliacion } from './resultado.builder';

interface SesionInfo {
  nombre_cuenta: string;
  banco?: string | null;
  moneda: string;
  periodo_desde: string;
  periodo_hasta: string;
  porcentaje_conciliado?: number;
}

/**
 * Genera un .xlsx real (multi-hoja) del resultado de conciliación:
 * Resumen / Conciliadas / Pendientes (mis registros) / Pendientes (banco) / En tránsito.
 * Usa la lib `xlsx` (ya instalada). Puro: recibe datos, devuelve Buffer.
 */
export function generarExcelResultado(sesion: SesionInfo, resultado: ResultadoConciliacion): Buffer {
  const wb = XLSX.utils.book_new();
  const r = resultado.resumen;

  const resumen = [
    ['Conciliación Bancaria con IA'],
    ['Cuenta', sesion.nombre_cuenta],
    ['Banco', sesion.banco || ''],
    ['Moneda', sesion.moneda],
    ['Período', `${sesion.periodo_desde} a ${sesion.periodo_hasta}`],
    [],
    ['% Conciliado', r.porcentaje_conciliado],
    ['Conciliadas', r.conciliadas],
    ['Pendientes (mis registros)', r.pendientes_propio],
    ['Pendientes (banco)', r.pendientes_banco],
    ['Con diferencia', r.con_diferencia],
    ['En tránsito', r.en_transito],
    ['Total mis registros', r.total_propio],
    ['Total banco', r.total_banco],
  ];
  agregarHoja(wb, 'Resumen', resumen);

  const conciliadas = [
    ['Fecha', 'Concepto', 'Tipo', 'Referencia', 'Importe propio', 'Importe banco', 'Diferencia'],
    ...resultado.conciliadas.map((c) => [
      c.propio?.fecha ?? '',
      c.propio?.concepto ?? '',
      c.propio?.tipo ?? '',
      c.propio?.referencia ?? '',
      num(c.propio?.importe),
      num(c.banco?.importe),
      num(c.diferencia_importe),
    ]),
  ];
  agregarHoja(wb, 'Conciliadas', conciliadas);

  agregarHoja(wb, 'Pendientes (mis registros)', filasPendientes(resultado.pendientesPropio));
  agregarHoja(wb, 'Pendientes (banco)', filasPendientes(resultado.pendientesBanco));
  agregarHoja(wb, 'En tránsito', filasPendientes(resultado.enTransito));

  return XLSX.write(wb, { type: 'buffer', bookType: 'xlsx' }) as Buffer;
}

function filasPendientes(movs: Array<{ fecha: string; concepto: string; tipo: string; referencia: string | null; importe: number }>) {
  return [
    ['Fecha', 'Concepto', 'Tipo', 'Referencia', 'Importe'],
    ...movs.map((p) => [p.fecha, p.concepto, p.tipo, p.referencia ?? '', num(p.importe)]),
  ];
}

function agregarHoja(wb: XLSX.WorkBook, nombre: string, aoa: unknown[][]) {
  const ws = XLSX.utils.aoa_to_sheet(aoa);
  // Nombre de hoja: máx 31 chars, sin caracteres inválidos.
  XLSX.utils.book_append_sheet(wb, ws, nombre.replace(/[\\/?*[\]:]/g, ' ').slice(0, 31));
}

function num(v: unknown): number {
  return Number(v || 0);
}
