import { Icon } from "@iconify/react";
import {
  Autocomplete,
  Box,
  Button,
  Card,
  CardContent,
  Chip,
  Collapse,
  Grid,
  IconButton,
  MenuItem,
  Paper,
  Skeleton,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Tooltip,
  Typography,
} from "@mui/material";
import { useQuery } from "@tanstack/react-query";
import { Fragment, useEffect, useMemo, useState } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import { getCxpEmpleadoPDF } from "../api/rendicion-viaticos.service";
import { getEmpleado, getEmpleados } from "../api/rrhh.service";
import { useDebouncedValue } from "../hooks/useDebouncedValue";
import { usePermission } from "../hooks/usePermission";
import { EmptyState, PDFPreviewDialog, ScreenGuia } from "../components/_standards";
import { fmtMoneda } from "../components/_standards/enums/monedas";
import { PagarCxpEmpleadoDialog } from "../components/organismos/RendicionViaticosDesign/PagarCxpEmpleadoDialog";
import { useCxpEmpleadosQuery } from "../tanstack/RendicionViaticosStack";
import { fmtFechaCalendario } from "../utils/fecha";

// Origen de la cuenta por pagar, para mostrar (nunca el código interno).
const ORIGEN_CXP_LABEL = {
  reintegro_viatico: "Rendición viáticos",
  rendicion_adelanto: "Adelanto de viáticos",
  rendicion_devolucion: "Devolución de viáticos",
  cxp_empleado_pago: "Pago al empleado",
};

const ESTADOS = [
  { value: "todos", label: "Todos" },
  { value: "pendiente", label: "Pendiente" },
  { value: "parcial", label: "Parcial" },
  { value: "pagada", label: "Pagada" },
  { value: "anulada", label: "Anulada" },
];

const GUIA_PASOS = [
  {
    icon: "mdi:receipt-text-clock",
    color: "#f59e0b",
    titulo: "Origen: reintegro diferido",
    desc: "Cuando la empresa cierra una rendición eligiendo reintegro DIFERIDO, se genera una CxP a favor del empleado.",
  },
  {
    icon: "mdi:cash-check",
    color: "#22c55e",
    titulo: "Pagos totales o parciales",
    desc: "Podés cancelar en varias cuotas. Cada pago registra un egreso de tesorería y actualiza el saldo pendiente.",
  },
];

const GUIA_NOTAS = [
  {
    icon: "mdi:information-outline",
    text: "La CxP se cancela automáticamente al alcanzar saldo 0.",
  },
];

const estadoColor = (estado) =>
  ({
    pendiente: "warning",
    parcial: "info",
    pagada: "success",
    anulada: "default",
  })[estado] ?? "default";

export function CxpEmpleadosPage() {
  const navigate = useNavigate();
  const { can } = usePermission("RRHH");
  const canPagar = can("RH_VIA_CXP_PAGAR");
  const [searchParams, setSearchParams] = useSearchParams();
  const empleadoIdParam = searchParams.get("empleado_id") || "";
  const estado = searchParams.get("estado") || "pendiente";

  const setEstado = (value) => {
    const next = new URLSearchParams(searchParams);
    if (!value || value === "pendiente") next.delete("estado");
    else next.set("estado", value);
    setSearchParams(next, { replace: true });
  };

  const desde = searchParams.get("desde") || "";
  const hasta = searchParams.get("hasta") || "";
  const setFecha = (key, value) => {
    const next = new URLSearchParams(searchParams);
    if (!value) next.delete(key);
    else next.set(key, value);
    setSearchParams(next, { replace: true });
  };
  const applyPresetRange = (preset) => {
    const hoy = new Date();
    const yyyy = (d) => d.toISOString().substring(0, 10);
    const next = new URLSearchParams(searchParams);
    if (preset === "mes-actual") {
      const first = new Date(hoy.getFullYear(), hoy.getMonth(), 1);
      next.set("desde", yyyy(first));
      next.set("hasta", yyyy(hoy));
    } else if (preset === "mes-anterior") {
      const first = new Date(hoy.getFullYear(), hoy.getMonth() - 1, 1);
      const last = new Date(hoy.getFullYear(), hoy.getMonth(), 0);
      next.set("desde", yyyy(first));
      next.set("hasta", yyyy(last));
    } else if (preset === "30d") {
      const d = new Date(hoy);
      d.setDate(d.getDate() - 30);
      next.set("desde", yyyy(d));
      next.set("hasta", yyyy(hoy));
    } else if (preset === "limpiar") {
      next.delete("desde");
      next.delete("hasta");
    }
    setSearchParams(next, { replace: true });
  };

  const [empleadoSel, setEmpleadoSel] = useState(null);
  const [empleadoInput, setEmpleadoInput] = useState("");
  const empleadoSearch = useDebouncedValue(empleadoInput, 400);
  const [cxpPagar, setCxpPagar] = useState(null);
  const [expandedId, setExpandedId] = useState(null);
  const [pdfCxp, setPdfCxp] = useState(null);
  const fetchPDF = useMemo(
    () => (pdfCxp ? () => getCxpEmpleadoPDF(pdfCxp.id) : null),
    [pdfCxp],
  );

  const { data: empleadosResp, isFetching: empleadosLoading } = useQuery({
    queryKey: ["rrhh-empleados-cxp", empleadoSearch],
    queryFn: () => getEmpleados({ search: empleadoSearch || undefined, limit: 10 }),
    keepPreviousData: true,
  });
  const empleados = empleadosResp?.data ?? empleadosResp?.items ?? empleadosResp ?? [];

  // sync url param al select — carga el empleado por id si no está en la lista.
  useEffect(() => {
    let cancel = false;
    if (empleadoIdParam && !empleadoSel) {
      getEmpleado(empleadoIdParam)
        .then((e) => {
          if (!cancel && e) setEmpleadoSel(e);
        })
        .catch(() => {});
    }
    return () => {
      cancel = true;
    };
  }, [empleadoIdParam, empleadoSel]);

  const filtros = useMemo(
    () => ({
      empleado_id: empleadoSel?.id,
      estado, // pasar tal cual — el backend interpreta "todos"
      desde: desde || undefined,
      hasta: hasta || undefined,
    }),
    [empleadoSel, estado, desde, hasta],
  );

  const { data, isLoading } = useCxpEmpleadosQuery(filtros);
  const items = Array.isArray(data) ? data : data?.items ?? [];

  const totalPendiente = items
    .filter((c) => ["pendiente", "parcial"].includes(c.estado))
    .reduce((s, c) => s + Number(c.saldo_pendiente || 0), 0);

  return (
    <Box p={2}>
      <ScreenGuia
        titulo="CxP a empleados (reintegros diferidos)"
        moduloPadre="Rendición de Viáticos"
        intro="Cuentas por pagar generadas por cierre de rendiciones con reintegro diferido."
        pasos={GUIA_PASOS}
        notas={GUIA_NOTAS}
      />

      <Stack direction="row" alignItems="center" justifyContent="space-between" mb={2} sx={{ flexWrap: "wrap", gap: 1 }}>
        <Typography variant="h6" sx={{ display: "flex", alignItems: "center", gap: 1 }}>
          <Icon icon="mdi:account-arrow-left" />
          CxP a empleados
        </Typography>
        <Button
          size="small"
          variant="outlined"
          startIcon={<Icon icon="mdi:arrow-left" />}
          onClick={() => navigate("/rendicion-viaticos")}
        >
          Volver a rendiciones
        </Button>
      </Stack>

      <Paper variant="outlined" sx={{ p: 2, mb: 2, borderRadius: 2 }}>
        <Stack direction={{ xs: "column", md: "row" }} spacing={2} alignItems={{ md: "center" }}>
          <Autocomplete
            size="small"
            options={empleados}
            value={empleadoSel}
            onChange={(_, v) => setEmpleadoSel(v)}
            inputValue={empleadoInput}
            onInputChange={(_, v) => setEmpleadoInput(v)}
            filterOptions={(x) => x}
            loading={empleadosLoading}
            loadingText="Buscando…"
            noOptionsText={empleadoSearch ? "Sin coincidencias" : "Escribí para buscar"}
            getOptionLabel={(o) => (o ? `${o.nombres} ${o.apellidos}` : "")}
            isOptionEqualToValue={(a, b) => a?.id === b?.id}
            renderInput={(params) => <TextField {...params} label="Empleado" placeholder="Todos" />}
            sx={{ minWidth: 320 }}
          />
          <TextField
            select
            size="small"
            label="Estado"
            value={estado}
            onChange={(e) => setEstado(e.target.value)}
            sx={{ minWidth: 180 }}
          >
            {ESTADOS.map((s) => (
              <MenuItem key={s.value} value={s.value}>
                {s.label}
              </MenuItem>
            ))}
          </TextField>
          <TextField
            size="small"
            type="date"
            label="Desde"
            InputLabelProps={{ shrink: true }}
            value={desde}
            onChange={(e) => setFecha("desde", e.target.value)}
            sx={{ minWidth: 150 }}
          />
          <TextField
            size="small"
            type="date"
            label="Hasta"
            InputLabelProps={{ shrink: true }}
            value={hasta}
            onChange={(e) => setFecha("hasta", e.target.value)}
            sx={{ minWidth: 150 }}
          />
        </Stack>
        <Stack direction="row" spacing={1} sx={{ mt: 1.5, flexWrap: "wrap", gap: 0.5 }}>
          <Button size="small" variant="text" onClick={() => applyPresetRange("mes-actual")}>
            Este mes
          </Button>
          <Button size="small" variant="text" onClick={() => applyPresetRange("mes-anterior")}>
            Mes anterior
          </Button>
          <Button size="small" variant="text" onClick={() => applyPresetRange("30d")}>
            Últimos 30 días
          </Button>
          {(desde || hasta) && (
            <Button size="small" variant="text" color="error" onClick={() => applyPresetRange("limpiar")}>
              Limpiar rango
            </Button>
          )}
        </Stack>
      </Paper>

      <Grid container spacing={{ xs: 1, sm: 2 }} sx={{ mb: 2 }}>
        <Grid size={{ xs: 6, sm: 4 }}>
          <Card variant="outlined">
            <CardContent sx={{ p: { xs: 1, sm: 1.5 } }}>
              <Typography color="text.secondary" variant="caption">Registros</Typography>
              <Typography variant="h5" fontWeight={700}>
                {isLoading ? <Skeleton width={40} /> : items.length}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid size={{ xs: 12, sm: 8 }}>
          <Card variant="outlined">
            <CardContent sx={{ p: { xs: 1, sm: 1.5 } }}>
              <Typography color="text.secondary" variant="caption">Saldo pendiente total</Typography>
              <Typography variant="h5" fontWeight={700} color="warning.main">
                {isLoading ? <Skeleton width={140} /> : fmtMoneda(totalPendiente, "PYG")}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
      </Grid>

      <Paper variant="outlined" sx={{ overflow: "hidden", borderRadius: 2 }}>
        {isLoading ? (
          <Box sx={{ p: 2 }}>
            <Skeleton height={44} />
            <Skeleton height={44} />
          </Box>
        ) : items.length === 0 ? (
          <Box sx={{ p: 3 }}>
            <EmptyState
              icon="mdi:account-arrow-left"
              title="Sin CxP a empleados"
              description="No hay reintegros diferidos con el filtro actual."
            />
          </Box>
        ) : (
          <TableContainer>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell sx={{ width: 40 }} />
                  <TableCell sx={{ fontWeight: 600 }}>Empleado</TableCell>
                  <TableCell sx={{ fontWeight: 600 }}>Fecha</TableCell>
                  <TableCell sx={{ fontWeight: 600 }}>Origen</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="right">Monto original</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="right">Pagado</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="right">Saldo</TableCell>
                  <TableCell sx={{ fontWeight: 600 }}>Estado</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="center">Acciones</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {items.map((c) => {
                  const puedeReg = canPagar && ["pendiente", "parcial"].includes(c.estado);
                  const isExpanded = expandedId === c.id;
                  const pagos = c.pagos ?? [];
                  const rendicionOrigen = c.devoluciones?.[0]?.rendicion;
                  const rendicionOrigenId = c.devoluciones?.[0]?.rendicion_viatico_id;
                  return (
                    <Fragment key={c.id}>
                      <TableRow hover>
                        <TableCell>
                          <IconButton
                            size="small"
                            onClick={() => setExpandedId(isExpanded ? null : c.id)}
                          >
                            <Icon
                              icon={isExpanded ? "mdi:chevron-up" : "mdi:chevron-down"}
                              width={18}
                            />
                          </IconButton>
                        </TableCell>
                        <TableCell>
                          <Typography variant="body2" fontWeight={600}>
                            {c.empleado?.nombres} {c.empleado?.apellidos}
                          </Typography>
                          {c.empleado?.numero_empleado && (
                            <Typography variant="caption" color="text.secondary">
                              #{c.empleado.numero_empleado}
                            </Typography>
                          )}
                        </TableCell>
                        <TableCell>{fmtFechaCalendario(c.fecha_generacion)}</TableCell>
                        <TableCell>
                          {rendicionOrigen ? (
                            <Box>
                              <Typography
                                variant="body2"
                                sx={{
                                  color: "primary.main",
                                  cursor: "pointer",
                                  textDecoration: "underline",
                                  fontWeight: 600,
                                }}
                                onClick={() =>
                                  rendicionOrigenId &&
                                  navigate(`/rendicion-viaticos/${rendicionOrigenId}`)
                                }
                              >
                                {rendicionOrigen.numero_rendicion}
                              </Typography>
                              <Typography variant="caption" color="text.secondary">
                                {rendicionOrigen.concepto}
                              </Typography>
                            </Box>
                          ) : (
                            ORIGEN_CXP_LABEL[c.origen_tipo] ?? "Otro"
                          )}
                        </TableCell>
                        <TableCell align="right">{fmtMoneda(Number(c.monto_original || 0), "PYG")}</TableCell>
                        <TableCell align="right">{fmtMoneda(Number(c.monto_pagado || 0), "PYG")}</TableCell>
                        <TableCell align="right">
                          <Typography sx={{ fontWeight: 700, color: puedeReg ? "warning.main" : "text.disabled" }}>
                            {fmtMoneda(Number(c.saldo_pendiente || 0), "PYG")}
                          </Typography>
                        </TableCell>
                        <TableCell>
                          <Chip
                            size="small"
                            label={c.estado}
                            color={estadoColor(c.estado)}
                            variant="outlined"
                          />
                        </TableCell>
                        <TableCell align="center">
                          <Stack direction="row" spacing={0.5} justifyContent="center">
                            <Tooltip title={puedeReg ? "Registrar pago" : "No disponible"}>
                              <span>
                                <IconButton
                                  size="small"
                                  color="primary"
                                  disabled={!puedeReg}
                                  onClick={() => setCxpPagar(c)}
                                >
                                  <Icon icon="mdi:cash-check" width={16} />
                                </IconButton>
                              </span>
                            </Tooltip>
                            <Tooltip title="Comprobante PDF">
                              <IconButton size="small" onClick={() => setPdfCxp(c)}>
                                <Icon icon="mdi:file-pdf-box" width={16} />
                              </IconButton>
                            </Tooltip>
                          </Stack>
                        </TableCell>
                      </TableRow>
                      <TableRow>
                        <TableCell colSpan={9} sx={{ p: 0, borderBottom: isExpanded ? undefined : 0 }}>
                          <Collapse in={isExpanded} unmountOnExit>
                            <Box sx={{ p: 2, bgcolor: "action.hover" }}>
                              <Typography variant="caption" fontWeight={700} sx={{ letterSpacing: 0.5, color: "text.secondary" }}>
                                HISTORIAL DE PAGOS
                              </Typography>
                              {pagos.length === 0 ? (
                                <Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}>
                                  Sin pagos registrados aún.
                                </Typography>
                              ) : (
                                <Table size="small" sx={{ mt: 1 }}>
                                  <TableHead>
                                    <TableRow>
                                      <TableCell sx={{ fontSize: 12 }}>Fecha</TableCell>
                                      <TableCell sx={{ fontSize: 12 }}>Cuenta origen</TableCell>
                                      <TableCell sx={{ fontSize: 12 }}>Nº operación</TableCell>
                                      <TableCell sx={{ fontSize: 12 }} align="right">Monto</TableCell>
                                    </TableRow>
                                  </TableHead>
                                  <TableBody>
                                    {pagos.map((p) => (
                                      <TableRow key={p.id}>
                                        <TableCell>{fmtFechaCalendario(p.fecha)}</TableCell>
                                        <TableCell>{p.cuenta?.nombre ?? "—"}</TableCell>
                                        <TableCell>{p.referencia ?? "—"}</TableCell>
                                        <TableCell align="right">
                                          <Typography variant="body2" fontWeight={600} color="success.main">
                                            {fmtMoneda(Number(p.monto || 0), "PYG")}
                                          </Typography>
                                        </TableCell>
                                      </TableRow>
                                    ))}
                                  </TableBody>
                                </Table>
                              )}
                            </Box>
                          </Collapse>
                        </TableCell>
                      </TableRow>
                    </Fragment>
                  );
                })}
              </TableBody>
            </Table>
          </TableContainer>
        )}
      </Paper>

      <PagarCxpEmpleadoDialog
        open={!!cxpPagar}
        onClose={() => setCxpPagar(null)}
        cxp={cxpPagar}
      />

      <PDFPreviewDialog
        open={!!pdfCxp}
        onClose={() => setPdfCxp(null)}
        title={`Comprobante de pago${pdfCxp?.empleado ? ` — ${[pdfCxp.empleado.nombres, pdfCxp.empleado.apellidos].filter(Boolean).join(" ")}` : ""}`}
        fetchBlob={fetchPDF}
        downloadFilename={`comprobante-pago-${pdfCxp?.empleado?.numero_empleado || "empleado"}-${String(pdfCxp?.fecha_generacion || "").slice(0, 10)}.pdf`}
      />
    </Box>
  );
}

export default CxpEmpleadosPage;
