import { useEffect, useMemo, useState } from "react";
import {
  Alert,
  Autocomplete,
  Box,
  Button,
  Checkbox,
  Chip,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  MenuItem,
  Paper,
  Stack,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
  TextField,
  Typography,
} from "@mui/material";
import { Icon } from "@iconify/react";
import { toast } from "sonner";
import {
  COB_GESTION_RESULTADO,
  COB_GESTION_RESULTADO_META,
  COB_GESTION_TIPO,
  COB_GESTION_TIPO_META,
} from "../../_standards/enums/estados";
import { MonedaInput } from "../../_standards";
import { createGestion } from "../../../api/cobranzas.service";
import { getCuotasPendientes } from "../../../api/cobros.service";
import { searchClientes } from "../../../api/clientes.service";
import { fmtFechaCalendario } from "../../../utils/fecha";
import { FacturaCuotasSelector } from "../promesas/FacturaCuotasSelector";

const TIPOS = Object.values(COB_GESTION_TIPO);
const RESULTADOS = Object.values(COB_GESTION_RESULTADO);

const TIPO_EVIDENCIA = [
  { value: "VERBAL", label: "Verbal", icon: "mdi:account-voice" },
  { value: "WHATSAPP", label: "WhatsApp", icon: "mdi:whatsapp" },
  { value: "EMAIL", label: "Email", icon: "mdi:email" },
  { value: "DOCUMENTO_FIRMADO", label: "Documento firmado", icon: "mdi:file-sign" },
];

const PAGADOR_TIPO = [
  { value: "CLIENTE", label: "Cliente" },
  { value: "GARANTE", label: "Garante" },
  { value: "TERCERO", label: "Tercero" },
];

const pad = (v, n) => String(v ?? "").padStart(n, "0");
const formatNroFactura = (fc) =>
  fc ? `${pad(fc.dest, 3)}-${pad(fc.dpunexp, 3)}-${pad(fc.dnumdoc, 7)}` : "—";
const fmtNum = (v) => new Intl.NumberFormat("es-PY").format(Math.round(Number(v) || 0));
const hoyMas7 = () => {
  const d = new Date();
  d.setDate(d.getDate() + 7);
  return d.toISOString().split("T")[0];
};
const diasVencidoCuota = (fechaVto) => {
  if (!fechaVto) return 0;
  const d = new Date(fechaVto);
  if (Number.isNaN(d.getTime())) return 0;
  return Math.floor((Date.now() - d.getTime()) / 86400000);
};

export function RegistrarGestionModal({
  open,
  onClose,
  cliente,
  factura,
  cobrador,
  onSuccess,
}) {
  const [tipoGestion, setTipoGestion] = useState("LLAMADA");
  const [resultado, setResultado] = useState("PROMESA_PAGO");
  const [observacion, setObservacion] = useState("");
  const [proximaAccion, setProximaAccion] = useState("");
  const [proximaFecha, setProximaFecha] = useState("");
  const [loading, setLoading] = useState(false);

  // ── Promesa enriquecida ───────────────────────────────────────────────────
  const [promesaFecha, setPromesaFecha] = useState(hoyMas7);
  const [promesaMonto, setPromesaMonto] = useState(0);
  const [montoEditado, setMontoEditado] = useState(false);
  const [tipoEvidencia, setTipoEvidencia] = useState("VERBAL");
  const [pagadorTipo, setPagadorTipo] = useState("CLIENTE");
  const [pagadorCliente, setPagadorCliente] = useState(null);
  const [pagadorOpts, setPagadorOpts] = useState([]);
  const [pagadorBuscando, setPagadorBuscando] = useState(false);
  const [cuotas, setCuotas] = useState([]);
  const [seleccionCuotas, setSeleccionCuotas] = useState({});
  const [loadingCuotas, setLoadingCuotas] = useState(false);

  const requierePromesa = resultado === "PROMESA_PAGO";

  useEffect(() => {
    if (!open) return;
    setTipoGestion("LLAMADA");
    setResultado("PROMESA_PAGO");
    setObservacion("");
    setProximaAccion("");
    setProximaFecha("");
    setPromesaFecha(hoyMas7());
    setPromesaMonto(0);
    setMontoEditado(false);
    setTipoEvidencia("VERBAL");
    setPagadorTipo("CLIENTE");
    setPagadorCliente(null);
    setSeleccionCuotas({});
  }, [open]);

  // Cargar cuotas pendientes cuando se necesita el form de promesa
  useEffect(() => {
    if (!open || !requierePromesa || !cliente?.id) return;
    let cancel = false;
    setLoadingCuotas(true);
    setCuotas([]);
    setSeleccionCuotas({});
    (async () => {
      try {
        const data = await getCuotasPendientes(cliente.id);
        if (cancel) return;
        const lista = Array.isArray(data) ? data : data?.data || [];
        // Si vino una factura específica, filtrar a sus cuotas y pre-seleccionar
        let filtradas = lista;
        const preSel = {};
        if (factura?.id) {
          filtradas = lista.filter((c) => c.factura_cab_id === factura.id);
          filtradas.forEach((c) => { preSel[c.id] = true; });
        }
        setCuotas(filtradas);
        setSeleccionCuotas(preSel);
      } catch {
        if (!cancel) toast.error("No se pudieron cargar las cuotas");
      } finally {
        if (!cancel) setLoadingCuotas(false);
      }
    })();
    return () => { cancel = true; };
  }, [open, requierePromesa, cliente?.id, factura?.id]);

  // Buscar garante/tercero
  useEffect(() => {
    if (pagadorTipo === "CLIENTE") return;
    if (!pagadorOpts.length && !pagadorBuscando) return;
  }, [pagadorTipo]);

  const buscarPagador = (q) => {
    if (!q || q.length < 2) return;
    setPagadorBuscando(true);
    const t = setTimeout(async () => {
      try {
        const res = await searchClientes(q, 15);
        setPagadorOpts(Array.isArray(res) ? res : res?.data || []);
      } catch {/* silencioso */}
      finally { setPagadorBuscando(false); }
    }, 300);
    return () => clearTimeout(t);
  };

  const cuotasSeleccionadas = useMemo(
    () => cuotas.filter((c) => seleccionCuotas[c.id]),
    [cuotas, seleccionCuotas],
  );
  const saldoSeleccionado = useMemo(
    () => cuotasSeleccionadas.reduce((a, c) => a + (Number(c.saldo_pendiente ?? c.dmoncuota) || 0), 0),
    [cuotasSeleccionadas],
  );

  // Auto-actualizar monto si no fue editado
  useEffect(() => {
    if (!montoEditado) setPromesaMonto(Math.round(saldoSeleccionado));
  }, [saldoSeleccionado, montoEditado]);

  const toggleCuota = (id) => setSeleccionCuotas((s) => ({ ...s, [id]: !s[id] }));
  const seleccionarVencidas = () => {
    const next = { ...seleccionCuotas };
    cuotas.forEach((c) => { if (diasVencidoCuota(c.dvenccuo) > 0) next[c.id] = true; });
    setSeleccionCuotas(next);
  };
  const toggleTodas = () => {
    const todasSel = cuotas.length > 0 && cuotas.every((c) => seleccionCuotas[c.id]);
    const next = {};
    if (!todasSel) cuotas.forEach((c) => { next[c.id] = true; });
    setSeleccionCuotas(next);
  };

  const clienteLabel = useMemo(() => {
    if (!cliente) return "—";
    return (
      cliente?.personas?.razon_social ||
      cliente?.razon_social ||
      cliente?.nombre_fantasia ||
      "Cliente sin nombre"
    );
  }, [cliente]);

  const clienteSubLabel = useMemo(() => {
    if (!cliente) return null;
    return (
      cliente?.personas?.ruc ||
      cliente?.ruc ||
      cliente?.personas?.nro_documento ||
      cliente?.nro_documento ||
      null
    );
  }, [cliente]);

  const handleSubmit = async () => {
    if (!cliente?.id) return toast.error("Cliente no definido");

    if (requierePromesa) {
      if (cuotasSeleccionadas.length === 0) {
        return toast.error("Seleccioná al menos una cuota a comprometer");
      }
      if (!promesaFecha) return toast.error("Indicá la fecha prometida");
      if (Number(promesaMonto) <= 0) return toast.error("Indicá un monto prometido");
      if (pagadorTipo !== "CLIENTE" && !pagadorCliente?.id) {
        return toast.error("Indicá el garante/tercero pagador");
      }
    }

    setLoading(true);
    try {
      const payload = {
        cliente_id: cliente.id,
        factura_cab_id: factura?.id ?? undefined,
        cobrador_id: cobrador?.id ?? undefined,
        tipo_gestion: tipoGestion,
        resultado,
        observacion: observacion.trim() || undefined,
        proxima_accion: proximaAccion.trim() || undefined,
        proxima_fecha: proximaFecha || undefined,
      };

      if (requierePromesa) {
        payload.promesa_fecha = promesaFecha;
        payload.promesa_monto = Number(promesaMonto);
        payload.promesa_cuota_ids = cuotasSeleccionadas.map((c) => c.id);
        payload.promesa_tipo_evidencia = tipoEvidencia;
        payload.promesa_pagador_tipo = pagadorTipo;
        if (pagadorTipo !== "CLIENTE") {
          payload.promesa_pagador_cliente_id = pagadorCliente.id;
        }
      }

      await createGestion(payload);
      toast.success(
        requierePromesa
          ? `Gestión + ${cuotasSeleccionadas.length} promesa(s) registradas`
          : "Gestión registrada",
      );
      onSuccess?.();
      onClose?.();
    } catch (e) {
      toast.error(e?.response?.data?.message || "No se pudo registrar la gestión");
    } finally {
      setLoading(false);
    }
  };

  return (
    <Dialog open={open} onClose={loading ? undefined : onClose} maxWidth={requierePromesa ? "md" : "sm"} fullWidth>
      <DialogTitle sx={{ display: "flex", alignItems: "center", gap: 1 }}>
        <Icon icon="mdi:clipboard-check-outline" width={22} />
        Registrar gestión de cobranza
      </DialogTitle>
      <DialogContent dividers>
        <Stack spacing={2} sx={{ pt: 1 }}>
          <Alert severity="info" variant="outlined" icon={<Icon icon="mdi:account" />}>
            <Typography variant="body2">
              <strong>Cliente:</strong> {clienteLabel}
              {clienteSubLabel && (
                <Typography component="span" variant="caption" sx={{ ml: 1, opacity: 0.75 }}>
                  ({clienteSubLabel})
                </Typography>
              )}
            </Typography>
            {factura && (
              <Typography variant="body2">
                <strong>Factura:</strong> {formatNroFactura(factura)}
              </Typography>
            )}
          </Alert>

          <Stack direction={{ xs: "column", sm: "row" }} spacing={2}>
            <TextField
              select
              label="Tipo de gestión"
              value={tipoGestion}
              onChange={(e) => setTipoGestion(e.target.value)}
              fullWidth
              size="small"
            >
              {TIPOS.map((t) => (
                <MenuItem key={t} value={t}>
                  {COB_GESTION_TIPO_META[t]?.label ?? t}
                </MenuItem>
              ))}
            </TextField>
            <TextField
              select
              label="Resultado"
              value={resultado}
              onChange={(e) => setResultado(e.target.value)}
              fullWidth
              size="small"
            >
              {RESULTADOS.map((r) => (
                <MenuItem key={r} value={r}>
                  {COB_GESTION_RESULTADO_META[r]?.label ?? r}
                </MenuItem>
              ))}
            </TextField>
          </Stack>

          <TextField
            label="Observación"
            value={observacion}
            onChange={(e) => setObservacion(e.target.value)}
            multiline
            minRows={2}
            fullWidth
            size="small"
            placeholder="Detalle del contacto, con quién hablaste, qué dijo el cliente…"
          />

          <Stack direction={{ xs: "column", sm: "row" }} spacing={2}>
            <TextField
              label="Próxima acción"
              value={proximaAccion}
              onChange={(e) => setProximaAccion(e.target.value)}
              placeholder="Ej: re-llamar, visita, derivar"
              fullWidth
              size="small"
            />
            <TextField
              type="date"
              label="Próxima fecha"
              value={proximaFecha}
              onChange={(e) => setProximaFecha(e.target.value)}
              InputLabelProps={{ shrink: true }}
              fullWidth
              size="small"
            />
          </Stack>

          {requierePromesa && (
            <>
              <Box sx={{ borderTop: 1, borderColor: "divider", pt: 2 }}>
                <Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 1 }}>
                  <Icon icon="mdi:handshake" width={18} color="#a855f7" />
                  <Typography variant="subtitle2" fontWeight={700}>
                    Detalle del compromiso de pago
                  </Typography>
                </Stack>

                <Stack direction="row" alignItems="center" spacing={1} sx={{ mb: 1 }}>
                  <Typography variant="caption" color="text.secondary">
                    Cuotas a comprometer
                  </Typography>
                  <Box flex={1} />
                  {cuotas.length > 0 && (
                    <>
                      <Button size="small" onClick={seleccionarVencidas}>Solo vencidas</Button>
                      <Button size="small" onClick={toggleTodas}>
                        {cuotas.every((c) => seleccionCuotas[c.id]) ? "Limpiar" : "Todas"}
                      </Button>
                    </>
                  )}
                </Stack>

                {loadingCuotas ? (
                  <Box display="flex" justifyContent="center" py={3}>
                    <CircularProgress size={24} />
                  </Box>
                ) : cuotas.length === 0 ? (
                  <Alert severity="info">El cliente no tiene cuotas pendientes.</Alert>
                ) : (
                  <FacturaCuotasSelector
                    cuotas={cuotas}
                    seleccion={seleccionCuotas}
                    onToggleCuota={toggleCuota}
                    compact
                  />
                )}

                <Stack direction={{ xs: "column", sm: "row" }} spacing={2} sx={{ mt: 2 }}>
                  <TextField
                    type="date"
                    label="Fecha prometida"
                    value={promesaFecha}
                    onChange={(e) => setPromesaFecha(e.target.value)}
                    InputLabelProps={{ shrink: true }}
                    fullWidth
                    size="small"
                    required
                  />
                  <MonedaInput
                    label="Monto prometido"
                    value={promesaMonto}
                    onChange={(v) => { setMontoEditado(true); setPromesaMonto(v); }}
                    moneda={factura?.moneda}
                    fullWidth
                    helperText={
                      cuotasSeleccionadas.length > 1
                        ? "Si difiere del saldo total, se prorratea entre cuotas"
                        : ""
                    }
                  />
                </Stack>

                <Stack direction={{ xs: "column", sm: "row" }} spacing={2} sx={{ mt: 2 }}>
                  <TextField
                    select
                    label="Tipo de evidencia"
                    value={tipoEvidencia}
                    onChange={(e) => setTipoEvidencia(e.target.value)}
                    fullWidth
                    size="small"
                    helperText="Cómo se documentó el compromiso"
                  >
                    {TIPO_EVIDENCIA.map((opt) => (
                      <MenuItem key={opt.value} value={opt.value}>
                        <Stack direction="row" alignItems="center" spacing={1}>
                          <Icon icon={opt.icon} />
                          <span>{opt.label}</span>
                        </Stack>
                      </MenuItem>
                    ))}
                  </TextField>
                  <TextField
                    select
                    label="Pagador"
                    value={pagadorTipo}
                    onChange={(e) => {
                      setPagadorTipo(e.target.value);
                      if (e.target.value === "CLIENTE") setPagadorCliente(null);
                    }}
                    fullWidth
                    size="small"
                    helperText="Quién se compromete al pago"
                  >
                    {PAGADOR_TIPO.map((opt) => (
                      <MenuItem key={opt.value} value={opt.value}>{opt.label}</MenuItem>
                    ))}
                  </TextField>
                </Stack>

                {pagadorTipo !== "CLIENTE" && (
                  <Autocomplete
                    sx={{ mt: 2 }}
                    size="small"
                    value={pagadorCliente}
                    onChange={(_, v) => setPagadorCliente(v)}
                    onInputChange={(_, v) => buscarPagador(v)}
                    options={pagadorOpts}
                    loading={pagadorBuscando}
                    filterOptions={(x) => x}
                    getOptionLabel={(o) =>
                      o?.personas?.razon_social || o?.nombre_fantasia || o?.personas?.ruc || ""
                    }
                    isOptionEqualToValue={(a, b) => a?.id === b?.id}
                    renderInput={(p) => (
                      <TextField
                        {...p}
                        label={pagadorTipo === "GARANTE" ? "Garante" : "Tercero pagador"}
                        placeholder="Razón social, RUC o CI…"
                      />
                    )}
                  />
                )}

                <Alert severity="info" sx={{ mt: 2 }} icon={<Icon icon="mdi:information" />}>
                  {cuotasSeleccionadas.length > 1
                    ? `Se crearán ${cuotasSeleccionadas.length} promesas (una por cuota) con la misma fecha y evidencia.`
                    : "Se enviará recordatorio automático un día antes de la fecha prometida."}
                </Alert>
              </Box>
            </>
          )}
        </Stack>
      </DialogContent>
      <DialogActions sx={{ justifyContent: "space-between", px: 3 }}>
        {requierePromesa ? (
          <Box>
            <Typography variant="caption" color="text.secondary">
              Saldo seleccionado
            </Typography>
            <Typography variant="subtitle1" fontWeight={700} color={saldoSeleccionado > 0 ? "warning.main" : "text.secondary"}>
              Gs. {fmtNum(saldoSeleccionado)}
              <Typography component="span" variant="caption" color="text.secondary" sx={{ ml: 1 }}>
                ({cuotasSeleccionadas.length} cuota{cuotasSeleccionadas.length === 1 ? "" : "s"})
              </Typography>
            </Typography>
          </Box>
        ) : <Box />}
        <Stack direction="row" spacing={1}>
          <Button onClick={onClose} disabled={loading}>Cancelar</Button>
          <Button
            onClick={handleSubmit}
            disabled={loading || (requierePromesa && cuotasSeleccionadas.length === 0)}
            variant="contained"
            startIcon={<Icon icon={requierePromesa ? "mdi:handshake" : "mdi:clipboard-check"} />}
          >
            {loading
              ? "Registrando…"
              : requierePromesa
                ? "Registrar gestión + promesa"
                : "Registrar gestión"}
          </Button>
        </Stack>
      </DialogActions>
    </Dialog>
  );
}

export default RegistrarGestionModal;
