import { Icon } from "@iconify/react";
import {
  Autocomplete,
  Box,
  Button,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  IconButton,
  TextField,
  Typography,
} from "@mui/material";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { createRubro, setSucursalesRubro, updateRubro } from "../../../api/rubros.service";
import { SwitchConAyuda } from "../../_standards";

/**
 * Alta y edición de un rubro (unidad de negocio).
 *
 * Las sucursales van por su propio endpoint (`PUT /rubros/:id/sucursales`), así
 * que al crear se guardan en un segundo paso, cuando el rubro ya tiene id.
 */
const COLORES = ["#6366f1", "#ec4899", "#f59e0b", "#22c55e", "#0ea5e9", "#ef4444", "#8b5cf6", "#14b8a6"];
const ICONOS = [
  { valor: "lucide:layers", label: "Genérico" },
  { valor: "lucide:gift", label: "Regalería" },
  { valor: "lucide:wrench", label: "Taller" },
  { valor: "lucide:shopping-basket", label: "Despensa" },
  { valor: "lucide:hammer", label: "Ferretería" },
  { valor: "lucide:pill", label: "Farmacia" },
  { valor: "lucide:shirt", label: "Indumentaria" },
  { valor: "lucide:fuel", label: "Combustible" },
];

const VACIO = { codigo: "", descripcion: "", color: COLORES[0], icono: ICONOS[0].valor, activo: true };

export const RubroFormDialog = ({ open, rubro, sucursales = [], onClose }) => {
  const esEdicion = Boolean(rubro?.id);
  const queryClient = useQueryClient();
  const [form, setForm] = useState(VACIO);
  const [sucursalesSeleccionadas, setSucursalesSeleccionadas] = useState([]);
  const [errores, setErrores] = useState({});

  // El listado de sucursales del usuario viene recortado a las que tiene
  // asignadas (`tieneAccesoElevado` en el backend). Si el rubro ya está en una
  // que el usuario no ve, esa opción no existiría en el selector y al tocar el
  // campo se guardaría el set sin ella: le borraría la asignación sin querer.
  // Por eso se suman las que llegan con el rubro.
  const opcionesSucursales = (() => {
    const porId = new Map(sucursales.map((s) => [s.id, s]));
    for (const sr of rubro?.sucursal_rubros || []) {
      const suc = sr.empresas_sucursales;
      if (suc?.id && !porId.has(suc.id)) porId.set(suc.id, suc);
    }
    return [...porId.values()];
  })();

  useEffect(() => {
    if (!open) return;
    if (esEdicion) {
      setForm({
        codigo: rubro.codigo || "",
        descripcion: rubro.descripcion || "",
        color: rubro.color || COLORES[0],
        icono: rubro.icono || ICONOS[0].valor,
        activo: rubro.activo !== false,
      });
      setSucursalesSeleccionadas((rubro.sucursal_rubros || []).map((sr) => sr.sucursal_id));
    } else {
      setForm(VACIO);
      setSucursalesSeleccionadas([]);
    }
    setErrores({});
  }, [open, rubro, esEdicion]);

  const invalidar = () => {
    queryClient.invalidateQueries({ queryKey: ["rubros"] });
    queryClient.invalidateQueries({ queryKey: ["rubros-activos"] });
  };

  const guardarSucursales = async (rubroId) => {
    try {
      await setSucursalesRubro(rubroId, sucursalesSeleccionadas);
    } catch {
      // El rubro ya quedó guardado; sólo falló el segundo paso.
      toast.error("El rubro se guardó, pero no se pudieron asignar las sucursales");
    }
  };

  const mutation = useMutation({
    mutationFn: async () => {
      const payload = {
        codigo: form.codigo.trim(),
        descripcion: form.descripcion.trim(),
        color: form.color,
        icono: form.icono,
        ...(esEdicion ? { activo: form.activo } : {}),
      };
      if (esEdicion) {
        await updateRubro(rubro.id, payload);
        await guardarSucursales(rubro.id);
        return { message: "Rubro actualizado" };
      }
      const resp = await createRubro(payload);
      const nuevoId = resp?.data?.id || resp?.id;
      if (nuevoId) await guardarSucursales(nuevoId);
      return resp;
    },
    onSuccess: (resp) => {
      toast.success(resp?.message || "Rubro guardado");
      invalidar();
      onClose();
    },
    onError: (error) => {
      toast.error(error?.response?.data?.message || "No se pudo guardar el rubro");
    },
  });

  const validar = () => {
    const e = {};
    if (!form.codigo.trim()) e.codigo = "El código es obligatorio";
    if (!form.descripcion.trim()) e.descripcion = "El nombre es obligatorio";
    setErrores(e);
    return Object.keys(e).length === 0;
  };

  const handleGuardar = () => {
    if (validar()) mutation.mutate();
  };

  return (
    <Dialog open={open} onClose={onClose} maxWidth="sm" fullWidth PaperProps={{ sx: { borderRadius: 2 } }}>
      <DialogTitle sx={{ display: "flex", alignItems: "center", gap: 1.25 }}>
        <Box
          sx={{
            width: "2.2rem", height: "2.2rem", borderRadius: "10px",
            bgcolor: "action.hover", display: "flex", alignItems: "center",
            justifyContent: "center", color: "primary.main", flexShrink: 0,
          }}
        >
          <Icon icon={form.icono || "lucide:layers"} width={20} />
        </Box>
        <Typography variant="subtitle1" fontWeight={700} sx={{ flex: 1 }}>
          {esEdicion ? "Editar Rubro" : "Nuevo Rubro"}
        </Typography>
        <IconButton onClick={onClose} size="small">
          <Icon icon="lucide:x" width={18} />
        </IconButton>
      </DialogTitle>

      <DialogContent dividers>
        <Box sx={{ display: "grid", gridTemplateColumns: { xs: "1fr", sm: "140px 1fr" }, gap: 2 }}>
          <TextField
            size="small"
            label="Código *"
            value={form.codigo}
            onChange={(e) => setForm((p) => ({ ...p, codigo: e.target.value.toUpperCase().slice(0, 20) }))}
            error={Boolean(errores.codigo)}
            helperText={errores.codigo || "Corto, sin espacios"}
            inputProps={{ maxLength: 20 }}
            autoFocus={!esEdicion}
          />
          <TextField
            size="small"
            label="Nombre *"
            placeholder="Ej: Ferretería"
            value={form.descripcion}
            onChange={(e) => setForm((p) => ({ ...p, descripcion: e.target.value.slice(0, 100) }))}
            error={Boolean(errores.descripcion)}
            helperText={errores.descripcion || "Es lo que ve el usuario en el selector"}
          />
        </Box>

        <Box sx={{ mt: 2.5 }}>
          <Autocomplete
            multiple
            size="small"
            options={opcionesSucursales}
            value={opcionesSucursales.filter((s) => sucursalesSeleccionadas.includes(s.id))}
            onChange={(_, sel) => setSucursalesSeleccionadas(sel.map((s) => s.id))}
            getOptionLabel={(o) => o.descripcion || o.nombre || ""}
            isOptionEqualToValue={(o, v) => o.id === v.id}
            renderInput={(params) => (
              <TextField
                {...params}
                label="Sucursales que operan este rubro"
                helperText={
                  sucursalesSeleccionadas.length
                    ? "Los usuarios asignados a estas sucursales arrancan en este rubro."
                    : "Sin sucursales: el rubro sirve para etiquetar, pero no le da default a ningún usuario."
                }
              />
            )}
          />
        </Box>

        <Box sx={{ mt: 2.5 }}>
          <Typography variant="caption" color="text.secondary" sx={{ fontWeight: 700, letterSpacing: 0.5, textTransform: "uppercase" }}>
            Color e icono del chip
          </Typography>
          <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", mt: 1 }}>
            {COLORES.map((color) => (
              <Box
                key={color}
                onClick={() => setForm((p) => ({ ...p, color }))}
                sx={{
                  width: 30, height: 30, borderRadius: "50%", backgroundColor: color, cursor: "pointer",
                  border: form.color === color ? "3px solid #fff" : "2px solid transparent",
                  boxShadow: form.color === color ? `0 0 0 2px ${color}` : "none",
                  transition: "all 0.15s",
                  "&:hover": { transform: "scale(1.1)" },
                }}
              />
            ))}
          </Box>
          <Box sx={{ display: "flex", gap: 1, flexWrap: "wrap", mt: 1.5 }}>
            {ICONOS.map((ic) => (
              <Box
                key={ic.valor}
                onClick={() => setForm((p) => ({ ...p, icono: ic.valor }))}
                title={ic.label}
                sx={{
                  width: 34, height: 34, borderRadius: "9px", cursor: "pointer",
                  display: "flex", alignItems: "center", justifyContent: "center",
                  color: form.icono === ic.valor ? "#fff" : "text.secondary",
                  bgcolor: form.icono === ic.valor ? form.color : "action.hover",
                  transition: "all 0.15s",
                }}
              >
                <Icon icon={ic.valor} width={18} />
              </Box>
            ))}
          </Box>
        </Box>

        {esEdicion && (
          <Box sx={{ mt: 2.5, ml: -1 }}>
            <SwitchConAyuda
              checked={form.activo}
              onChange={(activo) => setForm((p) => ({ ...p, activo }))}
              label="Rubro activo"
              ayuda="Un rubro inactivo deja de ofrecerse en los selectores, pero no se pierde nada: lo que ya está etiquetado con él sigue igual."
            />
          </Box>
        )}
      </DialogContent>

      <DialogActions>
        <Button onClick={onClose} disabled={mutation.isPending}>
          Cancelar
        </Button>
        <Button variant="contained" onClick={handleGuardar} disabled={mutation.isPending}>
          {esEdicion ? "Guardar" : "Crear"}
        </Button>
      </DialogActions>
    </Dialog>
  );
};
