import { Icon } from "@iconify/react/dist/iconify.js";
import {
    Box,
    Button,
    Dialog,
    DialogActions,
    DialogContent,
    DialogTitle,
    Divider,
    Paper,
    TextField,
    Typography,
} from "@mui/material";
import { useEffect, useState } from "react";
import { getSesionActiva } from "../../../../api/tesoreria.service";

// Denominaciones de billetes y monedas en PYG
const DENOMINACIONES_PYG = [
  { valor: 100000, label: "100.000" },
  { valor: 50000, label: "50.000" },
  { valor: 20000, label: "20.000" },
  { valor: 10000, label: "10.000" },
  { valor: 5000, label: "5.000" },
  { valor: 2000, label: "2.000" },
  { valor: 1000, label: "1.000" },
  { valor: 500, label: "500" },
  { valor: 100, label: "100" },
  { valor: 50, label: "50" },
];

// El monto contado se escribía con `replace(/\D/g, "")`, que borra el separador
// decimal: no se podía tipear una fracción y, peor, "2.492.687,3" quedaba como
// 24926873 — diez veces más, sin aviso. Los acumulados de caja sí traen
// decimales (el modo estación calcula litros x precio), así que el arqueo tiene
// que poder expresarlos para llegar a cuadrar.
export function parseMonto(texto) {
  if (texto === null || texto === undefined || texto === "") return 0;
  // Se admite coma o punto como separador decimal; el resto se descarta.
  const limpio = String(texto)
    .replace(/[^\d,.]/g, "")
    .replace(/\.(?=.*[.,])/g, "")
    .replace(",", ".");
  const n = Number(limpio);
  return Number.isFinite(n) ? n : 0;
}

// Formatea para mostrar conservando los decimales que el usuario escribió.
function formatMonto(texto) {
  if (texto === null || texto === undefined || texto === "") return "";
  const str = String(texto);
  const [entera, decimal] = str.replace(",", ".").split(".");
  const enteraFmt = (Number(entera.replace(/\D/g, "")) || 0).toLocaleString("es-PY");
  // Mientras se tipea, un separador sin dígitos todavía no debe desaparecer.
  if (decimal === undefined) return str.match(/[.,]$/) ? `${enteraFmt},` : enteraFmt;
  return `${enteraFmt},${decimal}`;
}

export function CerrarCajaDialog({
  open,
  onClose,
  sesionCaja,
  cajaDescripcion,
  mediosPago = [],
  montoCierre,
  setMontoCierre,
  observacionesCierre,
  setObservacionesCierre,
  onCerrarCaja,
  isLoading,
  requiereArqueo = false,
}) {
  // Estado del arqueo por denominación
  const [arqueo, setArqueo] = useState(() =>
    DENOMINACIONES_PYG.map((d) => ({ ...d, cantidad: 0 })),
  );

  // Reset arqueo cuando se abre el diálogo
  useEffect(() => {
    if (open) {
      setArqueo(DENOMINACIONES_PYG.map((d) => ({ ...d, cantidad: 0 })));
    }
  }, [open]);

  // Calcular total arqueo efectivo
  const totalArqueoEfectivo = arqueo.reduce(
    (sum, d) => sum + d.valor * d.cantidad,
    0,
  );

  // Actualizar monto cierre cuando cambia el arqueo (si requiere arqueo)
  useEffect(() => {
    if (requiereArqueo) {
      setMontoCierre(String(totalArqueoEfectivo));
    }
  }, [totalArqueoEfectivo, requiereArqueo, setMontoCierre]);

  const handleCantidadChange = (index, value) => {
    const cantidad = parseInt(value) || 0;
    setArqueo((prev) =>
      prev.map((d, i) => (i === index ? { ...d, cantidad } : d)),
    );
  };

  // Construir arqueo_detalle para el backend
  const buildArqueoDetalle = () => {
    return arqueo
      .filter((d) => d.cantidad > 0)
      .map((d) => ({
        tipo: "efectivo",
        denominacion: d.valor,
        cantidad: d.cantidad,
        subtotal: d.valor * d.cantidad,
      }));
  };

  const handleCerrar = () => {
    if (requiereArqueo) {
      const detalle = buildArqueoDetalle();
      onCerrarCaja(null, detalle);
    } else {
      onCerrarCaja();
    }
  };

  // La sesión que traen los POS se carga una sola vez al montar la pantalla y no
  // se refresca con cada venta, así que al llegar al arqueo sus acumulados ya
  // estaban viejos: la pantalla mostraba un saldo esperado menor al real y el
  // backend rechazaba el cierre por una diferencia que el cajero no veía.
  // Se vuelve a pedir al abrir el diálogo para arquear contra datos frescos.
  const [sesionFresca, setSesionFresca] = useState(null);
  useEffect(() => {
    if (!open || !sesionCaja?.id) {
      setSesionFresca(null);
      return;
    }
    let cancelado = false;
    getSesionActiva()
      .then((s) => {
        // Sólo si sigue siendo la misma sesión: si se cerró desde otro lado, se
        // conserva lo que ya había en pantalla en vez de mezclar datos.
        if (!cancelado && s?.id === sesionCaja.id) setSesionFresca(s);
      })
      .catch(() => {});
    return () => {
      cancelado = true;
    };
  }, [open, sesionCaja?.id]);

  const sesion = sesionFresca || sesionCaja;

  // Calcular saldo esperado en efectivo
  const saldoEsperado =
    (sesion?.monto_apertura || 0) +
    (sesion?.monto_ventas_efectivo || 0) +
    (sesion?.monto_entradas_manual || 0) -
    (sesion?.monto_salidas_manual || 0);

  // Calcular diferencia
  const montoContado = requiereArqueo
    ? totalArqueoEfectivo
    : parseMonto(montoCierre);
  const diferencia = montoContado - saldoEsperado;

  // Iconos para medios de pago
  const iconMap = {
    1: "mdi:cash",
    2: "mdi:credit-card",
    3: "mdi:bank-transfer",
    4: "mdi:qrcode",
    5: "mdi:cellphone",
  };

  // Mapear código de medio de pago a campo de sesión
  const getMontoMedioPago = (codigo) => {
    const montoMap = {
      1: sesion?.monto_ventas_efectivo || 0,
      2: sesion?.monto_ventas_tarjeta || 0,
      3: sesion?.monto_ventas_transferencia || 0,
    };
    return montoMap[codigo] || 0;
  };

  // Total ventas
  const totalVentas =
    (sesion?.monto_ventas_efectivo || 0) +
    (sesion?.monto_ventas_tarjeta || 0) +
    (sesion?.monto_ventas_transferencia || 0);

  return (
    <Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
      <DialogTitle>
        <Box display="flex" alignItems="center" gap={1}>
          <Icon icon="mdi:cash-lock" />
          Cerrar Caja - Arqueo
        </Box>
      </DialogTitle>
      <DialogContent>
        <Box sx={{ display: "flex", flexDirection: "column", gap: 2, mt: 1 }}>
          {/* Resumen de la sesión */}
          {sesion && (
            <Paper sx={{ p: 2, bgcolor: "background.default" }}>
              <Typography
                variant="subtitle2"
                color="text.secondary"
                gutterBottom
              >
                Resumen de Sesión
              </Typography>
              <Box
                sx={{
                  display: "flex",
                  justifyContent: "space-between",
                  mb: 1,
                }}
              >
                <Typography variant="body2">Caja:</Typography>
                <Typography variant="body2" fontWeight={600}>
                  {cajaDescripcion || "N/A"}
                </Typography>
              </Box>
              <Box
                sx={{
                  display: "flex",
                  justifyContent: "space-between",
                  mb: 1,
                }}
              >
                <Typography variant="body2">Apertura:</Typography>
                <Typography variant="body2" fontWeight={600}>
                  Gs. {(sesion.monto_apertura || 0).toLocaleString("es-PY")}
                </Typography>
              </Box>

              <Divider sx={{ my: 1 }} />
              <Typography
                variant="subtitle2"
                color="text.secondary"
                sx={{ mb: 1 }}
              >
                Ventas por Medio de Pago
              </Typography>
              {mediosPago.map((medio) => {
                const monto = getMontoMedioPago(medio.codigo);
                const esEfectivo = medio.codigo === 1;

                return (
                  <Box
                    key={medio.id}
                    sx={{
                      display: "flex",
                      justifyContent: "space-between",
                      mb: 0.5,
                    }}
                  >
                    <Typography variant="body2">
                      <Icon
                        icon={iconMap[medio.codigo] || "mdi:currency-usd"}
                        style={{ marginRight: 4, verticalAlign: "middle" }}
                      />
                      {medio.descripcion}:
                    </Typography>
                    <Typography
                      variant="body2"
                      fontWeight={600}
                      color={esEfectivo ? "success.main" : "info.main"}
                    >
                      Gs. {monto.toLocaleString("es-PY")}
                    </Typography>
                  </Box>
                );
              })}
              <Box
                sx={{
                  display: "flex",
                  justifyContent: "space-between",
                  mb: 1,
                  mt: 1,
                  pt: 1,
                  borderTop: "1px dashed",
                  borderColor: "divider",
                }}
              >
                <Typography variant="body2" fontWeight={600}>
                  Total Ventas:
                </Typography>
                <Typography
                  variant="body2"
                  fontWeight={700}
                  color="success.main"
                >
                  Gs. {totalVentas.toLocaleString("es-PY")}
                </Typography>
              </Box>

              {/* Fase 2: Resumen por moneda */}
              {sesion.resumen_monedas &&
                Object.keys(sesion.resumen_monedas).length > 0 && (
                  <>
                    <Divider sx={{ my: 1 }} />
                    <Typography
                      variant="subtitle2"
                      color="text.secondary"
                      sx={{ mb: 1 }}
                    >
                      <Icon
                        icon="mdi:currency-usd"
                        style={{ marginRight: 4, verticalAlign: "middle" }}
                      />
                      Ventas en Otras Monedas
                    </Typography>
                    {Object.entries(sesion.resumen_monedas).map(
                      ([codigo, data]) => (
                        <Box
                          key={codigo}
                          sx={{
                            display: "flex",
                            justifyContent: "space-between",
                            mb: 0.5,
                            pl: 1,
                          }}
                        >
                          <Typography variant="body2">
                            {codigo} ({data.cantidad_operaciones}{" "}
                            {data.cantidad_operaciones === 1 ? "op." : "ops."})
                          </Typography>
                          <Box textAlign="right">
                            <Typography
                              variant="body2"
                              fontWeight={600}
                              color="info.main"
                            >
                              {codigo}{" "}
                              {Number(data.total_original).toLocaleString(
                                "es-PY",
                                {
                                  minimumFractionDigits:
                                    codigo === "PYG" ? 0 : 2,
                                  maximumFractionDigits:
                                    codigo === "PYG" ? 0 : 2,
                                },
                              )}
                            </Typography>
                            <Typography
                              variant="caption"
                              color="text.secondary"
                            >
                              ≈ Gs.{" "}
                              {Number(data.total_convertido).toLocaleString(
                                "es-PY",
                              )}
                            </Typography>
                          </Box>
                        </Box>
                      ),
                    )}
                  </>
                )}

              <Divider sx={{ my: 1 }} />
              <Typography
                variant="subtitle2"
                color="text.secondary"
                sx={{ mb: 1 }}
              >
                Otros Movimientos
              </Typography>
              <Box
                sx={{
                  display: "flex",
                  justifyContent: "space-between",
                  mb: 0.5,
                }}
              >
                <Typography variant="body2">
                  <Icon
                    icon="mdi:arrow-down-circle"
                    style={{
                      marginRight: 4,
                      verticalAlign: "middle",
                      color: "#4caf50",
                    }}
                  />
                  Entradas Manuales:
                </Typography>
                <Typography
                  variant="body2"
                  fontWeight={600}
                  color="success.main"
                >
                  Gs.{" "}
                  {(sesion.monto_entradas_manual || 0).toLocaleString(
                    "es-PY",
                  )}
                </Typography>
              </Box>
              <Box
                sx={{
                  display: "flex",
                  justifyContent: "space-between",
                  mb: 1,
                }}
              >
                <Typography variant="body2">
                  <Icon
                    icon="mdi:arrow-up-circle"
                    style={{
                      marginRight: 4,
                      verticalAlign: "middle",
                      color: "#f44336",
                    }}
                  />
                  Salidas Manuales:
                </Typography>
                <Typography variant="body2" fontWeight={600} color="error.main">
                  -Gs.{" "}
                  {(sesion.monto_salidas_manual || 0).toLocaleString(
                    "es-PY",
                  )}
                </Typography>
              </Box>

              <Divider sx={{ my: 1 }} />
              <Box sx={{ display: "flex", justifyContent: "space-between" }}>
                <Typography variant="body1" fontWeight={700}>
                  Saldo Esperado en Efectivo:
                </Typography>
                <Typography
                  variant="body1"
                  fontWeight={700}
                  color="primary.main"
                >
                  Gs. {saldoEsperado.toLocaleString("es-PY")}
                </Typography>
              </Box>

              {/* Cobros bancarios por conciliar (no integran al efectivo) */}
              {((sesion?.monto_ventas_tarjeta || 0) +
                (sesion?.monto_ventas_transferencia || 0)) > 0 && (
                <Box
                  sx={{
                    mt: 1.5,
                    p: 1.25,
                    borderRadius: 1.5,
                    bgcolor: "info.light",
                    color: "info.contrastText",
                    border: "1px dashed",
                    borderColor: "info.main",
                  }}
                >
                  <Typography
                    variant="caption"
                    sx={{ display: "block", fontWeight: 700, mb: 0.5 }}
                  >
                    <Icon
                      icon="mdi:bank-outline"
                      style={{ marginRight: 4, verticalAlign: "middle" }}
                    />
                    Cobros bancarios por conciliar
                  </Typography>
                  {(sesion?.monto_ventas_tarjeta || 0) > 0 && (
                    <Box
                      sx={{ display: "flex", justifyContent: "space-between" }}
                    >
                      <Typography variant="body2">Tarjeta:</Typography>
                      <Typography variant="body2" fontWeight={600}>
                        Gs.{" "}
                        {(sesion.monto_ventas_tarjeta || 0).toLocaleString(
                          "es-PY",
                        )}
                      </Typography>
                    </Box>
                  )}
                  {(sesion?.monto_ventas_transferencia || 0) > 0 && (
                    <Box
                      sx={{ display: "flex", justifyContent: "space-between" }}
                    >
                      <Typography variant="body2">Transferencia:</Typography>
                      <Typography variant="body2" fontWeight={600}>
                        Gs.{" "}
                        {(
                          sesion.monto_ventas_transferencia || 0
                        ).toLocaleString("es-PY")}
                      </Typography>
                    </Box>
                  )}
                  <Divider sx={{ my: 0.5 }} />
                  <Box
                    sx={{ display: "flex", justifyContent: "space-between" }}
                  >
                    <Typography variant="body2" fontWeight={700}>
                      Total bancario:
                    </Typography>
                    <Typography variant="body2" fontWeight={700}>
                      Gs.{" "}
                      {(
                        (sesion.monto_ventas_tarjeta || 0) +
                        (sesion.monto_ventas_transferencia || 0)
                      ).toLocaleString("es-PY")}
                    </Typography>
                  </Box>
                  <Typography
                    variant="caption"
                    sx={{ display: "block", mt: 0.5, opacity: 0.85 }}
                  >
                    No suma al efectivo en caja. Se concilia contra extracto
                    bancario / liquidación de tarjeta.
                  </Typography>
                </Box>
              )}
            </Paper>
          )}

          {/* Sección de arqueo por denominación */}
          {requiereArqueo ? (
            <Paper sx={{ p: 2, bgcolor: "background.default" }}>
              <Typography
                variant="subtitle2"
                color="text.secondary"
                gutterBottom
                sx={{ display: "flex", alignItems: "center", gap: 1 }}
              >
                <Icon icon="mdi:calculator" />
                Arqueo de Efectivo por Denominación
              </Typography>
              <Box
                sx={{
                  display: "grid",
                  gridTemplateColumns: "1fr 80px 1fr",
                  gap: 0.5,
                  alignItems: "center",
                  mb: 1,
                }}
              >
                <Typography
                  variant="caption"
                  fontWeight={600}
                  color="text.secondary"
                >
                  Denominación
                </Typography>
                <Typography
                  variant="caption"
                  fontWeight={600}
                  color="text.secondary"
                  textAlign="center"
                >
                  Cantidad
                </Typography>
                <Typography
                  variant="caption"
                  fontWeight={600}
                  color="text.secondary"
                  textAlign="right"
                >
                  Subtotal
                </Typography>
              </Box>
              {arqueo.map((d, index) => (
                <Box
                  key={d.valor}
                  sx={{
                    display: "grid",
                    gridTemplateColumns: "1fr 80px 1fr",
                    gap: 0.5,
                    alignItems: "center",
                    py: 0.3,
                    "&:hover": { bgcolor: "action.hover", borderRadius: 1 },
                  }}
                >
                  <Typography variant="body2">Gs. {d.label}</Typography>
                  <TextField
                    size="small"
                    type="number"
                    value={d.cantidad || ""}
                    onChange={(e) =>
                      handleCantidadChange(index, e.target.value)
                    }
                    inputProps={{
                      min: 0,
                      style: { textAlign: "center", padding: "4px 8px" },
                    }}
                    sx={{ "& .MuiOutlinedInput-root": { height: 30 } }}
                  />
                  <Typography
                    variant="body2"
                    textAlign="right"
                    fontWeight={d.cantidad > 0 ? 600 : 400}
                  >
                    Gs. {(d.valor * d.cantidad).toLocaleString("es-PY")}
                  </Typography>
                </Box>
              ))}
              <Divider sx={{ my: 1 }} />
              <Box sx={{ display: "flex", justifyContent: "space-between" }}>
                <Typography variant="body1" fontWeight={700}>
                  Total Efectivo Contado:
                </Typography>
                <Typography
                  variant="body1"
                  fontWeight={700}
                  color="primary.main"
                >
                  Gs. {totalArqueoEfectivo.toLocaleString("es-PY")}
                </Typography>
              </Box>
            </Paper>
          ) : (
            <TextField
              label="Monto Contado en Efectivo *"
              value={formatMonto(montoCierre)}
              onChange={(e) => {
                // Se guarda el texto crudo (sin separadores de miles) para no
                // perder los decimales a medio escribir.
                const crudo = e.target.value
                  .replace(/\./g, "")
                  .replace(/[^\d,]/g, "");
                setMontoCierre(crudo);
              }}
              fullWidth
              InputProps={{
                startAdornment: (
                  <Typography sx={{ mr: 1, color: "text.secondary" }}>
                    Gs.
                  </Typography>
                ),
              }}
              helperText="Ingrese el monto físico contado en caja"
            />
          )}

          {/* Mostrar diferencia */}
          {(montoCierre || (requiereArqueo && totalArqueoEfectivo > 0)) &&
            sesion && (
              <Paper sx={{ p: 2, bgcolor: "background.default" }}>
                <Box sx={{ display: "flex", justifyContent: "space-between" }}>
                  <Typography variant="body1" fontWeight={600}>
                    Diferencia:
                  </Typography>
                  <Typography
                    variant="body1"
                    fontWeight={700}
                    color={
                      diferencia === 0
                        ? "success.main"
                        : diferencia > 0
                          ? "info.main"
                          : "error.main"
                    }
                  >
                    {diferencia === 0
                      ? "Sin diferencia"
                      : diferencia > 0
                        ? `+Gs. ${diferencia.toLocaleString("es-PY")} (Sobrante)`
                        : `-Gs. ${Math.abs(diferencia).toLocaleString("es-PY")} (Faltante)`}
                  </Typography>
                </Box>
              </Paper>
            )}

          <TextField
            label="Observaciones"
            value={observacionesCierre}
            onChange={(e) => setObservacionesCierre(e.target.value)}
            fullWidth
            multiline
            rows={2}
            placeholder="Notas sobre el cierre de caja..."
          />
        </Box>
      </DialogContent>
      <DialogActions sx={{ p: 2 }}>
        <Button onClick={onClose} disabled={isLoading}>
          Cancelar
        </Button>
        <Button
          variant="contained"
          color="error"
          onClick={handleCerrar}
          disabled={
            isLoading ||
            (!montoCierre && !requiereArqueo) ||
            (requiereArqueo && totalArqueoEfectivo === 0)
          }
          startIcon={
            isLoading ? (
              <Icon icon="mdi:loading" className="spin" />
            ) : (
              <Icon icon="mdi:lock" />
            )
          }
        >
          {isLoading ? "Cerrando..." : "Cerrar Caja"}
        </Button>
      </DialogActions>
    </Dialog>
  );
}
