import { MovimientoNormalizado } from './tipos';

/**
 * Parser CSV multi-banco (Paraguay), portado de TesConciliacionService.parseCsv.
 * Puro, sin efectos secundarios. Detecta columnas de Continental/BNF/Itaú/
 * Sudameris/genérico y la variante de columna única con signo. Devuelve
 * movimientos normalizados con confianza_ia = 1 (dato estructurado exacto).
 */
export function parseCsvMovimientos(csv: string): MovimientoNormalizado[] {
  const rawLines = csv.split('\n').map((l) => l.trim()).filter(Boolean);
  if (rawLines.length < 2) return [];

  // Algunos bancos insertan filas de metadata antes del header real.
  let headerIdx = 0;
  for (let i = 0; i < Math.min(rawLines.length, 15); i++) {
    const lower = rawLines[i].toLowerCase();
    if (lower.includes('fecha') || lower.includes('día') || lower.includes('dia') || lower.includes('date')) {
      headerIdx = i;
      break;
    }
  }

  // El separador se toma de la fila de ENCABEZADO (no de la línea 0, que puede ser
  // metadata sin separador). ; o , o tab.
  const headerLine = rawLines[headerIdx];
  const sep = headerLine.includes(';') ? ';' : headerLine.includes('\t') ? '\t' : ',';

  const header = headerLine.split(sep).map((h) => h.trim().toLowerCase().replace(/"/g, ''));
  const idx = (names: string[]) => names.reduce((found, n) => (found >= 0 ? found : header.indexOf(n)), -1);

  const iFecha = idx(['fecha', 'dia', 'día', 'date', 'día hora', 'dia hora', 'dia/hora', 'fecha valor', 'fecha movimiento', 'fecha transaccion', 'f. operacion', 'fecha operacion', 'fecha op']);
  const iDesc = idx(['descripcion', 'descripción', 'description', 'concepto', 'detalle', 'movimiento', 'obs', 'observacion']);
  const iDebito = idx(['debito', 'débito', 'debit', 'cargo', 'salida', 'debe', 'egreso', 'egresos', 'monto débito', 'monto debito', 'débitos', 'debitos']);
  const iCredito = idx(['credito', 'crédito', 'credit', 'abono', 'entrada', 'haber', 'ingreso', 'ingresos', 'monto crédito', 'monto credito', 'créditos', 'creditos']);
  const iImporte = idx(['importe', 'monto', 'amount', 'valor']);
  const iRef = idx(['referencia', 'reference', 'nro', 'numero', 'número', 'comprobante', 'nro. comprobante', 'nro comprobante']);

  if (iFecha < 0) return [];

  const parseMonto = (v: string) => {
    if (!v) return 0;
    return Math.abs(parseFloat(v.replace(/\./g, '').replace(',', '.').replace(/\s/g, '')) || 0);
  };

  const result: MovimientoNormalizado[] = [];

  for (let i = headerIdx + 1; i < rawLines.length; i++) {
    const cols = rawLines[i].split(sep).map((c) => c.trim().replace(/"/g, ''));
    if (cols.length <= 1) continue;

    const rawFecha = cols[iFecha] || '';
    const fecha = parseFecha(rawFecha.split(' ')[0].split('T')[0]);
    if (!fecha) continue;

    let debito = 0;
    let credito = 0;

    if (iImporte >= 0 && iDebito < 0 && iCredito < 0) {
      // Columna importe único con signo (BNF, Itaú online, etc.)
      const raw = (cols[iImporte] || '').replace(/\./g, '').replace(',', '.').replace(/\s/g, '');
      const val = parseFloat(raw) || 0;
      if (val < 0) debito = Math.abs(val);
      else credito = val;
    } else {
      debito = iDebito >= 0 ? parseMonto(cols[iDebito]) : 0;
      credito = iCredito >= 0 ? parseMonto(cols[iCredito]) : 0;
    }

    if (debito === 0 && credito === 0) continue;

    const tipo = debito > 0 ? 'DEBITO' : 'CREDITO';
    const importe = debito > 0 ? debito : credito;

    result.push({
      fecha,
      concepto: (iDesc >= 0 && cols[iDesc]) || '(sin concepto)',
      tipo,
      importe,
      referencia: (iRef >= 0 && cols[iRef]) || null,
      confianza_ia: 1,
    });
  }

  return result;
}

/** DD/MM/YYYY | DD-MM-YYYY | YYYY-MM-DD → YYYY-MM-DD | null */
export function parseFecha(raw: string): string | null {
  if (!raw) return null;
  const dmy = raw.match(/^(\d{1,2})[/\-](\d{1,2})[/\-](\d{4})$/);
  if (dmy) return `${dmy[3]}-${dmy[2].padStart(2, '0')}-${dmy[1].padStart(2, '0')}`;
  if (/^\d{4}-\d{2}-\d{2}$/.test(raw)) return raw;
  return null;
}
