/* eslint-disable react/prop-types */
import { Icon } from "@iconify/react";
import {
  Box,
  Button,
  Chip,
  CircularProgress,
  Collapse,
  LinearProgress,
  Paper,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  Tab,
  Tabs,
  Tooltip,
  Typography,
  useTheme,
} from "@mui/material";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { PDFPreviewDialog } from "../_standards";
import { fmtMoneda } from "../_standards/enums/monedas";
import { fmtFechaCalendario } from "../../utils/fecha";
import { generarConciliacionIaBlob } from "../../reportesPDF/generarConciliacionIaPdf";
import {
  registrarBanco as apiRegistrarBanco,
  marcarEnTransito as apiMarcarEnTransito,
  registrarDiferencia as apiRegistrarDiferencia,
  matchManual as apiMatchManual,
  resumenIa as apiResumenIa,
  sugerenciasMatch as apiSugerenciasMatch,
  descargarExcelResultado,
} from "../../api/conciliacion-bancaria-ia.service";

// Segundos → "Xh Ym" | "X min" para el chip de ahorro de tiempo.
const fmtDuracion = (seg) => {
  const min = Math.round((seg || 0) / 60);
  if (min < 60) return `${min} min`;
  const h = Math.floor(min / 60);
  const r = min % 60;
  return r ? `${h} h ${r} min` : `${h} h`;
};

const SEV_COLOR = { alta: "error", media: "warning", info: "info" };

const msgError = (e, fallback) => e?.response?.data?.message || e?.message || fallback;

// Mapea un resultado del backend al estado local del panel.
const toData = (r) => ({
  conciliadas: r.conciliadas.map((c) => ({ ...c })),
  pendientesPropio: r.pendientesPropio.map((p) => ({ ...p })),
  pendientesBanco: r.pendientesBanco.map((p) => ({ ...p })),
  enTransito: (r.enTransito || []).map((p) => ({ ...p })),
  totalPropio: r.resumen.total_propio,
  totalBanco: r.resumen.total_banco,
});

const TipoChip = ({ tipo }) => (
  <Chip
    size="small"
    label={tipo === "CREDITO" ? "Crédito" : "Débito"}
    color={tipo === "CREDITO" ? "success" : "default"}
    variant={tipo === "CREDITO" ? "filled" : "outlined"}
    sx={{ height: 20, fontSize: "0.65rem", fontWeight: 700 }}
  />
);

const Metric = ({ n, label, color, bg, border }) => (
  <Paper variant="outlined" sx={{ flex: 1, minWidth: 130, p: 2, borderRadius: 2, bgcolor: bg, borderColor: border }}>
    <Typography sx={{ fontSize: 28, fontWeight: 800, lineHeight: 1, color }}>{n}</Typography>
    <Typography variant="caption" sx={{ textTransform: "uppercase", letterSpacing: 0.6, fontWeight: 700, color: "text.secondary" }}>
      {label}
    </Typography>
  </Paper>
);

export const ResultadoPanel = ({ sesion, resultado }) => {
  const theme = useTheme();
  const [tab, setTab] = useState(0);
  const [pdfOpen, setPdfOpen] = useState(false);
  const moneda = sesion.moneda || "PYG";
  const m = (v) => fmtMoneda(v, moneda);
  const nombreArchivo = `conciliacion-${(sesion.nombre_cuenta || "cuenta").replace(/\W+/g, "-").toLowerCase()}.pdf`;

  // Estado local: reflejo del resultado persistido. Las acciones llaman al backend
  // y refrescan desde la respuesta (UI == estado guardado).
  const [data, setData] = useState(() => toData(resultado));
  const [busy, setBusy] = useState(false);

  // Análisis IA (resumen ejecutivo + hallazgos + asiento + ahorro) y sugerencias.
  const [analisis, setAnalisis] = useState(null);
  const [analisisLoading, setAnalisisLoading] = useState(true);
  const [sugerencias, setSugerencias] = useState([]);
  const [asientoOpen, setAsientoOpen] = useState(false);

  const refrescarAnalisis = async () => {
    setAnalisisLoading(true);
    try {
      const [a, s] = await Promise.all([apiResumenIa(sesion.id), apiSugerenciasMatch(sesion.id)]);
      setAnalisis(a);
      setSugerencias(s.sugerencias || []);
    } catch {
      // El análisis es complementario; si falla, el resto del panel sigue funcionando.
    } finally {
      setAnalisisLoading(false);
    }
  };

  useEffect(() => {
    refrescarAnalisis();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [sesion.id]);

  // Derivados (mismo criterio que el motor: % = líneas conciliadas / líneas totales)
  const conciliadasCount = data.conciliadas.length;
  const conDiferencia = data.conciliadas.filter((c) => Math.abs(c.diferencia_importe) > 0).length;
  const pendP = data.pendientesPropio.length;
  const pendB = data.pendientesBanco.length;
  const totalLineas = data.totalPropio + data.totalBanco;
  const porcentaje = totalLineas ? Math.round(((conciliadasCount * 2) / totalLineas) * 100) : 0;

  const resultadoActual = {
    resumen: {
      total_propio: data.totalPropio,
      total_banco: data.totalBanco,
      conciliadas: conciliadasCount,
      pendientes_propio: pendP,
      pendientes_banco: pendB,
      con_diferencia: conDiferencia,
      porcentaje_conciliado: porcentaje,
    },
    conciliadas: data.conciliadas,
    pendientesPropio: data.pendientesPropio,
    pendientesBanco: data.pendientesBanco,
  };

  // ── Acciones (persisten en el backend y recalculan el %) ────────────────────
  const correrAccion = async (fn, okMsg, errMsg) => {
    setBusy(true);
    try {
      const r = await fn();
      setData(toData(r));
      toast.success(okMsg);
      refrescarAnalisis();
    } catch (e) {
      toast.error(msgError(e, errMsg));
    } finally {
      setBusy(false);
    }
  };

  // Aceptar una sugerencia de match (IA/heurística).
  const aceptarSugerencia = (s) =>
    correrAccion(
      () => apiMatchManual(sesion.id, s.movimiento_propio_id, s.movimiento_banco_id),
      "Conciliado según la sugerencia",
      "No se pudo aplicar la sugerencia",
    );

  // Registrar un pendiente del banco (comisión, ITF, débito no registrado): se crea
  // en "mis registros" y queda conciliado.
  const registrarBanco = (line) =>
    correrAccion(() => apiRegistrarBanco(sesion.id, line.id), "Movimiento registrado y conciliado", "No se pudo registrar");

  // Marcar una partida propia como "en tránsito": sale del período, se vigila para el próximo extracto.
  const marcarEnTransito = (line) =>
    correrAccion(() => apiMarcarEnTransito(sesion.id, line.id), "Marcado como partida en tránsito", "No se pudo marcar en tránsito");

  // Registrar la diferencia de una conciliada (comisión incluida por el banco): queda sin diferencia.
  const registrarDiferencia = (conc) =>
    correrAccion(() => apiRegistrarDiferencia(sesion.id, conc.id), "Diferencia aceptada — conciliación sin diferencia", "No se pudo aceptar la diferencia");

  // Descarga el .xlsx real generado por el backend (refleja el estado persistido).
  const bajarExcel = async () => {
    try {
      await descargarExcelResultado(sesion.id, nombreArchivo.replace(/\.pdf$/, ".xlsx"));
    } catch (e) {
      toast.error(msgError(e, "No se pudo descargar el Excel"));
    }
  };

  const todoConciliado = pendP === 0 && pendB === 0 && conDiferencia === 0;

  return (
    <Box>
      {/* Barra de porcentaje */}
      <Paper variant="outlined" sx={{ p: 2.5, mb: 2.5, borderRadius: 3 }}>
        <Box sx={{ display: "flex", alignItems: "center", justifyContent: "space-between", mb: 1 }}>
          <Typography variant="subtitle1" fontWeight={700}>
            Resultado de la conciliación
          </Typography>
          <Chip
            icon={<Icon icon={todoConciliado ? "mdi:party-popper" : "mdi:check-decagram"} width={16} />}
            label={`${porcentaje}% conciliado`}
            color="success"
            sx={{ fontWeight: 700 }}
          />
        </Box>
        <LinearProgress
          variant="determinate"
          value={porcentaje}
          color="success"
          sx={{ height: 10, borderRadius: 5, bgcolor: theme.palette.action.hover }}
        />
      </Paper>

      {/* Resumen ejecutivo (IA): loading mientras se genera */}
      {analisisLoading && !analisis && (
        <Paper
          variant="outlined"
          sx={{ p: 2.5, mb: 2.5, borderRadius: 3, bgcolor: theme.palette.primary.main + "0A", borderColor: theme.palette.primary.main + "40" }}
        >
          <Box sx={{ display: "flex", alignItems: "center", gap: 1.25 }}>
            <CircularProgress size={18} />
            <Icon icon="mdi:brain" width={20} color={theme.palette.primary.main} />
            <Typography variant="subtitle1" fontWeight={700}>Generando resumen ejecutivo con IA…</Typography>
          </Box>
          <Typography variant="body2" color="text.secondary" sx={{ mt: 0.75 }}>
            La IA está analizando la conciliación (hallazgos, asiento sugerido y ahorro de tiempo). Puede tardar unos segundos.
          </Typography>
          <LinearProgress sx={{ mt: 1.5, borderRadius: 1 }} />
        </Paper>
      )}

      {/* Resumen ejecutivo (IA) + ahorro de tiempo */}
      {analisis && (
        <Paper
          variant="outlined"
          sx={{ p: 2.5, mb: 2.5, borderRadius: 3, bgcolor: theme.palette.primary.main + "0A", borderColor: theme.palette.primary.main + "40" }}
        >
          <Box sx={{ display: "flex", alignItems: "center", gap: 1, mb: 1, flexWrap: "wrap" }}>
            <Icon icon="mdi:brain" width={20} color={theme.palette.primary.main} />
            <Typography variant="subtitle1" fontWeight={700}>Resumen ejecutivo</Typography>
            <Chip
              size="small"
              variant="outlined"
              color={analisis.generado_por === "ia" ? "primary" : "default"}
              label={analisis.generado_por === "ia" ? "Generado con IA" : "Resumen automático"}
              sx={{ height: 22, fontSize: "0.62rem", fontWeight: 700 }}
            />
            {analisis.ahorro?.segundos_estimado_manual > 0 && (
              <Chip
                size="small"
                color="success"
                variant="outlined"
                icon={<Icon icon="mdi:clock-fast" width={14} />}
                label={`Ahorro ≈ ${fmtDuracion(analisis.ahorro.segundos_estimado_manual)} de trabajo manual`}
                sx={{ height: 22, fontSize: "0.62rem", fontWeight: 700, ml: "auto" }}
              />
            )}
          </Box>
          <Typography variant="body2" sx={{ color: "text.primary", lineHeight: 1.6 }}>
            {analisis.narrativa}
          </Typography>

          {/* Hallazgos */}
          {analisis.hallazgos?.length > 0 && (
            <Box sx={{ display: "flex", gap: 1, mt: 1.5, flexWrap: "wrap" }}>
              {analisis.hallazgos.map((h, i) => (
                <Paper
                  key={i}
                  variant="outlined"
                  sx={{ p: 1.25, borderRadius: 2, flex: "1 1 220px", minWidth: 220, borderLeft: `3px solid ${theme.palette[SEV_COLOR[h.severidad] || "info"].main}` }}
                >
                  <Box sx={{ display: "flex", alignItems: "center", gap: 0.75 }}>
                    <Icon
                      icon={h.severidad === "alta" ? "mdi:alert" : h.severidad === "media" ? "mdi:alert-outline" : "mdi:information-outline"}
                      width={16}
                      color={theme.palette[SEV_COLOR[h.severidad] || "info"].main}
                    />
                    <Typography variant="caption" fontWeight={700}>{h.titulo}</Typography>
                  </Box>
                  {h.monto > 0 && (
                    <Typography variant="subtitle2" fontWeight={800} sx={{ mt: 0.25 }}>{m(h.monto)}</Typography>
                  )}
                  <Typography variant="caption" color="text.secondary" display="block">{h.detalle}</Typography>
                </Paper>
              ))}
            </Box>
          )}

          {/* Asiento contable sugerido */}
          {analisis.asiento_sugerido?.length > 0 && (
            <Box sx={{ mt: 1.5 }}>
              <Button size="small" variant="text" startIcon={<Icon icon={asientoOpen ? "mdi:chevron-up" : "mdi:chevron-down"} />} onClick={() => setAsientoOpen((v) => !v)}>
                Asiento contable sugerido
              </Button>
              <Collapse in={asientoOpen}>
                <Table size="small" sx={{ mt: 1 }}>
                  <TableHead>
                    <TableRow>
                      <TableCell>Cuenta</TableCell>
                      <TableCell>Concepto</TableCell>
                      <TableCell align="right">Debe</TableCell>
                      <TableCell align="right">Haber</TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {analisis.asiento_sugerido.map((l, i) => (
                      <TableRow key={i}>
                        <TableCell>{l.cuenta_sugerida}</TableCell>
                        <TableCell>{l.concepto}</TableCell>
                        <TableCell align="right">{l.debe ? m(l.debe) : ""}</TableCell>
                        <TableCell align="right">{l.haber ? m(l.haber) : ""}</TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
                <Typography variant="caption" color="text.secondary" sx={{ display: "block", mt: 0.5 }}>
                  Propuesta a partir de los cargos del banco. Para registrarlo en Contabilidad, confirmá las cuentas del plan.
                </Typography>
              </Collapse>
            </Box>
          )}
        </Paper>
      )}

      {/* Sugerencias de conciliación (los que "casi cruzan") */}
      {sugerencias.length > 0 && (
        <Paper variant="outlined" sx={{ p: 2, mb: 2.5, borderRadius: 3, borderColor: theme.palette.info.main + "55" }}>
          <Box sx={{ display: "flex", alignItems: "center", gap: 1, mb: 1 }}>
            <Icon icon="mdi:lightbulb-on-outline" width={18} color={theme.palette.info.main} />
            <Typography variant="subtitle2" fontWeight={700}>
              Sugerencias de conciliación ({sugerencias.length})
            </Typography>
          </Box>
          {sugerencias.map((s, i) => (
            <Box
              key={i}
              sx={{ display: "flex", alignItems: "center", gap: 1.5, py: 1, flexWrap: "wrap", borderTop: i ? `1px solid ${theme.palette.divider}` : "none" }}
            >
              <Box sx={{ flex: "1 1 260px", minWidth: 240 }}>
                <Typography variant="body2" fontWeight={600}>
                  {s.propio?.concepto} <span style={{ opacity: 0.6 }}>↔</span> {s.banco?.concepto}
                </Typography>
                <Typography variant="caption" color="text.secondary">
                  {m(s.propio?.importe)} vs {m(s.banco?.importe)} · {s.motivo}
                </Typography>
              </Box>
              <Chip size="small" variant="outlined" label={`${Math.round((s.confianza || 0) * 100)}% probable`} sx={{ height: 22, fontSize: "0.62rem" }} />
              <Button size="small" variant="outlined" color="info" disabled={busy} startIcon={<Icon icon="mdi:link-variant" width={16} />} onClick={() => aceptarSugerencia(s)}>
                Conciliar
              </Button>
            </Box>
          ))}
        </Paper>
      )}

      {/* Tarjetas */}
      <Box sx={{ display: "flex", gap: 1.5, mb: 2.5, flexWrap: "wrap" }}>
        <Metric n={conciliadasCount} label="Conciliadas" color={theme.palette.success.main} bg={theme.palette.success.main + "12"} border={theme.palette.success.main + "55"} />
        <Metric n={pendP} label="Pend. mis registros" color={theme.palette.warning.main} />
        <Metric n={pendB} label="Pend. banco" color={theme.palette.warning.main} />
        <Metric n={conDiferencia} label="Con diferencia" color={theme.palette.info.main} />
        {data.enTransito.length > 0 && (
          <Metric n={data.enTransito.length} label="En tránsito" color={theme.palette.text.secondary} />
        )}
      </Box>

      {/* Acciones */}
      <Box sx={{ display: "flex", gap: 1.5, mb: 2.5, flexWrap: "wrap", alignItems: "center" }}>
        <Button variant="contained" color="error" startIcon={<Icon icon="mdi:file-pdf-box" />} onClick={() => setPdfOpen(true)}>
          Ver / Descargar PDF
        </Button>
        <Button variant="outlined" color="success" disabled={busy} startIcon={<Icon icon="mdi:file-excel-box" />} onClick={bajarExcel}>
          Descargar Excel
        </Button>
        {todoConciliado && (
          <Chip icon={<Icon icon="mdi:check-all" width={16} />} color="success" variant="outlined" label="Todo resuelto" sx={{ fontWeight: 700 }} />
        )}
      </Box>

      {/* Pestañas */}
      <Paper variant="outlined" sx={{ borderRadius: 3, overflow: "hidden" }}>
        <Tabs value={tab} onChange={(_, v) => setTab(v)} variant="scrollable" sx={{ borderBottom: 1, borderColor: "divider", px: 1 }}>
          <Tab label={`Conciliadas (${conciliadasCount})`} />
          <Tab label={`Pendientes · mis registros (${pendP})`} />
          <Tab label={`Pendientes · banco (${pendB})`} />
        </Tabs>

        <Box sx={{ overflowX: "auto" }}>
          {/* ── Conciliadas ── */}
          {tab === 0 && (
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>Fecha</TableCell>
                  <TableCell>Concepto</TableCell>
                  <TableCell>Tipo</TableCell>
                  <TableCell align="right">Importe propio</TableCell>
                  <TableCell align="right">Importe banco</TableCell>
                  <TableCell align="right">Diferencia</TableCell>
                  <TableCell align="center">Acción</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {data.conciliadas.map((c) => {
                  const dif = c.diferencia_importe;
                  const conDif = Math.abs(dif) > 0;
                  return (
                    <TableRow key={c.id} hover>
                      <TableCell>{fmtFechaCalendario(c.propio.fecha)}</TableCell>
                      <TableCell>{c.propio.concepto}</TableCell>
                      <TableCell><TipoChip tipo={c.propio.tipo} /></TableCell>
                      <TableCell align="right">{m(c.propio.importe)}</TableCell>
                      <TableCell align="right">{m(c.banco.importe)}</TableCell>
                      <TableCell align="right" sx={{ color: conDif ? "warning.main" : "success.main", fontWeight: 600 }}>
                        {m(dif)}
                      </TableCell>
                      <TableCell align="center">
                        {conDif ? (
                          <Tooltip title="El banco cobró un importe distinto (comisión incluida o error). Das por buena la diferencia y la conciliación queda sin diferencia pendiente.">
                            <Button size="small" variant="outlined" color="info" disabled={busy} startIcon={<Icon icon="mdi:bank-plus" width={16} />} onClick={() => registrarDiferencia(c)}>
                              Aceptar dif.
                            </Button>
                          </Tooltip>
                        ) : c.registrado ? (
                          <Chip size="small" color="success" variant="outlined" label="Registrado" sx={{ height: 22, fontSize: "0.62rem" }} />
                        ) : (
                          <Icon icon="mdi:check-circle" width={18} color={theme.palette.success.main} />
                        )}
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table>
          )}

          {/* ── Pendientes (mis registros / banco) ── */}
          {(tab === 1 || tab === 2) && (
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell>Fecha</TableCell>
                  <TableCell>Concepto</TableCell>
                  <TableCell>Tipo</TableCell>
                  <TableCell align="right">Importe</TableCell>
                  <TableCell>Motivo</TableCell>
                  <TableCell align="center">Acción</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {(tab === 1 ? data.pendientesPropio : data.pendientesBanco).map((p) => (
                  <TableRow key={p.id} hover>
                    <TableCell>{fmtFechaCalendario(p.fecha)}</TableCell>
                    <TableCell>{p.concepto}</TableCell>
                    <TableCell><TipoChip tipo={p.tipo} /></TableCell>
                    <TableCell align="right">{m(p.importe)}</TableCell>
                    <TableCell>
                      {p.confianza_ia < 0.5 ? (
                        <Chip size="small" color="warning" variant="outlined" label="Baja confianza IA" sx={{ height: 20, fontSize: "0.62rem" }} />
                      ) : (
                        <Chip size="small" variant="outlined" label="Sin correspondencia" sx={{ height: 20, fontSize: "0.62rem" }} />
                      )}
                    </TableCell>
                    <TableCell align="center">
                      {tab === 2 ? (
                        <Tooltip title="Cargo del banco que no tenías registrado (comisión, ITF, débito). Lo registra como movimiento tuyo y queda conciliado.">
                          <Button size="small" variant="outlined" color="success" disabled={busy} startIcon={<Icon icon="mdi:cash-register" width={16} />} onClick={() => registrarBanco(p)}>
                            Registrar
                          </Button>
                        </Tooltip>
                      ) : (
                        <Tooltip title="Partida tuya sin espejo en el banco (cheque no cobrado, depósito no acreditado). La apartás para cruzarla en el próximo extracto.">
                          <Button size="small" variant="outlined" disabled={busy} startIcon={<Icon icon="mdi:clock-outline" width={16} />} onClick={() => marcarEnTransito(p)}>
                            En tránsito
                          </Button>
                        </Tooltip>
                      )}
                    </TableCell>
                  </TableRow>
                ))}
                {(tab === 1 ? data.pendientesPropio : data.pendientesBanco).length === 0 && (
                  <TableRow>
                    <TableCell colSpan={6} align="center" sx={{ py: 3, color: "text.secondary" }}>
                      <Icon icon="mdi:check-all" width={22} /> Sin pendientes en esta lista
                    </TableCell>
                  </TableRow>
                )}
              </TableBody>
            </Table>
          )}
        </Box>
      </Paper>

      <PDFPreviewDialog
        open={pdfOpen}
        onClose={() => setPdfOpen(false)}
        title={`Conciliación — ${sesion.nombre_cuenta || ""}`}
        fetchBlob={() => generarConciliacionIaBlob(sesion, resultadoActual)}
        downloadFilename={nombreArchivo}
      />
    </Box>
  );
};
