import { Add, Delete, Edit, Home, ManageAccounts, People, Star } from "@mui/icons-material";
import {
  Autocomplete,
  Box,
  Button,
  Chip,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  Divider,
  IconButton,
  List,
  ListItem,
  ListItemText,
  TextField,
  Tooltip,
  Typography,
} from "@mui/material";
import { getSupervisoresActivos } from "../../../api/supervisores.service";
import { getCobradoresActivos, getVendedoresActivos } from "../../../api/vendedores-cobradores.service";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import {
  createDireccion,
  deleteDireccion,
  getDirecciones,
  updateDireccion,
} from "../../../api/clientes.service";
import { useReferencialesQuery } from "../../../tanstack/ReferencialesStack";
import { useSubmodulo } from "../../../hooks/useSubmodulo.js";

const EMPTY_FORM = {
  label: "",
  direccion: "",
  nro: "0",
  referencia: "",
  pais_id: null,
  departamento_id: null,
  distrito_id: null,
  ciudad_id: null,
  es_principal: false,
  vendedor_id: null,
  cobrador_id: null,
  supervisor_id: null,
};

export function ClienteDireccionesPanel({ cliente }) {
  const queryClient = useQueryClient();
  const { hasAccess: tieneVendedores } = useSubmodulo("VENTAS_VENDEDOR_COBRADOR");
  const [formOpen, setFormOpen] = useState(false);
  const [editando, setEditando] = useState(null);
  const [form, setForm] = useState(EMPTY_FORM);
  const [deleteConfirm, setDeleteConfirm] = useState(null);

  const { data: referenciales } = useReferencialesQuery();
  const paises = referenciales?.geografica?.paises || [];
  const departamentos = referenciales?.geografica?.departamentos || [];
  const distritos = referenciales?.geografica?.distritos || [];
  const ciudades = referenciales?.geografica?.ciudades || [];

  const paraguay = useMemo(
    () =>
      paises.find(
        (p) =>
          p.codigo === "PRY" ||
          p.descripcion?.toLowerCase() === "paraguay",
      ),
    [paises],
  );
  const selectedPais = useMemo(
    () => paises.find((p) => p.id === form.pais_id) || null,
    [paises, form.pais_id],
  );
  const isParaguay =
    !!selectedPais &&
    (selectedPais.codigo === "PRY" ||
      selectedPais.descripcion?.toLowerCase() === "paraguay");

  const { data: vendedoresActivos = [] } = useQuery({ queryKey: ["vendedores-activos"], queryFn: getVendedoresActivos, enabled: tieneVendedores });
  const { data: cobradoresActivos = [] } = useQuery({ queryKey: ["cobradores-activos"], queryFn: getCobradoresActivos, enabled: tieneVendedores });
  const { data: supervisoresActivos = [] } = useQuery({ queryKey: ["supervisores-activos"], queryFn: getSupervisoresActivos, enabled: tieneVendedores });

  const { data: direcciones = [], isLoading } = useQuery({
    queryKey: ["cliente-direcciones", cliente?.id],
    queryFn: () => getDirecciones(cliente.id),
    enabled: !!cliente?.id,
  });

  const invalidate = () =>
    queryClient.invalidateQueries({ queryKey: ["cliente-direcciones", cliente?.id] });

  const createMut = useMutation({
    mutationFn: (data) => createDireccion(cliente.id, data),
    onSuccess: () => { toast.success("Dirección agregada"); invalidate(); setFormOpen(false); },
    onError: () => toast.error("Error al guardar dirección"),
  });

  const updateMut = useMutation({
    mutationFn: ({ id, data }) => updateDireccion(cliente.id, id, data),
    onSuccess: () => { toast.success("Dirección actualizada"); invalidate(); setFormOpen(false); },
    onError: () => toast.error("Error al actualizar dirección"),
  });

  const deleteMut = useMutation({
    mutationFn: (id) => deleteDireccion(cliente.id, id),
    onSuccess: () => { toast.success("Dirección eliminada"); invalidate(); setDeleteConfirm(null); },
    onError: () => toast.error("Error al eliminar dirección"),
  });

  const openNew = () => {
    setEditando(null);
    setForm({ ...EMPTY_FORM, pais_id: paraguay?.id || null, es_principal: true });
    setFormOpen(true);
  };

  const openEdit = (dir) => {
    setEditando(dir.id);
    setForm({
      label: dir.label || "",
      direccion: dir.direccion || "",
      nro: dir.nro || "0",
      referencia: dir.referencia || "",
      pais_id: dir.pais_id || null,
      departamento_id: dir.departamento_id || null,
      distrito_id: dir.distrito_id || null,
      ciudad_id: dir.ciudad_id || null,
      es_principal: dir.es_principal || false,
      vendedor_id: dir.vendedor_id || null,
      cobrador_id: dir.cobrador_id || null,
      supervisor_id: dir.supervisor_id || null,
    });
    setFormOpen(true);
  };

  const [attemptedSave, setAttemptedSave] = useState(false);

  const errores = useMemo(() => {
    const e = {};
    if (!form.pais_id) e.pais_id = "Elegí un país";
    // Depto / distrito / ciudad van "de la mano" en Paraguay: o los tres seteados o ninguno.
    // El usuario puede dejar la ubicación completamente vacía (dirección textual libre alcanza)
    // o seleccionar toda la cadena en orden (depto → distrito → ciudad).
    if (isParaguay) {
      const algunoSeteado =
        !!form.departamento_id || !!form.distrito_id || !!form.ciudad_id;
      if (algunoSeteado) {
        if (!form.departamento_id) e.departamento_id = "Elegí el departamento primero";
        if (!form.distrito_id) e.distrito_id = "Elegí el distrito";
        if (!form.ciudad_id) e.ciudad_id = "Elegí la ciudad";
      }
    }
    // Si la ubicación quedó completa (depto + distrito + ciudad), la dirección textual
    // pasa a ser obligatoria — no tiene sentido registrar "ciudad X" sin saber la calle.
    const ubicacionCompleta =
      isParaguay &&
      !!form.departamento_id &&
      !!form.distrito_id &&
      !!form.ciudad_id;
    if (ubicacionCompleta && !form.direccion?.trim()) {
      e.direccion = "Cargá la calle / dirección concreta del cliente";
    }
    return e;
  }, [form, isParaguay]);
  const tieneErrores = Object.keys(errores).length > 0;

  // Reset del flag al abrir/cerrar el diálogo
  useEffect(() => {
    if (!formOpen) setAttemptedSave(false);
  }, [formOpen]);

  const handleSave = () => {
    setAttemptedSave(true);
    if (tieneErrores) {
      toast.error("Completá los campos obligatorios antes de guardar");
      return;
    }
    const payload = {
      ...form,
      pais_id: form.pais_id || null,
      departamento_id: isParaguay ? form.departamento_id || null : null,
      distrito_id: isParaguay ? form.distrito_id || null : null,
      ciudad_id: isParaguay ? form.ciudad_id || null : null,
    };
    if (editando) updateMut.mutate({ id: editando, data: payload });
    else createMut.mutate(payload);
  };

  const isSaving = createMut.isPending || updateMut.isPending;
  // Un error se muestra solo cuando el usuario intentó guardar (evita ruido visual al abrir el form).
  const err = (campo) => attemptedSave && errores[campo];

  const departamentosFiltrados = useMemo(() => {
    if (!isParaguay) return [];
    return selectedPais
      ? departamentos.filter((d) => !d.pais_id || d.pais_id === selectedPais.id)
      : departamentos;
  }, [departamentos, isParaguay, selectedPais]);

  const distFiltrados = useMemo(() => {
    if (!isParaguay || !form.departamento_id) return [];
    return distritos.filter((d) => d.departamento_id === form.departamento_id);
  }, [distritos, isParaguay, form.departamento_id]);

  const ciudadesFiltradas = useMemo(() => {
    if (!isParaguay || !form.distrito_id) return [];
    return ciudades.filter((c) => c.distrito_id === form.distrito_id);
  }, [ciudades, isParaguay, form.distrito_id]);

  // Si el país deja de ser Paraguay, limpiar geografía local.
  useEffect(() => {
    if (!formOpen) return;
    if (isParaguay) return;
    if (form.departamento_id || form.distrito_id || form.ciudad_id) {
      setForm((f) => ({ ...f, departamento_id: null, distrito_id: null, ciudad_id: null }));
    }
  }, [isParaguay, formOpen, form.departamento_id, form.distrito_id, form.ciudad_id]);

  // Si el departamento se vacía o cambia, limpiar distrito y ciudad inválidos.
  useEffect(() => {
    if (!formOpen || !isParaguay) return;
    if (!form.departamento_id && (form.distrito_id || form.ciudad_id)) {
      setForm((f) => ({ ...f, distrito_id: null, ciudad_id: null }));
      return;
    }
    if (form.distrito_id && !distFiltrados.some((d) => d.id === form.distrito_id)) {
      setForm((f) => ({ ...f, distrito_id: null, ciudad_id: null }));
    }
  }, [formOpen, isParaguay, form.departamento_id, form.distrito_id, form.ciudad_id, distFiltrados]);

  // Si el distrito se vacía o cambia, limpiar ciudad inválida.
  useEffect(() => {
    if (!formOpen || !isParaguay) return;
    if (!form.distrito_id && form.ciudad_id) {
      setForm((f) => ({ ...f, ciudad_id: null }));
      return;
    }
    if (form.ciudad_id && !ciudadesFiltradas.some((c) => c.id === form.ciudad_id)) {
      setForm((f) => ({ ...f, ciudad_id: null }));
    }
  }, [formOpen, isParaguay, form.distrito_id, form.ciudad_id, ciudadesFiltradas]);

  const formatAddr = (dir) => {
    const parts = [dir.direccion, dir.nro, dir.distritos?.descripcion, dir.ciudades?.descripcion].filter(Boolean);
    return parts.join(", ") || "Sin detalle";
  };

  if (!cliente?.id) {
    return (
      <Box textAlign="center" py={4}>
        <Typography variant="body2" color="text.secondary">
          Guarde el cliente primero para gestionar sus direcciones.
        </Typography>
      </Box>
    );
  }

  return (
    <>
      {isLoading ? (
        <Box display="flex" justifyContent="center" py={4}>
          <CircularProgress size={28} />
        </Box>
      ) : (
        <>
          <List disablePadding>
            {direcciones.length === 0 ? (
              <Box textAlign="center" py={3}>
                <Typography variant="body2" color="text.secondary">
                  Sin direcciones registradas
                </Typography>
              </Box>
            ) : (
              direcciones.map((dir, idx) => (
                <Box key={dir.id}>
                  {idx > 0 && <Divider />}
                  <ListItem
                    secondaryAction={
                      <Box display="flex" gap={0.5}>
                        <Tooltip title="Editar">
                          <IconButton size="small" onClick={() => openEdit(dir)}>
                            <Edit fontSize="small" />
                          </IconButton>
                        </Tooltip>
                        <Tooltip title="Eliminar">
                          <IconButton size="small" color="error" onClick={() => setDeleteConfirm(dir.id)}>
                            <Delete fontSize="small" />
                          </IconButton>
                        </Tooltip>
                      </Box>
                    }
                  >
                    <ListItemText
                      primary={
                        <Box display="flex" alignItems="center" gap={1} flexWrap="wrap">
                          {dir.label && (
                            <Typography variant="body2" fontWeight={600}>{dir.label}</Typography>
                          )}
                          {dir.es_principal && (
                            <Chip icon={<Star sx={{ fontSize: 12 }} />} label="Principal" size="small" color="primary" variant="outlined" sx={{ height: 18, fontSize: "0.65rem" }} />
                          )}
                        </Box>
                      }
                      secondary={
                        <Box>
                          <span>{formatAddr(dir)}</span>
                          {tieneVendedores && (dir.vendedor || dir.cobrador || dir.supervisor) && (
                            <Box display="flex" gap={0.5} flexWrap="wrap" mt={0.5}>
                              {dir.vendedor && (
                                <Chip icon={<People sx={{ fontSize: 12 }} />} label={`V: ${dir.vendedor.nombre}`} size="small" sx={{ height: 18, fontSize: "0.65rem" }} />
                              )}
                              {dir.cobrador && (
                                <Chip icon={<People sx={{ fontSize: 12 }} />} label={`C: ${dir.cobrador.nombre}`} size="small" sx={{ height: 18, fontSize: "0.65rem" }} />
                              )}
                              {dir.supervisor && (
                                <Chip icon={<ManageAccounts sx={{ fontSize: 12 }} />} label={`Sup: ${dir.supervisor.nombre}`} size="small" color="secondary" sx={{ height: 18, fontSize: "0.65rem" }} />
                              )}
                            </Box>
                          )}
                        </Box>
                      }
                    />
                  </ListItem>
                </Box>
              ))
            )}
          </List>
          <Box mt={1}>
            <Button startIcon={<Add />} onClick={openNew} variant="outlined" size="small">
              Agregar dirección
            </Button>
          </Box>
        </>
      )}

      {/* Subformulario agregar/editar */}
      <Dialog open={formOpen} onClose={() => setFormOpen(false)} maxWidth="sm" fullWidth>
        <DialogTitle sx={{ pb: 1.5 }}>
          {editando ? "Editar dirección" : "Nueva dirección"}
        </DialogTitle>
        {/* pt suficiente para que el label flotante del primer TextField no quede tapado
            por el DialogTitle cuando el usuario tipea (MUI shrink lo lleva hacia arriba) */}
        <DialogContent sx={{ display: "flex", flexDirection: "column", gap: 2, pt: "24px !important" }}>
          <TextField
            label="Identificador (ej: Sucursal 1)"
            size="small"
            value={form.label}
            onChange={(e) => setForm((f) => ({ ...f, label: e.target.value }))}
            placeholder="Casa, Sucursal 1, Depósito..."
            fullWidth
            InputLabelProps={{ shrink: true }}
          />
          <Box display="flex" gap={1}>
            <TextField
              label="Dirección"
              size="small"
              value={form.direccion}
              onChange={(e) => setForm((f) => ({ ...f, direccion: e.target.value }))}
              fullWidth
              placeholder="Ej: Av. Mariscal López 1234"
              error={!!err("direccion")}
              helperText={err("direccion") || undefined}
            />
            <TextField
              label="Nro."
              size="small"
              value={form.nro}
              onChange={(e) => setForm((f) => ({ ...f, nro: e.target.value }))}
              sx={{ width: 90 }}
            />
          </Box>
          <TextField
            label="Referencia"
            size="small"
            value={form.referencia}
            onChange={(e) => setForm((f) => ({ ...f, referencia: e.target.value }))}
            multiline
            rows={2}
            fullWidth
          />
          <Autocomplete
            size="small"
            options={paises}
            getOptionLabel={(o) => o.descripcion || ""}
            value={paises.find((p) => p.id === form.pais_id) || null}
            onChange={(_, v) => setForm((f) => ({ ...f, pais_id: v?.id || null, departamento_id: null, distrito_id: null, ciudad_id: null }))}
            renderInput={(params) => (
              <TextField
                {...params}
                label="País"
                required
                error={!!err("pais_id")}
                helperText={err("pais_id") || undefined}
              />
            )}
          />
          {isParaguay && (
            <Box
              sx={{
                p: 1,
                borderRadius: 1,
                bgcolor: "action.hover",
                display: "flex",
                alignItems: "center",
                gap: 0.75,
              }}
            >
              <Typography variant="caption" color="text.secondary" sx={{ lineHeight: 1.35 }}>
                <b>Ubicación (opcional):</b> elegí en orden{" "}
                <b>1.&nbsp;Departamento</b>&nbsp;→&nbsp;<b>2.&nbsp;Distrito</b>&nbsp;→&nbsp;<b>3.&nbsp;Ciudad</b>. Los
                distritos y ciudades se filtran según el nivel superior. Si no querés cargar
                ubicación, dejalos vacíos.
              </Typography>
            </Box>
          )}
          <Autocomplete
            size="small"
            options={departamentosFiltrados}
            getOptionLabel={(o) => o.descripcion || ""}
            value={departamentos.find((d) => d.id === form.departamento_id) || null}
            onChange={(_, v) => setForm((f) => ({ ...f, departamento_id: v?.id || null, distrito_id: null, ciudad_id: null }))}
            disabled={!isParaguay}
            renderInput={(params) => (
              <TextField
                {...params}
                label="1. Departamento"
                error={!!err("departamento_id")}
                helperText={
                  err("departamento_id") ||
                  (!isParaguay
                    ? "Solo aplica para Paraguay"
                    : "Empezá por acá si querés registrar la ubicación.")
                }
              />
            )}
          />
          <Box display="flex" gap={1}>
            <Autocomplete
              size="small"
              options={distFiltrados}
              getOptionLabel={(o) => o.descripcion || ""}
              value={distritos.find((d) => d.id === form.distrito_id) || null}
              onChange={(_, v) => setForm((f) => ({ ...f, distrito_id: v?.id || null, ciudad_id: null }))}
              disabled={!isParaguay || !form.departamento_id}
              renderInput={(params) => (
                <TextField
                  {...params}
                  label="2. Distrito"
                  error={!!err("distrito_id")}
                  helperText={
                    err("distrito_id") ||
                    (isParaguay && !form.departamento_id ? "Elegí antes el departamento" : undefined)
                  }
                />
              )}
              sx={{ flex: 1 }}
            />
            <Autocomplete
              size="small"
              options={ciudadesFiltradas}
              getOptionLabel={(o) => o.descripcion || ""}
              value={ciudades.find((c) => c.id === form.ciudad_id) || null}
              onChange={(_, v) => setForm((f) => ({ ...f, ciudad_id: v?.id || null }))}
              disabled={!isParaguay || !form.distrito_id}
              renderInput={(params) => (
                <TextField
                  {...params}
                  label="3. Ciudad"
                  error={!!err("ciudad_id")}
                  helperText={
                    err("ciudad_id") ||
                    (isParaguay && !form.distrito_id ? "Elegí antes el distrito" : undefined)
                  }
                />
              )}
              sx={{ flex: 1 }}
            />
          </Box>
          <Box display="flex" alignItems="center" gap={1}>
            <input
              type="checkbox"
              id="es_principal_panel"
              checked={form.es_principal}
              onChange={(e) => setForm((f) => ({ ...f, es_principal: e.target.checked }))}
            />
            <label htmlFor="es_principal_panel" style={{ fontSize: "0.875rem", cursor: "pointer", display: "flex", alignItems: "center", gap: 4 }}>
              <Home fontSize="small" /> Marcar como dirección principal
            </label>
          </Box>

          {tieneVendedores && (
            <>
              <Divider>
                <Chip icon={<People sx={{ fontSize: 14 }} />} label="Asignaciones" size="small" />
              </Divider>

              <Autocomplete
                size="small"
                options={vendedoresActivos}
                getOptionLabel={(o) => `${o.nombre} ${o.apellido || ""}`.trim()}
                value={vendedoresActivos.find((v) => v.id === form.vendedor_id) || null}
                onChange={(_, v) => {
                  const supId = v?.supervisores_asignados?.[0]?.supervisor?.id || null;
                  setForm((f) => ({
                    ...f,
                    vendedor_id: v?.id || null,
                    supervisor_id: supId ?? f.supervisor_id,
                  }));
                }}
                renderInput={(params) => <TextField {...params} label="Vendedor asignado" />}
                clearOnEscape
              />
              <Autocomplete
                size="small"
                options={cobradoresActivos}
                getOptionLabel={(o) => `${o.nombre} ${o.apellido || ""}`.trim()}
                value={cobradoresActivos.find((c) => c.id === form.cobrador_id) || null}
                onChange={(_, v) => {
                  const supId = v?.supervisores_asignados?.[0]?.supervisor?.id || null;
                  setForm((f) => ({
                    ...f,
                    cobrador_id: v?.id || null,
                    supervisor_id: supId ?? f.supervisor_id,
                  }));
                }}
                renderInput={(params) => <TextField {...params} label="Cobrador asignado" />}
                clearOnEscape
              />
              <Autocomplete
                size="small"
                options={supervisoresActivos}
                getOptionLabel={(o) => `${o.nombre} ${o.apellido || ""}`.trim()}
                value={supervisoresActivos.find((s) => s.id === form.supervisor_id) || null}
                onChange={(_, v) => setForm((f) => ({ ...f, supervisor_id: v?.id || null }))}
                renderInput={(params) => (
                  <TextField
                    {...params}
                    label="Supervisor"
                    InputProps={{ ...params.InputProps, startAdornment: <ManageAccounts fontSize="small" sx={{ mr: 0.5, color: "text.secondary" }} /> }}
                  />
                )}
                clearOnEscape
              />
            </>
          )}
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setFormOpen(false)} color="inherit">Cancelar</Button>
          <Button variant="contained" onClick={handleSave} disabled={isSaving}>
            {isSaving ? "Guardando..." : "Guardar"}
          </Button>
        </DialogActions>
      </Dialog>

      {/* Confirmar eliminación */}
      <Dialog open={!!deleteConfirm} onClose={() => setDeleteConfirm(null)} maxWidth="xs">
        <DialogTitle>¿Eliminar dirección?</DialogTitle>
        <DialogContent>
          <Typography variant="body2">Esta acción no se puede deshacer.</Typography>
        </DialogContent>
        <DialogActions>
          <Button onClick={() => setDeleteConfirm(null)}>Cancelar</Button>
          <Button color="error" variant="contained" disabled={deleteMut.isPending} onClick={() => deleteMut.mutate(deleteConfirm)}>
            Eliminar
          </Button>
        </DialogActions>
      </Dialog>
    </>
  );
}
