import { Icon } from "@iconify/react";
import { useQuery } from "@tanstack/react-query";
import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import styled from "styled-components";
import { toast } from "sonner";
import * as XLSX from "xlsx";
import {
  Autocomplete, Button, Chip, CircularProgress, Dialog, DialogActions, DialogContent, DialogTitle,
  IconButton, Paper, Table, TableBody, TableCell, TableContainer, TableHead,
  TableRow, TextField, Tooltip, Typography,
} from "@mui/material";
import { FileDownload, PictureAsPdf, Refresh } from "@mui/icons-material";
import { AccesoRestringido } from "../components/common/AccesoRestringido";
import { usePermission } from "../hooks/usePermission";
import { getCierreCobros, getCierreCobrosPdfBlob } from "../api/cobros.service";
import { getCobradoresActivos } from "../api/vendedores-cobradores.service";
import { getMonedas } from "../api/monedas.service";
import { fmtMoneda } from "../components/_standards/enums/monedas";
import { fmtFechaCalendario, hoyISO } from "../utils/fecha";
import { sanitizeRecords } from "../components/_standards";

const firstOfMonthISO = () => {
  const d = new Date();
  d.setDate(1);
  return d.toISOString().slice(0, 10);
};
const todayISO = () => hoyISO();

export default function CierreCobros() {
  const navigate = useNavigate();
  const { can } = usePermission("COBRANZAS");
  const canRead = can("COB_CC_CUENTA_COBRAR_VER");

  const [fechaDesde, setFechaDesde] = useState(firstOfMonthISO());
  const [fechaHasta, setFechaHasta] = useState(todayISO());
  const [cobradorId, setCobradorId] = useState("");
  const [monedaId, setMonedaId] = useState("");
  const [pdfUrl, setPdfUrl] = useState(null);
  const [loadingPdf, setLoadingPdf] = useState(false);

  const params = useMemo(
    () => ({
      fechaDesde,
      fechaHasta,
      cobradorId: cobradorId || undefined,
      monedaId: monedaId || undefined,
    }),
    [fechaDesde, fechaHasta, cobradorId, monedaId],
  );

  const { data, isLoading, refetch, isFetching } = useQuery({
    queryKey: ["cierre-cobros", params],
    queryFn: () => getCierreCobros(params),
    enabled: canRead,
    staleTime: 60_000,
  });

  const { data: cobradores = [] } = useQuery({
    queryKey: ["cobradores-activos"],
    queryFn: getCobradoresActivos,
    select: (d) => (Array.isArray(d) ? d : (d?.data ?? [])),
    staleTime: 5 * 60_000,
    enabled: canRead,
  });

  const { data: monedas = [] } = useQuery({
    queryKey: ["monedas-activas"],
    queryFn: () => getMonedas(),
    select: (d) => (Array.isArray(d) ? d : (d?.data ?? [])).filter((m) => m.activo !== false),
    staleTime: 30 * 60_000,
    enabled: canRead,
  });

  const monedaSel = monedas.find((m) => m.id === monedaId);
  const monedaActiva =
    monedaSel?.codigo ||
    data?.porMonedaTotales?.[0]?.codigo ||
    "PYG";

  const porDia = data?.porDia ?? [];
  const porCondicion = data?.porCondicion ?? [];
  const porMedio = data?.porMedio ?? [];
  const totalGeneral = data?.totalGeneral ?? 0;
  const mediosBuckets = data?.mediosBuckets ?? [];
  const totalRecibos = data?.recibos?.length ?? 0;

  const handleExcel = () => {
    if (!data) return;
    const wb = XLSX.utils.book_new();
    // Diario
    const rowsDia = porDia.map((d) => {
      const row = {
        "Fecha": fmtFechaCalendario(d.fecha),
        "Recibos": d.recibos,
        ...Object.fromEntries(mediosBuckets.map((m) => [m, Math.round(d.por_medio?.[m] ?? 0)])),
        "Total": Math.round(d.total_cobrado ?? 0),
      };
      return row;
    });
    // Totales
    const totalRow = {
      "Fecha": "TOTAL",
      "Recibos": totalRecibos,
      ...Object.fromEntries(mediosBuckets.map((m) => [m, porMedio.find((p) => p.medio === m)?.monto ?? 0])),
      "Total": Math.round(totalGeneral),
    };
    rowsDia.push({});
    rowsDia.push(totalRow);
    const ws1 = XLSX.utils.json_to_sheet(sanitizeRecords(rowsDia));
    ws1["!cols"] = [{ wch: 12 }, { wch: 10 }, ...mediosBuckets.map(() => ({ wch: 14 })), { wch: 16 }];
    XLSX.utils.book_append_sheet(wb, ws1, "Por Día");

    // Por condición
    const rowsCond = porCondicion.map((c) => ({
      "Condición de pago": c.condicion,
      "Recibos": c.cantidad_recibos,
      "Cantidad líneas": c.cantidad_lineas,
      "Monto": Math.round(c.monto),
    }));
    const ws2 = XLSX.utils.json_to_sheet(sanitizeRecords(rowsCond));
    ws2["!cols"] = [{ wch: 22 }, { wch: 10 }, { wch: 14 }, { wch: 16 }];
    XLSX.utils.book_append_sheet(wb, ws2, "Por Condición");

    XLSX.writeFile(wb, `cierre-cobros_${monedaActiva}_${fechaDesde}_${fechaHasta}.xlsx`);
  };

  const handlePDF = async () => {
    setLoadingPdf(true);
    try {
      const blob = await getCierreCobrosPdfBlob(params);
      const url = URL.createObjectURL(blob);
      setPdfUrl(url);
    } catch (e) {
      toast.error(e?.response?.data?.message || "Error al generar el PDF");
    } finally {
      setLoadingPdf(false);
    }
  };

  const cerrarPdf = () => {
    if (pdfUrl) URL.revokeObjectURL(pdfUrl);
    setPdfUrl(null);
  };

  if (!canRead) return <AccesoRestringido modulo="COBRANZAS" />;

  return (
    <Container>
      <Header>
        <BackBtn onClick={() => navigate("/reportes")}>
          <Icon icon="lucide:arrow-left" />
        </BackBtn>
        <TitleSection>
          <MainTitle>
            <Icon icon="lucide:file-clock" />
            Cierre de Cobros
          </MainTitle>
          <Subtitle>Cobros del período, agrupados por día, medio y condición de pago</Subtitle>
        </TitleSection>
        <HeaderActions>
          <Button size="small" variant="outlined" onClick={handleExcel}
            startIcon={<FileDownload />} disabled={!data || porDia.length === 0}>
            Excel
          </Button>
          <Button size="small" variant="outlined" onClick={handlePDF}
            startIcon={loadingPdf ? <CircularProgress size={14} /> : <PictureAsPdf />}
            disabled={!data || porDia.length === 0 || loadingPdf}>
            PDF
          </Button>
          <Tooltip title="Refrescar">
            <IconButton size="small" onClick={() => refetch()} disabled={isFetching}>
              <Refresh fontSize="small" />
            </IconButton>
          </Tooltip>
        </HeaderActions>
      </Header>

      <Filters>
        <TextField label="Desde" type="date" size="small"
          value={fechaDesde} onChange={(e) => setFechaDesde(e.target.value)}
          InputLabelProps={{ shrink: true }} sx={{ minWidth: 160 }} />
        <TextField label="Hasta" type="date" size="small"
          value={fechaHasta} onChange={(e) => setFechaHasta(e.target.value)}
          InputLabelProps={{ shrink: true }} sx={{ minWidth: 160 }} />
        <Autocomplete
          size="small"
          options={cobradores}
          getOptionLabel={(c) => [c.nombre, c.apellido].filter(Boolean).join(" ")}
          value={cobradores.find((c) => c.id === cobradorId) || null}
          onChange={(_, v) => setCobradorId(v?.id || "")}
          isOptionEqualToValue={(o, v) => o.id === v.id}
          renderInput={(params) => (
            <TextField {...params} label="Cobrador (opcional — vacío = todos)"
              placeholder="Buscar…" />
          )}
          sx={{ minWidth: 260 }}
          noOptionsText="Sin resultados"
          clearOnEscape
        />
        <Autocomplete
          size="small"
          options={monedas}
          getOptionLabel={(m) => `${m.codigo}${m.descripcion ? ` — ${m.descripcion}` : ""}`}
          value={monedas.find((m) => m.id === monedaId) || null}
          onChange={(_, v) => setMonedaId(v?.id || "")}
          isOptionEqualToValue={(o, v) => o.id === v.id}
          renderInput={(params) => <TextField {...params} label="Moneda (opcional)" />}
          sx={{ minWidth: 200 }}
          noOptionsText="Sin monedas"
          clearOnEscape
        />
      </Filters>

      {!monedaId && data?.porMonedaTotales?.length > 1 && (
        <MultiMonedaBanner>
          <Icon icon="lucide:alert-triangle" />
          <div>
            <b>Hay cobros en múltiples monedas</b> —{" "}
            {data.porMonedaTotales.map((pm, i) => (
              <span key={pm.codigo}>
                {i > 0 && " · "}
                {fmtMoneda(pm.monto, pm.codigo)}
              </span>
            ))}
            <div style={{ fontSize: 12, opacity: 0.8, marginTop: 2 }}>
              Los totales de la tabla se muestran en <b>{monedaActiva}</b>. Filtrá por moneda para ver solo esa.
            </div>
          </div>
        </MultiMonedaBanner>
      )}

      {isLoading ? (
        <Loading><CircularProgress size={28} /> Cargando…</Loading>
      ) : porDia.length === 0 ? (
        <Empty>
          <Icon icon="lucide:file-search" />
          <p>Sin cobros para los filtros elegidos</p>
        </Empty>
      ) : (
        <Grid>
          <MainCol>
            <SectionCard>
              <SectionTitle>Cobros por día</SectionTitle>
              <TableContainer component={Paper} elevation={0} sx={{ border: "1px solid", borderColor: "divider" }}>
                <Table size="small">
                  <TableHead>
                    <TableRow>
                      <TableCell><b>Fecha</b></TableCell>
                      <TableCell align="right"><b>Recibos</b></TableCell>
                      {mediosBuckets.map((m) => (
                        <TableCell key={m} align="right"><b>{m}</b></TableCell>
                      ))}
                      <TableCell align="right"><b>Total</b></TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {porDia.map((d) => (
                      <TableRow key={d.fecha} hover>
                        <TableCell sx={{ whiteSpace: "nowrap" }}>{fmtFechaCalendario(d.fecha)}</TableCell>
                        <TableCell align="right">{d.recibos}</TableCell>
                        {mediosBuckets.map((m) => (
                          <TableCell key={m} align="right">
                            {(d.por_medio?.[m] ?? 0) > 0 ? fmtMoneda(d.por_medio[m], monedaActiva) : "—"}
                          </TableCell>
                        ))}
                        <TableCell align="right" sx={{ fontWeight: 600 }}>
                          {fmtMoneda(d.total_cobrado, monedaActiva)}
                        </TableCell>
                      </TableRow>
                    ))}
                    <TableRow sx={{ background: "action.hover" }}>
                      <TableCell sx={{ fontWeight: 700 }}>TOTAL</TableCell>
                      <TableCell align="right" sx={{ fontWeight: 700 }}>{totalRecibos}</TableCell>
                      {mediosBuckets.map((m) => {
                        const tot = porMedio.find((p) => p.medio === m)?.monto ?? 0;
                        return (
                          <TableCell key={m} align="right" sx={{ fontWeight: 700 }}>
                            {tot > 0 ? fmtMoneda(tot, monedaActiva) : "—"}
                          </TableCell>
                        );
                      })}
                      <TableCell align="right" sx={{ fontWeight: 700, color: "#22c55e" }}>
                        {fmtMoneda(totalGeneral, monedaActiva)}
                      </TableCell>
                    </TableRow>
                  </TableBody>
                </Table>
              </TableContainer>
            </SectionCard>
          </MainCol>

          <SideCol>
            <SectionCard>
              <SectionTitle>Por condición de pago</SectionTitle>
              {porCondicion.length === 0 ? (
                <Typography variant="body2" sx={{ opacity: 0.6 }}>Sin datos</Typography>
              ) : (
                <TableContainer component={Paper} elevation={0} sx={{ border: "1px solid", borderColor: "divider" }}>
                  <Table size="small">
                    <TableHead>
                      <TableRow>
                        <TableCell><b>Condición</b></TableCell>
                        <TableCell align="right"><b>Recibos</b></TableCell>
                        <TableCell align="right"><b>Monto</b></TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {porCondicion.map((c) => (
                        <TableRow key={c.condicion} hover>
                          <TableCell>
                            <Chip label={c.condicion} size="small" variant="outlined" />
                          </TableCell>
                          <TableCell align="right">{c.cantidad_recibos}</TableCell>
                          <TableCell align="right" sx={{ fontWeight: 600 }}>
                            {fmtMoneda(c.monto, monedaActiva)}
                          </TableCell>
                        </TableRow>
                      ))}
                    </TableBody>
                  </Table>
                </TableContainer>
              )}
            </SectionCard>

            <SectionCard>
              <SectionTitle>Resumen</SectionTitle>
              <ResumenGrid>
                <ResumenItem>
                  <ResumenLabel>Total cobrado</ResumenLabel>
                  <ResumenValue $green>{fmtMoneda(totalGeneral, monedaActiva)}</ResumenValue>
                </ResumenItem>
                <ResumenItem>
                  <ResumenLabel>Recibos emitidos</ResumenLabel>
                  <ResumenValue>{totalRecibos}</ResumenValue>
                </ResumenItem>
              </ResumenGrid>
            </SectionCard>
          </SideCol>
        </Grid>
      )}

      {/* PDF Preview */}
      <Dialog open={!!pdfUrl} onClose={cerrarPdf} maxWidth="xl" fullWidth
        PaperProps={{ sx: { height: "90vh" } }}>
        <DialogTitle sx={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
          <span style={{ display: "flex", alignItems: "center", gap: 8 }}>
            <PictureAsPdf />
            Vista previa — Cierre de Cobros
          </span>
          <Button size="small" variant="outlined" startIcon={<Icon icon="lucide:download" />}
            onClick={() => {
              const a = document.createElement("a");
              a.href = pdfUrl;
              a.download = `cierre-cobros_${fechaDesde}_${fechaHasta}.pdf`;
              a.click();
            }}>
            Descargar
          </Button>
        </DialogTitle>
        <DialogContent sx={{ p: 0 }}>
          {pdfUrl && (
            <iframe src={pdfUrl} title="pdf-cierre-cobros" style={{ width: "100%", height: "100%", border: 0 }} />
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={cerrarPdf}>Cerrar</Button>
        </DialogActions>
      </Dialog>
    </Container>
  );
}

const Container = styled.div`padding: 20px; display: flex; flex-direction: column; gap: 16px;`;
const Header = styled.div`display: flex; align-items: center; gap: 12px;`;
const BackBtn = styled.button`
  background: transparent; border: 1px solid ${({ theme }) => theme.color2};
  border-radius: 8px; padding: 6px 8px; cursor: pointer; color: ${({ theme }) => theme.text};
  &:hover { background: ${({ theme }) => theme.bg3}; }
  svg { width: 18px; height: 18px; }
`;
const TitleSection = styled.div`flex: 1;`;
const MainTitle = styled.h2`
  margin: 0; display: flex; align-items: center; gap: 8px; font-size: 20px;
  svg { color: #f88533; width: 24px; height: 24px; }
`;
const Subtitle = styled.p`margin: 0; font-size: 13px; opacity: 0.7;`;
const HeaderActions = styled.div`display: flex; gap: 8px; align-items: center;`;
const Filters = styled.div`
  display: flex; gap: 12px; flex-wrap: wrap; align-items: center;
  padding: 12px; border: 1px solid ${({ theme }) => theme.color2}; border-radius: 10px;
  background: ${({ theme }) => theme.bg2};
`;
const MultiMonedaBanner = styled.div`
  display: flex; align-items: flex-start; gap: 10px; padding: 10px 14px;
  border: 1px solid #f59e0b55; background: #f59e0b18; border-radius: 8px;
  font-size: 13px; color: ${({ theme }) => theme.text};
  svg { width: 20px; height: 20px; color: #f59e0b; flex-shrink: 0; margin-top: 1px; }
`;
const Loading = styled.div`display: flex; align-items: center; gap: 12px; padding: 40px; opacity: 0.7;`;
const Empty = styled.div`
  display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 60px; opacity: 0.5;
  svg { width: 48px; height: 48px; }
`;
const Grid = styled.div`
  display: grid; grid-template-columns: 2fr 1fr; gap: 16px;
  @media (max-width: 1100px) { grid-template-columns: 1fr; }
`;
const MainCol = styled.div`display: flex; flex-direction: column; gap: 16px;`;
const SideCol = styled.div`display: flex; flex-direction: column; gap: 16px;`;
const SectionCard = styled.div`
  border: 1px solid ${({ theme }) => theme.color2}; border-radius: 10px;
  background: ${({ theme }) => theme.bg2}; padding: 14px;
`;
const SectionTitle = styled.div`
  font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px;
  opacity: 0.75; margin-bottom: 10px;
`;
const ResumenGrid = styled.div`display: grid; grid-template-columns: 1fr 1fr; gap: 10px;`;
const ResumenItem = styled.div`display: flex; flex-direction: column; gap: 2px;`;
const ResumenLabel = styled.span`font-size: 11px; opacity: 0.6; text-transform: uppercase; letter-spacing: 0.4px;`;
const ResumenValue = styled.span`
  font-size: 18px; font-weight: 700;
  color: ${({ $green, theme }) => ($green ? "#22c55e" : theme.text)};
`;
