import { ResultadoConciliacion } from './resultado.builder';

export type Severidad = 'alta' | 'media' | 'info';

export interface Hallazgo {
  tipo: string;
  severidad: Severidad;
  titulo: string;
  detalle: string;
  monto: number;
  cantidad: number;
}

export interface LineaAsiento {
  cuenta_sugerida: string;
  concepto: string;
  debe: number;
  haber: number;
}

export interface AnalisisResultado {
  hallazgos: Hallazgo[];
  asientoSugerido: LineaAsiento[];
  ahorro: { movimientos: number; segundos_estimado_manual: number };
}

// Clasificación por palabras clave del concepto (bancos Paraguay).
function clasificar(concepto: string): 'COMISION' | 'ITF' | 'INTERES' | 'SEGURO' | 'OTRO' {
  const c = (concepto || '').toLowerCase();
  if (c.includes('comisi') || c.includes('gasto banc') || c.includes('mantenimiento')) return 'COMISION';
  if (c.includes('itf') || c.includes('impuesto')) return 'ITF';
  if (c.includes('inter')) return 'INTERES';
  if (c.includes('seguro')) return 'SEGURO';
  return 'OTRO';
}

const suma = (arr: Array<{ importe: number }>) => arr.reduce((t, x) => t + Number(x.importe || 0), 0);

/**
 * Deriva hallazgos accionables y un asiento contable sugerido a partir del
 * resultado. Determinista (sin IA) — alimenta el resumen ejecutivo, el panel de
 * hallazgos y la vista previa del asiento.
 */
export function analizarResultado(resultado: ResultadoConciliacion): AnalisisResultado {
  const hallazgos: Hallazgo[] = [];

  // 1) Conciliadas con diferencia (típicamente el banco cobró de más / comisión incluida).
  const conDif = resultado.conciliadas.filter((c) => Math.abs(c.diferencia_importe) > 0);
  const bancoCobroMas = conDif.filter((c) => c.diferencia_importe < 0);
  if (conDif.length) {
    const monto = conDif.reduce((t, c) => t + Math.abs(c.diferencia_importe), 0);
    hallazgos.push({
      tipo: 'DIFERENCIA',
      severidad: 'alta',
      titulo: bancoCobroMas.length
        ? `El banco cobró de más en ${bancoCobroMas.length} movimiento(s)`
        : `${conDif.length} conciliación(es) con diferencia`,
      detalle: 'Movimientos que cruzan pero con importe distinto (comisión incluida o error del banco).',
      monto,
      cantidad: conDif.length,
    });
  }

  // 2) Cargos del banco no registrados por la empresa (débitos pendientes del banco).
  const debitosBanco = resultado.pendientesBanco.filter((p) => p.tipo === 'DEBITO');
  if (debitosBanco.length) {
    hallazgos.push({
      tipo: 'CARGO_NO_REGISTRADO',
      severidad: 'alta',
      titulo: `${debitosBanco.length} cargo(s) del banco sin registrar`,
      detalle: 'Comisiones, ITF, débitos automáticos que el banco cobró y no tenías cargados.',
      monto: suma(debitosBanco),
      cantidad: debitosBanco.length,
    });
  }

  // 3) Acreditaciones del banco no registradas (intereses, transferencias no cargadas).
  const creditosBanco = resultado.pendientesBanco.filter((p) => p.tipo === 'CREDITO');
  if (creditosBanco.length) {
    hallazgos.push({
      tipo: 'ACREDITACION_NO_REGISTRADA',
      severidad: 'media',
      titulo: `${creditosBanco.length} acreditación(es) del banco sin registrar`,
      detalle: 'Intereses o ingresos que el banco acreditó y no tenías cargados.',
      monto: suma(creditosBanco),
      cantidad: creditosBanco.length,
    });
  }

  // 4) Partidas propias pendientes (cheques emitidos sin cobrar, depósitos no acreditados).
  if (resultado.pendientesPropio.length) {
    hallazgos.push({
      tipo: 'PARTIDA_PROPIA_PENDIENTE',
      severidad: 'media',
      titulo: `${resultado.pendientesPropio.length} partida(s) tuya(s) sin espejo en el banco`,
      detalle: 'Cheques emitidos no cobrados o depósitos no acreditados aún — candidatos a "en tránsito".',
      monto: suma(resultado.pendientesPropio),
      cantidad: resultado.pendientesPropio.length,
    });
  }

  // 5) Líneas de baja confianza IA (para revisar).
  const bajaConf = [...resultado.pendientesPropio, ...resultado.pendientesBanco].filter((p) => p.confianza_ia < 0.5);
  if (bajaConf.length) {
    hallazgos.push({
      tipo: 'BAJA_CONFIANZA',
      severidad: 'info',
      titulo: `${bajaConf.length} línea(s) de baja confianza`,
      detalle: 'La IA no está segura de la interpretación — conviene revisarlas manualmente.',
      monto: suma(bajaConf),
      cantidad: bajaConf.length,
    });
  }

  // ── Asiento contable sugerido (para los cargos/acreditaciones del banco) ──────
  const asientoSugerido: LineaAsiento[] = [];
  let totalDebe = 0;
  const cuentaPorTipo: Record<string, string> = {
    COMISION: 'Gastos bancarios / Comisiones',
    ITF: 'Impuestos - ITF',
    SEGURO: 'Gastos - Seguros',
    INTERES: 'Ingresos financieros',
    OTRO: 'Otros gastos bancarios',
  };
  for (const d of debitosBanco) {
    const clase = clasificar(d.concepto);
    asientoSugerido.push({ cuenta_sugerida: cuentaPorTipo[clase], concepto: d.concepto, debe: Number(d.importe), haber: 0 });
    totalDebe += Number(d.importe);
  }
  // Las diferencias donde el banco cobró de más también son gasto (comisión incluida).
  for (const c of bancoCobroMas) {
    const monto = Math.abs(c.diferencia_importe);
    asientoSugerido.push({ cuenta_sugerida: cuentaPorTipo.COMISION, concepto: `Diferencia en ${c.banco?.concepto ?? 'movimiento'}`, debe: monto, haber: 0 });
    totalDebe += monto;
  }
  if (totalDebe > 0) {
    asientoSugerido.push({ cuenta_sugerida: 'Banco', concepto: 'Ajuste por conciliación bancaria', debe: 0, haber: totalDebe });
  }

  const movimientos = resultado.resumen.total_propio + resultado.resumen.total_banco;
  return {
    hallazgos,
    asientoSugerido,
    // Estimación conservadora: ~40s por línea de conciliación manual (buscar, cruzar, anotar).
    ahorro: { movimientos, segundos_estimado_manual: movimientos * 40 },
  };
}
