import { Icon } from "@iconify/react";
import {
  Alert,
  Box,
  Button,
  Chip,
  Collapse,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  IconButton,
  InputAdornment,
  MenuItem,
  Paper,
  Select,
  Skeleton,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Tooltip,
  Typography,
} from "@mui/material";
import { useRef, useState } from "react";
import { toast } from "sonner";
import { useAnularReciboMultiMutation, useRecibosMultiQuery, useReciboMultiQuery } from "../../../tanstack/RecibosMultiStack";
import { usePermission } from "../../../hooks/usePermission";
import { NuevoReciboMultiWizard } from "./NuevoReciboMultiWizard";
import {
  EmptyState,
  ScreenGuia,
  fmtMoneda,
  getEstadoChip,
  TIPOS_MEDIO_PAGO,
  getTipoRetencionChip,
} from "../../_standards";
import { GUIA_RECIBOS_MULTI } from "./_guias";

// ─── Helpers ──────────────────────────────────────────────────────────────────
const fmtGs = (v) => fmtMoneda(v, "PYG");

const fmtFecha = (str) => {
  if (!str) return "—";
  try {
    return new Date(str).toLocaleDateString("es-PY", {
      day: "2-digit",
      month: "2-digit",
      year: "numeric",
    });
  } catch {
    return str;
  }
};

const getISODate = (offset = 0) => {
  const d = new Date();
  d.setDate(d.getDate() + offset);
  // Date local en YYYY-MM-DD (no UTC, para mantener el día del usuario)
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
};

// Convierte YYYY-MM-DD a inicio del día local en ISO UTC
const dayStartISO = (ymd) => {
  const [y, m, d] = ymd.split("-").map(Number);
  const dt = new Date(y, m - 1, d, 0, 0, 0, 0);
  return dt.toISOString();
};
// Convierte YYYY-MM-DD a fin del día local en ISO UTC
const dayEndISO = (ymd) => {
  const [y, m, d] = ymd.split("-").map(Number);
  const dt = new Date(y, m - 1, d, 23, 59, 59, 999);
  return dt.toISOString();
};

const QUICK_RANGES = [
  { label: "Hoy", desde: () => getISODate(0), hasta: () => getISODate(0) },
  { label: "Ayer", desde: () => getISODate(-1), hasta: () => getISODate(-1) },
  { label: "Última semana", desde: () => getISODate(-6), hasta: () => getISODate(0) },
  { label: "Último mes", desde: () => getISODate(-29), hasta: () => getISODate(0) },
  { label: "Personalizado", desde: null, hasta: null },
];

// Estados de recibo usan el enum estándar (ACTIVO/ANULADO).

// ─── Detalle drawer ───────────────────────────────────────────────────────────
export function ReciboDetalleDialog({ id, open, onClose, onAnular, canAnular }) {
  const { data, isLoading } = useReciboMultiQuery(open ? id : null);

  return (
    <Dialog open={open} onClose={onClose} maxWidth="md" fullWidth>
      <DialogTitle sx={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <span>Detalle de recibo</span>
        <IconButton size="small" onClick={onClose}>
          <Icon icon="mdi:close" />
        </IconButton>
      </DialogTitle>
      <DialogContent dividers>
        {isLoading && (
          <Box sx={{ display: "flex", flexDirection: "column", gap: 1 }}>
            {[...Array(6)].map((_, i) => (
              <Skeleton key={i} height={32} />
            ))}
          </Box>
        )}
        {data && (() => {
          const facturasArr     = Array.isArray(data.facturas)     ? data.facturas     : [];
          const mediosPagoArr   = Array.isArray(data.medios_pago)  ? data.medios_pago  : [];
          const ncAplicadasArr  = Array.isArray(data.nc_aplicadas) ? data.nc_aplicadas : [];
          const retencionesArr  = Array.isArray(data.retenciones)  ? data.retenciones  : [];
          const comprasAplicadasArr = Array.isArray(data.facturas_compra_aplicadas) ? data.facturas_compra_aplicadas : [];
          const gastosAsociadosArr = Array.isArray(data.gastos_asociados) ? data.gastos_asociados : [];
          return (
          <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
            {/* Encabezado */}
            <Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 1 }}>
              <Box>
                <Typography variant="caption" color="text.secondary">
                  Número
                </Typography>
                <Typography fontWeight={600}>{data.numero}</Typography>
              </Box>
              <Box>
                <Typography variant="caption" color="text.secondary">
                  Estado
                </Typography>
                <Box>
                  <Chip size="small" {...getEstadoChip(data.estado)} />
                </Box>
              </Box>
              <Box>
                <Typography variant="caption" color="text.secondary">
                  Fecha
                </Typography>
                <Typography>{fmtFecha(data.fecha)}</Typography>
              </Box>
              <Box>
                <Typography variant="caption" color="text.secondary">
                  Cliente
                </Typography>
                <Typography>{data.cliente_razon_social}</Typography>
              </Box>
              <Box>
                <Typography variant="caption" color="text.secondary">
                  Total cobrado
                </Typography>
                <Typography fontWeight={600} color="primary.main">
                  {fmtGs(data.total_cobrado)}
                </Typography>
              </Box>
              {data.total_intereses > 0 && (
                <Box>
                  <Typography variant="caption" color="text.secondary">
                    Intereses
                  </Typography>
                  <Typography>{fmtGs(data.total_intereses)}</Typography>
                </Box>
              )}
            </Box>

            {/* Facturas imputadas */}
            <Box>
              <Typography variant="subtitle2" gutterBottom>
                Facturas imputadas
              </Typography>
              <TableContainer component={Paper} variant="outlined">
                <Table size="small">
                  <TableHead>
                    <TableRow>
                      <TableCell>Factura</TableCell>
                      <TableCell align="right">Imputado</TableCell>
                      <TableCell align="right">Saldo anterior</TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {facturasArr.map((f) => (
                      <TableRow key={f.id}>
                        <TableCell>{f.factura_numero || "Sin número"}</TableCell>
                        <TableCell align="right">{fmtGs(f.monto_imputado)}</TableCell>
                        <TableCell align="right">{fmtGs(f.saldo_anterior)}</TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              </TableContainer>
            </Box>

            {/* Medios de pago */}
            {mediosPagoArr.length > 0 && (
              <Box>
                <Typography variant="subtitle2" gutterBottom>
                  Medios de pago
                </Typography>
                <TableContainer component={Paper} variant="outlined">
                  <Table size="small">
                    <TableHead>
                      <TableRow>
                        <TableCell>Tipo</TableCell>
                        <TableCell>Referencia</TableCell>
                        <TableCell align="right">Monto</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {mediosPagoArr.map((m) => (
                        <TableRow key={m.id}>
                          <TableCell>{TIPOS_MEDIO_PAGO[m.tipo ?? m.medio]?.label ?? (m.tipo ?? m.medio)}</TableCell>
                          <TableCell>{m.referencia ?? "—"}</TableCell>
                          <TableCell align="right">{fmtGs(m.monto)}</TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Box>
            )}

            {/* NC aplicadas */}
            {ncAplicadasArr.length > 0 && (
              <Box>
                <Typography variant="subtitle2" gutterBottom>
                  Notas de crédito aplicadas
                </Typography>
                {ncAplicadasArr.map((nc) => (
                  <Box key={nc.id} sx={{ display: "flex", justifyContent: "space-between", py: 0.5 }}>
                    <Typography variant="body2">{nc.nc_numero || "Sin número"}</Typography>
                    <Typography variant="body2" color="success.main">
                      -{fmtGs(nc.monto_aplicado)}
                    </Typography>
                  </Box>
                ))}
              </Box>
            )}

            {/* Facturas por acuerdo comercial */}
            {comprasAplicadasArr.length > 0 && (
              <Box>
                <Box sx={{ display: "flex", alignItems: "center", gap: 1, mb: 0.5 }}>
                  <Typography variant="subtitle2">Facturas por acuerdo comercial compensadas</Typography>
                  <Chip size="small" color="info" icon={<Icon icon="mdi:swap-horizontal" />} label="Compensación" />
                </Box>
                <TableContainer component={Paper} variant="outlined">
                  <Table size="small">
                    <TableHead>
                      <TableRow>
                        <TableCell>Factura</TableCell>
                        <TableCell>Fecha</TableCell>
                        <TableCell>Observación</TableCell>
                        <TableCell align="right">Monto</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {comprasAplicadasArr.map((c) => (
                        <TableRow key={c.id}>
                          <TableCell sx={{ fontFamily: "monospace" }}>{c.compra_numero || "Sin número"}</TableCell>
                          <TableCell>{fmtFecha(c.compra_fecha)}</TableCell>
                          <TableCell>{c.observacion ?? "—"}</TableCell>
                          <TableCell align="right" sx={{ color: "info.main", fontWeight: 600 }}>
                            -{fmtGs(c.monto)}
                          </TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Box>
            )}

            {/* Gastos documentados */}
            {gastosAsociadosArr.length > 0 && (
              <Box>
                <Box sx={{ display: "flex", alignItems: "center", gap: 1, mb: 0.5 }}>
                  <Typography variant="subtitle2">Gastos documentados descontados</Typography>
                  <Chip size="small" color="warning" icon={<Icon icon="mdi:receipt-text-minus-outline" />} label="CxP cancelada" />
                </Box>
                <TableContainer component={Paper} variant="outlined">
                  <Table size="small">
                    <TableHead>
                      <TableRow>
                        <TableCell>Proveedor</TableCell>
                        <TableCell>Factura</TableCell>
                        <TableCell>Fecha</TableCell>
                        <TableCell>Observación</TableCell>
                        <TableCell align="right">Monto</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {gastosAsociadosArr.map((g) => (
                        <TableRow key={g.id}>
                          <TableCell>{g.proveedor_razon_social ?? "—"}</TableCell>
                          <TableCell sx={{ fontFamily: "monospace" }}>{g.gasto_numero || "Sin número"}</TableCell>
                          <TableCell>{fmtFecha(g.gasto_fecha)}</TableCell>
                          <TableCell>{g.observacion ?? "—"}</TableCell>
                          <TableCell align="right" sx={{ color: "warning.main", fontWeight: 600 }}>
                            -{fmtGs(g.monto_aplicado)}
                          </TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Box>
            )}

            {/* Retenciones */}
            {retencionesArr.length > 0 && (
              <Box>
                <Typography variant="subtitle2" gutterBottom>
                  Retenciones recibidas
                </Typography>
                <TableContainer component={Paper} variant="outlined">
                  <Table size="small">
                    <TableHead>
                      <TableRow>
                        <TableCell>Tipo</TableCell>
                        <TableCell>Comprobante</TableCell>
                        <TableCell>Fecha</TableCell>
                        <TableCell align="right">Monto</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {retencionesArr.map((r) => (
                        <TableRow key={r.id}>
                          <TableCell><Chip size="small" {...getTipoRetencionChip(r.tipo)} /></TableCell>
                          <TableCell>{r.numero_comprobante}</TableCell>
                          <TableCell>{fmtFecha(r.fecha_comprobante)}</TableCell>
                          <TableCell align="right">{fmtGs(r.monto)}</TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
              </Box>
            )}

            {/* Motivo anulación */}
            {data.estado === "ANULADO" && data.motivo_anulacion && (
              <Alert severity="error" icon={<Icon icon="mdi:cancel" />}>
                <strong>Anulado:</strong> {data.motivo_anulacion}
              </Alert>
            )}
          </Box>
          );
        })()}
      </DialogContent>
      <DialogActions>
        {canAnular && data?.estado === "ACTIVO" && (
          <Button color="error" startIcon={<Icon icon="mdi:cancel" />} onClick={() => onAnular(data)}>
            Anular
          </Button>
        )}
        <Button onClick={onClose}>Cerrar</Button>
      </DialogActions>
    </Dialog>
  );
}

// ─── Anular dialog ────────────────────────────────────────────────────────────
export function AnularDialog({ recibo, open, onClose }) {
  const [motivo, setMotivo] = useState("");
  const mutation = useAnularReciboMultiMutation();

  const handleConfirm = () => {
    if (!motivo.trim()) {
      toast.error("Ingresá un motivo de anulación");
      return;
    }
    mutation.mutate(
      { id: recibo.id, motivo: motivo.trim() },
      {
        onSuccess: () => {
          onClose();
          setMotivo("");
        },
      },
    );
  };

  return (
    <Dialog open={open} onClose={onClose} maxWidth="xs" fullWidth>
      <DialogTitle>Anular recibo {recibo?.numero}</DialogTitle>
      <DialogContent sx={{ pt: "16px !important" }}>
        <Alert severity="warning" sx={{ mb: 2 }}>
          Se revertirán todos los saldos automáticamente.
        </Alert>
        <TextField label="Motivo de anulación" value={motivo} onChange={(e) => setMotivo(e.target.value)} multiline rows={3} fullWidth size="small" autoFocus />
      </DialogContent>
      <DialogActions>
        <Button onClick={onClose} disabled={mutation.isPending}>
          Cancelar
        </Button>
        <Button variant="contained" color="error" onClick={handleConfirm} disabled={mutation.isPending}>
          {mutation.isPending ? "Anulando…" : "Confirmar anulación"}
        </Button>
      </DialogActions>
    </Dialog>
  );
}

// ─── Panel principal ──────────────────────────────────────────────────────────
export function RecibosMultiPanel() {
  const { can } = usePermission("COBRANZAS");

  const [rangeIdx, setRangeIdx] = useState(0);
  const [desde, setDesde] = useState(getISODate(0));
  const [hasta, setHasta] = useState(getISODate(0));
  const [busqueda, setBusqueda] = useState("");
  const [page, setPage] = useState(1);

  const [detalleId, setDetalleId] = useState(null);
  const [detalleOpen, setDetalleOpen] = useState(false);
  const [anularRecibo, setAnularRecibo] = useState(null);
  const [wizardOpen, setWizardOpen] = useState(false);

  const busquedaTrim = busqueda.trim();
  const filters = {
    ...(busquedaTrim
      ? {}
      : {
          desde: desde ? dayStartISO(desde) : undefined,
          hasta: hasta ? dayEndISO(hasta) : undefined,
        }),
    search: busquedaTrim || undefined,
    page,
    limit: 25,
  };
  const { data, isLoading } = useRecibosMultiQuery(filters);
  const guiaRef = useRef(null);
  const scrollToGuia = () => guiaRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });

  const recibos = data?.data ?? [];
  const total = data?.total ?? 0;
  const pages = data?.pages ?? 1;

  const handleRangeChange = (idx) => {
    setRangeIdx(idx);
    const r = QUICK_RANGES[idx];
    if (r.desde) {
      setDesde(r.desde());
      setHasta(r.hasta());
    }
  };

  const openDetalle = (id) => {
    setDetalleId(id);
    setDetalleOpen(true);
  };

  return (
    <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
      <ScreenGuia ref={guiaRef} titulo="¿Cómo funcionan los recibos multi-factura?" {...GUIA_RECIBOS_MULTI} />

      {/* Toolbar */}
      <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", alignItems: "center" }}>
        <Select size="small" value={rangeIdx} onChange={(e) => handleRangeChange(e.target.value)} sx={{ minWidth: 150 }}>
          {QUICK_RANGES.map((r, i) => (
            <MenuItem key={r.label} value={i}>
              {r.label}
            </MenuItem>
          ))}
        </Select>

        <Collapse in={QUICK_RANGES[rangeIdx].desde === null} orientation="horizontal">
          <Box sx={{ display: "flex", gap: 1 }}>
            <TextField size="small" type="date" label="Desde" value={desde} onChange={(e) => setDesde(e.target.value)} InputLabelProps={{ shrink: true }} />
            <TextField size="small" type="date" label="Hasta" value={hasta} onChange={(e) => setHasta(e.target.value)} InputLabelProps={{ shrink: true }} />
          </Box>
        </Collapse>

        <TextField
          size="small"
          placeholder="Buscar cliente o nro. recibo…"
          value={busqueda}
          onChange={(e) => {
            setBusqueda(e.target.value);
            setPage(1);
          }}
          sx={{ minWidth: 240 }}
          InputProps={{
            startAdornment: (
              <InputAdornment position="start">
                <Icon icon="mdi:magnify" />
              </InputAdornment>
            ),
          }}
        />

        <Box sx={{ ml: "auto" }}>
          {can("COB_REC_RECIBO_CREAR") && (
            <Button variant="contained" startIcon={<Icon icon="mdi:plus" />} onClick={() => setWizardOpen(true)}>
              Nuevo recibo
            </Button>
          )}
        </Box>
      </Box>

      {/* Tabla */}
      <TableContainer component={Paper} variant="outlined">
        <Table size="small">
          <TableHead>
            <TableRow sx={{ "& th": { fontWeight: 600, bgcolor: "action.hover" } }}>
              <TableCell>Número</TableCell>
              <TableCell>Fecha</TableCell>
              <TableCell>Cliente</TableCell>
              <TableCell align="right">Facturas</TableCell>
              <TableCell align="right">Total cobrado</TableCell>
              <TableCell align="right">Retenciones</TableCell>
              <TableCell>Estado</TableCell>
              <TableCell align="center">Acciones</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {isLoading &&
              [...Array(8)].map((_, i) => (
                <TableRow key={i}>
                  {[...Array(8)].map((__, j) => (
                    <TableCell key={j}>
                      <Skeleton />
                    </TableCell>
                  ))}
                </TableRow>
              ))}
            {!isLoading && recibos.length === 0 && (
              <TableRow>
                <TableCell colSpan={8} sx={{ borderBottom: "none", py: 0 }}>
                  <EmptyState
                    icon="mdi:receipt-text-outline"
                    title="No hay recibos en este período"
                    description="Probá ampliar el rango de fechas o registrar un nuevo recibo multi-factura."
                    ctaLabel={can("COB_REC_RECIBO_CREAR") ? "Nuevo recibo" : undefined}
                    onCta={can("COB_REC_RECIBO_CREAR") ? () => setWizardOpen(true) : undefined}
                    onHelp={scrollToGuia}
                  />
                </TableCell>
              </TableRow>
            )}
            {recibos.map((r) => (
              <TableRow
                key={r.id}
                hover
                sx={{
                  cursor: "pointer",
                  opacity: r.estado === "ANULADO" ? 0.5 : 1,
                  "& td": { textDecoration: r.estado === "ANULADO" ? "line-through" : "none" },
                }}
                onClick={() => openDetalle(r.id)}
              >
                <TableCell sx={{ fontFamily: "monospace", textDecoration: "none !important" }}>{r.numero}</TableCell>
                <TableCell sx={{ textDecoration: "none !important" }}>{fmtFecha(r.fecha)}</TableCell>
                <TableCell>{r.cliente_razon_social}</TableCell>
                <TableCell align="right">{r._count?.facturas ?? "—"}</TableCell>
                <TableCell align="right" sx={{ fontWeight: 600 }}>
                  {fmtGs(r.total_cobrado)}
                </TableCell>
                <TableCell align="right">{r._count?.retenciones > 0 ? <Chip size="small" label={`${r._count.retenciones} ret.`} color="info" variant="outlined" /> : "—"}</TableCell>
                <TableCell sx={{ textDecoration: "none !important" }}>
                  <Chip size="small" {...getEstadoChip(r.estado)} />
                </TableCell>
                <TableCell align="center" sx={{ textDecoration: "none !important" }} onClick={(e) => e.stopPropagation()}>
                  <Tooltip title="Ver detalle">
                    <IconButton size="small" onClick={() => openDetalle(r.id)}>
                      <Icon icon="mdi:eye-outline" />
                    </IconButton>
                  </Tooltip>
                  {can("COB_REC_RECIBO_ANULAR") && r.estado === "ACTIVO" && (
                    <Tooltip title="Anular recibo">
                      <IconButton size="small" color="error" onClick={() => setAnularRecibo(r)}>
                        <Icon icon="mdi:cancel" />
                      </IconButton>
                    </Tooltip>
                  )}
                </TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>

      {/* Paginación simple */}
      {pages > 1 && (
        <Box sx={{ display: "flex", justifyContent: "flex-end", alignItems: "center", gap: 1 }}>
          <Typography variant="body2" color="text.secondary">
            {total} recibos — Página {page} de {pages}
          </Typography>
          <IconButton size="small" disabled={page <= 1} onClick={() => setPage((p) => p - 1)}>
            <Icon icon="mdi:chevron-left" />
          </IconButton>
          <IconButton size="small" disabled={page >= pages} onClick={() => setPage((p) => p + 1)}>
            <Icon icon="mdi:chevron-right" />
          </IconButton>
        </Box>
      )}

      {/* Dialogs */}
      <ReciboDetalleDialog
        id={detalleId}
        open={detalleOpen}
        onClose={() => setDetalleOpen(false)}
        canAnular={can("COB_REC_RECIBO_ANULAR")}
        onAnular={(r) => {
          setDetalleOpen(false);
          setAnularRecibo(r);
        }}
      />

      {anularRecibo && <AnularDialog recibo={anularRecibo} open={!!anularRecibo} onClose={() => setAnularRecibo(null)} />}

      {wizardOpen && <NuevoReciboMultiWizard open={wizardOpen} onClose={() => setWizardOpen(false)} />}
    </Box>
  );
}
