import { Icon } from "@iconify/react";
import {
  Autocomplete,
  Box,
  Button,
  Card,
  CardContent,
  Chip,
  FormControlLabel,
  Grid,
  Paper,
  Skeleton,
  Stack,
  Switch,
  Table,
  TableBody,
  TableCell,
  TableContainer,
  TableHead,
  TableRow,
  TextField,
  Typography,
} from "@mui/material";
import { useQuery } from "@tanstack/react-query";
import { useMemo, useState } from "react";
import { useNavigate, useSearchParams } from "react-router-dom";
import { toast } from "sonner";
import * as XLSX from "xlsx";
import { getReporteSaldosPorEmpleadoPDF } from "../api/rendicion-viaticos.service";
import { getEmpleados } from "../api/rrhh.service";
import { useDebouncedValue } from "../hooks/useDebouncedValue";
import { EmptyState, PDFPreviewDialog, ScreenGuia } from "../components/_standards";
import { fmtMoneda } from "../components/_standards/enums/monedas";
import { DetalleEmpleadoSaldoDialog } from "../components/organismos/RendicionViaticosDesign/DetalleEmpleadoSaldoDialog";
import { useReporteSaldosPorEmpleadoQuery } from "../tanstack/RendicionViaticosStack";
import { sanitizeRows } from "../components/_standards";
import { hoyISO } from "../utils/fecha";

const GUIA_PASOS = [
  {
    icon: "mdi:account-cash",
    color: "#3b82f6",
    titulo: "Saldo a favor de la empresa",
    desc: "El empleado tiene adelantos aún no rendidos. Necesita cerrar la rendición o devolver el excedente.",
  },
  {
    icon: "mdi:hand-heart",
    color: "#22c55e",
    titulo: "Saldo a favor del empleado",
    desc: "La empresa le debe reintegros. Suma tanto saldos negativos de rendiciones abiertas como CxP diferidas pendientes.",
  },
  {
    icon: "mdi:file-eye",
    color: "#f59e0b",
    titulo: "Auditar por empleado",
    desc: "Reporte auxiliar que apoya al informe contable de la cuenta 1.01.03.03.04 (Anticipos a Funcionarios).",
  },
];

const GUIA_NOTAS = [
  {
    icon: "mdi:information-outline",
    text: "Solo se muestran rendiciones no cerradas y CxP con saldo pendiente.",
  },
];

export function RendicionSaldosPorEmpleadoPage() {
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const soloConSaldo = (searchParams.get("solo_con_saldo") ?? "true") !== "false";
  const setSoloConSaldo = (v) => {
    const next = new URLSearchParams(searchParams);
    if (v) next.delete("solo_con_saldo");
    else next.set("solo_con_saldo", "false");
    setSearchParams(next, { replace: true });
  };

  const [empleadoSel, setEmpleadoSel] = useState(null);
  const [empleadoInput, setEmpleadoInput] = useState("");
  const empleadoSearch = useDebouncedValue(empleadoInput, 400);

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

  const filtros = useMemo(
    () => ({
      empleado_id: empleadoSel?.id,
      solo_con_saldo: soloConSaldo ? "true" : "",
    }),
    [empleadoSel, soloConSaldo],
  );

  const { data, isLoading } = useReporteSaldosPorEmpleadoQuery(filtros);
  const items = data?.items ?? [];
  const totales = data?.totales ?? {};

  // Drill-down
  const [detalleEmp, setDetalleEmp] = useState(null);
  // PDF preview
  const [pdfOpen, setPdfOpen] = useState(false);
  const fetchPDF = useMemo(() => () => getReporteSaldosPorEmpleadoPDF(filtros), [filtros]);
  // Export XLSX
  const [exportando, setExportando] = useState(false);

  const diasSinActividad = (item) => {
    if (!item.ultima_actividad) return null;
    const dias = Math.floor((Date.now() - new Date(item.ultima_actividad).getTime()) / 86400000);
    return dias < 0 ? 0 : dias;
  };

  const handleExportar = () => {
    if (exportando || items.length === 0) {
      if (items.length === 0) toast.info("No hay datos para exportar");
      return;
    }
    setExportando(true);
    try {
      const rows = [
        [
          "Empleado",
          "Cédula",
          "Nº empleado",
          "Rend. abiertas",
          "Adelantado",
          "Rendido",
          "A favor empresa",
          "A favor empleado",
          "CxP pendientes",
          "CxP monto",
          "Última actividad",
          "Días sin actividad",
        ],
      ];
      for (const it of items) {
        const dias = diasSinActividad(it);
        rows.push([
          `${it.empleado.nombres} ${it.empleado.apellidos}`.trim(),
          it.empleado.cedula_identidad || "",
          it.empleado.numero_empleado || "",
          it.rendiciones_abiertas,
          Number(it.monto_adelantado || 0),
          Number(it.monto_rendido || 0),
          Number(it.saldo_a_favor_empresa || 0),
          Number(it.saldo_a_favor_empleado || 0),
          it.cxp_pendientes,
          Number(it.cxp_monto_pendiente || 0),
          it.ultima_actividad
            ? new Date(it.ultima_actividad).toLocaleDateString("es-PY")
            : "",
          dias ?? "",
        ]);
      }
      const wb = XLSX.utils.book_new();
      const ws = XLSX.utils.aoa_to_sheet(sanitizeRows(rows));
      ws["!cols"] = [
        { wch: 28 }, { wch: 12 }, { wch: 8 }, { wch: 8 },
        { wch: 14 }, { wch: 14 }, { wch: 16 }, { wch: 16 },
        { wch: 10 }, { wch: 14 }, { wch: 14 }, { wch: 8 },
      ];
      XLSX.utils.book_append_sheet(wb, ws, "Saldos");
      const hoy = hoyISO();
      XLSX.writeFile(wb, `saldos-viaticos-por-empleado-${hoy}.xlsx`);
      toast.success("Reporte exportado correctamente");
    } catch (err) {
      toast.error(err?.message || "Error al exportar");
    } finally {
      setExportando(false);
    }
  };

  return (
    <Box p={2}>
      <ScreenGuia
        titulo="Saldos de viáticos por empleado"
        moduloPadre="Rendición de Viáticos · Reportes"
        intro="Informe auxiliar por empleado con saldos abiertos y CxP diferidas pendientes."
        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-cash-outline" />
          Saldos por empleado
        </Typography>
        <Stack direction="row" spacing={1}>
          <Button
            size="small"
            variant="outlined"
            startIcon={<Icon icon="mdi:file-excel-box" />}
            onClick={handleExportar}
            disabled={exportando}
          >
            {exportando ? "Exportando..." : "Excel"}
          </Button>
          <Button
            size="small"
            variant="outlined"
            startIcon={<Icon icon="mdi:file-pdf-box" />}
            onClick={() => setPdfOpen(true)}
            disabled={items.length === 0}
          >
            PDF
          </Button>
          <Button
            size="small"
            variant="outlined"
            startIcon={<Icon icon="mdi:arrow-left" />}
            onClick={() => navigate("/rendicion-viaticos")}
          >
            Volver
          </Button>
        </Stack>
      </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 }}
          />
          <FormControlLabel
            control={
              <Switch checked={soloConSaldo} onChange={(e) => setSoloConSaldo(e.target.checked)} />
            }
            label="Solo con saldo pendiente"
          />
        </Stack>
      </Paper>

      {/* KPIs totales */}
      <Grid container spacing={{ xs: 1, sm: 2 }} sx={{ mb: 2 }}>
        <Grid size={{ xs: 6, sm: 3 }}>
          <Card variant="outlined" sx={{ height: "100%" }}>
            <CardContent sx={{ p: { xs: 1, sm: 1.5 } }}>
              <Typography color="text.secondary" variant="caption">
                Empleados con actividad
              </Typography>
              <Typography variant="h5" fontWeight={700}>
                {isLoading ? <Skeleton width={40} /> : totales.empleados_con_actividad ?? 0}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid size={{ xs: 6, sm: 3 }}>
          <Card variant="outlined" sx={{ height: "100%" }}>
            <CardContent sx={{ p: { xs: 1, sm: 1.5 } }}>
              <Typography color="text.secondary" variant="caption">
                Rendiciones abiertas
              </Typography>
              <Typography variant="h5" fontWeight={700} color="warning.main">
                {isLoading ? <Skeleton width={40} /> : totales.rendiciones_abiertas ?? 0}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid size={{ xs: 12, sm: 3 }}>
          <Card variant="outlined" sx={{ height: "100%" }}>
            <CardContent sx={{ p: { xs: 1, sm: 1.5 } }}>
              <Typography color="text.secondary" variant="caption">
                Saldo a favor empresa
              </Typography>
              <Typography variant="h6" fontWeight={700} color="warning.main">
                {isLoading ? <Skeleton width={100} /> : fmtMoneda(totales.saldo_a_favor_empresa ?? 0, "PYG")}
              </Typography>
            </CardContent>
          </Card>
        </Grid>
        <Grid size={{ xs: 12, sm: 3 }}>
          <Card variant="outlined" sx={{ height: "100%" }}>
            <CardContent sx={{ p: { xs: 1, sm: 1.5 } }}>
              <Typography color="text.secondary" variant="caption">
                Saldo a favor empleado
              </Typography>
              <Typography variant="h6" fontWeight={700} color="success.main">
                {isLoading ? <Skeleton width={100} /> : fmtMoneda(totales.saldo_a_favor_empleado ?? 0, "PYG")}
              </Typography>
              {(totales.cxp_pendientes ?? 0) > 0 && (
                <Typography variant="caption" color="text.secondary">
                  {totales.cxp_pendientes} CxP pendientes
                </Typography>
              )}
            </CardContent>
          </Card>
        </Grid>
      </Grid>

      <Paper variant="outlined" sx={{ overflow: "hidden", borderRadius: 2 }}>
        {isLoading ? (
          <Box sx={{ p: 2 }}>
            <Skeleton height={44} />
            <Skeleton height={44} />
            <Skeleton height={44} />
          </Box>
        ) : items.length === 0 ? (
          <Box sx={{ p: 3 }}>
            <EmptyState
              icon="mdi:account-cash-outline"
              title="Sin saldos abiertos"
              description="Ningún empleado tiene rendiciones abiertas ni CxP pendientes con el filtro actual."
            />
          </Box>
        ) : (
          <TableContainer>
            <Table size="small">
              <TableHead>
                <TableRow>
                  <TableCell sx={{ fontWeight: 600 }}>Empleado</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="center">Rend. abiertas</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="right">Adelantado</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="right">Rendido</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="right">A favor empresa</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="right">A favor empleado</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="center">CxP pendientes</TableCell>
                  <TableCell sx={{ fontWeight: 600 }} align="center">Última actividad</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {items.map((it) => (
                  <TableRow
                    key={it.empleado.id}
                    hover
                    sx={{ cursor: "pointer" }}
                    onClick={() => setDetalleEmp(it.empleado)}
                  >
                    <TableCell>
                      <Typography variant="body2" fontWeight={600}>
                        {it.empleado.nombres} {it.empleado.apellidos}
                      </Typography>
                      {it.empleado.numero_empleado && (
                        <Typography variant="caption" color="text.secondary">
                          #{it.empleado.numero_empleado}
                        </Typography>
                      )}
                    </TableCell>
                    <TableCell align="center">{it.rendiciones_abiertas}</TableCell>
                    <TableCell align="right">{fmtMoneda(it.monto_adelantado, "PYG")}</TableCell>
                    <TableCell align="right">{fmtMoneda(it.monto_rendido, "PYG")}</TableCell>
                    <TableCell align="right">
                      <Typography sx={{ fontWeight: 700, color: it.saldo_a_favor_empresa > 0 ? "warning.main" : "text.secondary" }}>
                        {fmtMoneda(it.saldo_a_favor_empresa, "PYG")}
                      </Typography>
                    </TableCell>
                    <TableCell align="right">
                      <Typography sx={{ fontWeight: 700, color: it.saldo_a_favor_empleado > 0 ? "success.main" : "text.secondary" }}>
                        {fmtMoneda(it.saldo_a_favor_empleado, "PYG")}
                      </Typography>
                    </TableCell>
                    <TableCell align="center">
                      {it.cxp_pendientes > 0 ? (
                        <Chip
                          size="small"
                          label={`${it.cxp_pendientes} · ${fmtMoneda(it.cxp_monto_pendiente, "PYG")}`}
                          color="info"
                          variant="outlined"
                          onClick={(e) => {
                            e.stopPropagation();
                            navigate(`/rendicion-viaticos/cxp-empleados?empleado_id=${it.empleado.id}`);
                          }}
                        />
                      ) : (
                        "—"
                      )}
                    </TableCell>
                    <TableCell align="center">
                      {(() => {
                        const dias = diasSinActividad(it);
                        if (dias === null) return "—";
                        const color = dias > 30 ? "error" : dias > 15 ? "warning" : "success";
                        return (
                          <Chip
                            size="small"
                            label={`${dias}d`}
                            color={color}
                            variant="outlined"
                          />
                        );
                      })()}
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </TableContainer>
        )}
      </Paper>

      <DetalleEmpleadoSaldoDialog
        open={!!detalleEmp}
        onClose={() => setDetalleEmp(null)}
        empleado={detalleEmp}
      />

      <PDFPreviewDialog
        open={pdfOpen}
        onClose={() => setPdfOpen(false)}
        title="Saldos de viáticos por empleado"
        fetchBlob={fetchPDF}
        downloadFilename={`saldos-viaticos-por-empleado-${hoyISO()}.pdf`}
      />
    </Box>
  );
}

export default RendicionSaldosPorEmpleadoPage;
