import { Icon } from "@iconify/react";
import { Box, Chip, Paper, Stack, TextField, Typography } from "@mui/material";
import { keepPreviousData, useQuery } from "@tanstack/react-query";
import { useMemo, useState } from "react";
import { useNavigate } from "react-router-dom";
import { getCarteraInm } from "../../api/inmobiliario.service";
import {
  descargarCSV, descargarExcel, EmptyState, ExportarMenuButton, ScreenGuia, StandardTable,
} from "../../components/_standards";
import { chipDe, fmtMoneda, INM_OPERACION_ESTADOS } from "../../components/_standards/enums";
import { BarraPagado, GrillaKpi, Kpi } from "../../components/organismos/inmobiliario/operaciones/OperacionUi";
import { num } from "../../components/organismos/inmobiliario/operaciones/operacionUtils";
import { ProyectoFiltro } from "../../components/organismos/inmobiliario/operaciones/ProyectoFiltro";
import { usePermission } from "../../hooks/usePermission";
import { fmtFechaCalendario, hoyISO } from "../../utils/fecha";

const GUIA_PASOS = [
  {
    icon: "mdi:scale-balance",
    color: "#60a5fa",
    titulo: "Qué se ve",
    desc: "Cada venta viva con saldo: lo vencido, los días de atraso y la mora estimada, calculados sobre el cronograma propio del vertical.",
  },
  {
    icon: "mdi:sort-descending",
    color: "#f87171",
    titulo: "Priorizá",
    desc: "La tabla arranca ordenada por días de atraso. Filtrá \"Sólo con atraso\" para la gestión diaria de cobro.",
  },
  {
    icon: "mdi:cash-register",
    color: "#34d399",
    titulo: "Cobrá",
    desc: "Abrí la operación para cobrar las cuotas: cada cobro emite su factura de contado.",
  },
];

const textoBusqueda = (f) =>
  [f.numero, f.unidad?.codigo, f.proyecto?.nombre, f.cliente?.nombre, f.cliente?.documento, f.cliente?.telefono]
    .filter(Boolean)
    .join(" ")
    .toLowerCase();

export function InmCartera() {
  const { can } = usePermission("INMOBILIARIO");
  const canRead = can("INM_COB_CARTERA_VER");
  const canVerOperacion = can("INM_OPE_OPERACION_VER");
  const navigate = useNavigate();

  const [proyectoId, setProyectoId] = useState("");
  const [soloAtraso, setSoloAtraso] = useState(false);
  const [buscar, setBuscar] = useState("");
  const [orden, setOrden] = useState({ key: "atraso", dir: "desc" });

  const { data, isLoading } = useQuery({
    queryKey: ["inmobiliario", "cartera", { proyectoId, soloAtraso }],
    queryFn: () =>
      getCarteraInm({ proyecto_id: proyectoId || undefined, solo_vencidas: soloAtraso ? "true" : undefined }),
    enabled: canRead,
    placeholderData: keepPreviousData,
    refetchOnWindowFocus: false,
  });

  const filas = useMemo(() => {
    const todas = data?.filas ?? [];
    const q = buscar.trim().toLowerCase();
    return q ? todas.filter((f) => textoBusqueda(f).includes(q)) : todas;
  }, [data, buscar]);
  const totales = Object.entries(data?.totales ?? {});

  if (!canRead) return null;

  const exportar = (fn) => {
    const encabezados = [
      "Operación", "Estado", "Proyecto", "Unidad", "Comprador", "Documento", "Teléfono", "Moneda", "Precio", "Cobrado", "Saldo",
      "Vencido", "Cuotas vencidas", "Días de atraso", "Mora estimada", "Próxima cuota", "Monto próxima", "% pagado",
    ];
    const datos = filas.map((f) => [
      f.numero,
      chipDe(INM_OPERACION_ESTADOS, f.estado).label,
      f.proyecto?.nombre ?? "",
      f.unidad?.codigo ?? "",
      f.cliente?.nombre ?? "",
      f.cliente?.documento ?? "",
      f.cliente?.telefono ?? "",
      f.moneda,
      num(f.precio),
      num(f.cobrado),
      num(f.saldo),
      num(f.vencido),
      num(f.cuotas_vencidas),
      num(f.dias_atraso_max),
      num(f.mora_estimada),
      f.proxima ? fmtFechaCalendario(f.proxima.fecha) : "",
      f.proxima ? num(f.proxima.saldo) : "",
      num(f.pct_pagado),
    ]);
    fn({ encabezados, filas: datos, archivo: `cartera_inmobiliaria_${hoyISO()}`, hoja: "Cartera" });
  };

  const hayFiltros = Boolean(proyectoId || soloAtraso || buscar.trim());

  return (
    <Box sx={{ p: { xs: 2, md: 3 } }}>
      <Stack spacing={2}>
        <ScreenGuia
          moduloPadre="Inmobiliario"
          intro="La deuda de las ventas inmobiliarias vive en su propio cronograma (las cuotas se facturan al cobrarse), por eso su cartera y su mora se ven acá y no en Cobranzas."
          pasos={GUIA_PASOS}
        />

        <Stack direction="row" spacing={1} alignItems="center" flexWrap="wrap" useFlexGap>
          <Typography variant="h6" sx={{ flex: 1 }}>
            Cartera inmobiliaria
          </Typography>
          <ExportarMenuButton disabled={!filas.length} onExcel={() => exportar(descargarExcel)} onCSV={() => exportar(descargarCSV)} />
        </Stack>

        <Paper variant="outlined" sx={{ p: 1.5 }}>
          <Stack direction="row" spacing={1.5} alignItems="center" flexWrap="wrap" useFlexGap>
            <TextField
              size="small"
              label="Buscar"
              placeholder="Operación, unidad, comprador o teléfono"
              value={buscar}
              onChange={(ev) => setBuscar(ev.target.value)}
              sx={{ flex: "1 1 240px", minWidth: 220 }}
            />
            <ProyectoFiltro value={proyectoId} onChange={setProyectoId} sx={{ flex: "1 1 220px" }} />
            <Chip
              icon={<Icon icon="mdi:clock-alert-outline" width={16} />}
              label="Sólo con atraso"
              color={soloAtraso ? "error" : "default"}
              variant={soloAtraso ? "filled" : "outlined"}
              onClick={() => setSoloAtraso((v) => !v)}
              aria-pressed={soloAtraso}
            />
          </Stack>
        </Paper>

        {totales.length > 0 && (
          <GrillaKpi min={260}>
            {totales.map(([codigo, t]) => (
              <Kpi
                key={codigo}
                titulo={`Saldo en ${codigo}`}
                icon="mdi:cash-multiple"
                valor={fmtMoneda(t.saldo, codigo)}
                color={num(t.vencido) > 0 ? "#ef4444" : "#22c55e"}
                nota={`${t.operaciones} ${t.operaciones === 1 ? "operación" : "operaciones"} · ${t.con_atraso} con atraso`}
              >
                <Stack direction="row" spacing={2} flexWrap="wrap" useFlexGap sx={{ mt: 0.5 }}>
                  <Box>
                    <Typography variant="caption" color="text.secondary">
                      Vencido
                    </Typography>
                    <Typography variant="body2" fontWeight={600} color={num(t.vencido) > 0 ? "error.main" : undefined}>
                      {fmtMoneda(t.vencido, codigo)}
                    </Typography>
                  </Box>
                  <Box>
                    <Typography variant="caption" color="text.secondary">
                      Mora estimada
                    </Typography>
                    <Typography variant="body2" fontWeight={600}>
                      {fmtMoneda(t.mora_estimada, codigo)}
                    </Typography>
                  </Box>
                </Stack>
              </Kpi>
            ))}
          </GrillaKpi>
        )}

        <StandardTable
          tableId="inm-cartera"
          data={filas}
          loading={isLoading}
          density="compact"
          sort={{ value: orden, onChange: setOrden }}
          onRowClick={canVerOperacion ? (f) => navigate(`/inmobiliario/operaciones/${f.id}`) : undefined}
          columns={[
            {
              key: "numero",
              label: "Operación",
              minWidth: 130,
              primary: true,
              sortable: true,
              render: (f) => (
                <Box>
                  <Typography variant="body2" fontWeight={600}>
                    {f.numero}
                  </Typography>
                  <Typography variant="caption" color="text.secondary">
                    {chipDe(INM_OPERACION_ESTADOS, f.estado).label}
                  </Typography>
                </Box>
              ),
            },
            {
              key: "proyecto",
              label: "Proyecto / unidad",
              minWidth: 170,
              wrap: true,
              sortable: true,
              sortValue: (f) => `${f.proyecto?.nombre ?? ""} ${f.unidad?.codigo ?? ""}`,
              render: (f) => (
                <Box>
                  <Typography variant="body2">{f.proyecto?.nombre ?? "—"}</Typography>
                  <Typography variant="caption" color="text.secondary">
                    {f.unidad?.codigo ?? "—"}
                  </Typography>
                </Box>
              ),
            },
            {
              key: "comprador",
              label: "Comprador",
              minWidth: 200,
              wrap: true,
              caption: true,
              sortable: true,
              sortValue: (f) => f.cliente?.nombre ?? "",
              render: (f) => (
                <Box>
                  <Typography variant="body2">{f.cliente?.nombre ?? "—"}</Typography>
                  {f.cliente?.telefono && (
                    <Typography variant="caption" color="text.secondary">
                      <Icon icon="mdi:phone-outline" width={12} style={{ verticalAlign: "-2px", marginRight: 2 }} />
                      {f.cliente.telefono}
                    </Typography>
                  )}
                </Box>
              ),
            },
            {
              key: "saldo",
              label: "Saldo",
              minWidth: 150,
              align: "right",
              highlight: true,
              sortable: true,
              sortValue: (f) => num(f.saldo),
              render: (f) => fmtMoneda(f.saldo, f.moneda),
            },
            {
              key: "vencido",
              label: "Vencido",
              minWidth: 140,
              align: "right",
              sortable: true,
              sortValue: (f) => num(f.vencido),
              render: (f) => (
                <Typography variant="body2" color={num(f.vencido) > 0 ? "error.main" : "text.secondary"} fontWeight={num(f.vencido) > 0 ? 600 : 400}>
                  {fmtMoneda(f.vencido, f.moneda)}
                </Typography>
              ),
            },
            {
              key: "cuotas_vencidas",
              label: "Cuotas venc.",
              minWidth: 90,
              align: "center",
              sortable: true,
              sortValue: (f) => num(f.cuotas_vencidas),
              render: (f) => f.cuotas_vencidas || "—",
            },
            {
              key: "atraso",
              label: "Atraso",
              minWidth: 100,
              align: "center",
              sortable: true,
              chip: true,
              sortValue: (f) => num(f.dias_atraso_max),
              render: (f) =>
                f.dias_atraso_max > 0 ? (
                  <Chip
                    size="small"
                    color={f.dias_atraso_max > 60 ? "error" : "warning"}
                    label={`${f.dias_atraso_max} ${f.dias_atraso_max === 1 ? "día" : "días"}`}
                  />
                ) : (
                  <Chip size="small" variant="outlined" color="success" label="Al día" />
                ),
            },
            {
              key: "mora",
              label: "Mora estimada",
              minWidth: 120,
              align: "right",
              sortable: true,
              sortValue: (f) => num(f.mora_estimada),
              render: (f) => (num(f.mora_estimada) > 0 ? fmtMoneda(f.mora_estimada, f.moneda) : "—"),
            },
            {
              key: "proxima",
              label: "Próxima cuota",
              minWidth: 140,
              sortable: true,
              sortValue: (f) => f.proxima?.fecha ?? null,
              render: (f) =>
                f.proxima ? (
                  <Box>
                    <Typography variant="body2">{fmtFechaCalendario(f.proxima.fecha)}</Typography>
                    <Typography variant="caption" color="text.secondary">
                      {fmtMoneda(f.proxima.saldo, f.moneda)}
                    </Typography>
                  </Box>
                ) : (
                  "—"
                ),
            },
            {
              key: "pagado",
              label: "% pagado",
              minWidth: 140,
              sortable: true,
              sortValue: (f) => num(f.pct_pagado),
              render: (f) => <BarraPagado pct={f.pct_pagado} ancho={70} />,
            },
          ]}
          emptyState={
            <EmptyState
              icon={hayFiltros ? "mdi:filter-remove-outline" : "mdi:check-decagram-outline"}
              title={
                soloAtraso && !buscar.trim()
                  ? "Ninguna venta tiene cuotas vencidas"
                  : hayFiltros
                    ? "Ninguna venta coincide con el filtro"
                    : "No hay ventas con saldo pendiente"
              }
              description="La cartera muestra las ventas vivas (reservadas, con boleto, escrituradas o entregadas) que todavía deben algo."
              ctaLabel={hayFiltros ? "Limpiar filtros" : undefined}
              ctaIcon="mdi:filter-remove-outline"
              onCta={() => {
                setProyectoId("");
                setSoloAtraso(false);
                setBuscar("");
              }}
            />
          }
        />
      </Stack>
    </Box>
  );
}

export default InmCartera;
