import SearchIcon from "@mui/icons-material/Search";
import LockIcon from "@mui/icons-material/Lock";
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
import {
  Alert,
  Box,
  Button,
  Checkbox,
  Chip,
  CircularProgress,
  Dialog,
  DialogActions,
  DialogContent,
  DialogTitle,
  FormControlLabel,
  InputAdornment,
  List,
  ListItemButton,
  ListItemText,
  Stack,
  TextField,
  Tooltip,
  Typography,
  useMediaQuery,
  useTheme,
} from "@mui/material";
import { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
import {
  useActualizarPerfilMutation,
  useArbolModulosQuery,
  useClonarPerfilMutation,
  useCrearPerfilMutation,
  usePerfilV2Query,
} from "../../../tanstack/SeguridadStack";

const normalize = (s) =>
  (s || "").normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase();

export const PerfilFormDialog = ({ open, onClose, perfil }) => {
  const muiTheme = useTheme();
  const isMobile = useMediaQuery(muiTheme.breakpoints.down("md"));
  const isEdit = !!perfil;
  const isSistema = !!perfil?.is_sistema;

  const { data: arbol = [], isLoading: loadingArbol } = useArbolModulosQuery();
  const { data: perfilFull, isLoading: loadingPerfil } = usePerfilV2Query(
    isEdit && open ? perfil?.id : null,
  );

  const crearMut = useCrearPerfilMutation();
  const actualizarMut = useActualizarPerfilMutation();
  const clonarMut = useClonarPerfilMutation();

  const [moduloSearch, setModuloSearch] = useState("");
  const [activeModuloId, setActiveModuloId] = useState(null);

  const {
    register,
    handleSubmit,
    reset,
    watch,
    setValue,
    formState: { errors },
  } = useForm({
    defaultValues: { perfil: "", desc_perfil: "", privilegio_ids: [] },
  });

  const selected = watch("privilegio_ids") || [];
  const selectedSet = useMemo(() => new Set(selected), [selected]);

  useEffect(() => {
    if (!open) {
      setModuloSearch("");
      setActiveModuloId(null);
    }
  }, [open]);

  useEffect(() => {
    if (!open) return;
    if (isEdit && perfilFull) {
      reset({
        perfil: perfilFull.perfil,
        desc_perfil: perfilFull.desc_perfil || "",
        privilegio_ids: perfilFull.privilegio_ids || [],
      });
    } else if (!isEdit) {
      reset({ perfil: "", desc_perfil: "", privilegio_ids: [] });
    }
  }, [perfilFull, open, isEdit, reset]);

  // Set default active module on first load
  useEffect(() => {
    if (!activeModuloId && arbol.length > 0) {
      setActiveModuloId(arbol[0].id);
    }
  }, [arbol, activeModuloId]);

  const filteredModulos = useMemo(() => {
    if (!moduloSearch.trim()) return arbol;
    const q = normalize(moduloSearch);
    return arbol.filter((m) => {
      if (normalize(m.descripcion).includes(q) || normalize(m.codigo).includes(q)) return true;
      return (m.submodulos || []).some(
        (s) => normalize(s.descripcion).includes(q) || normalize(s.codigo).includes(q),
      );
    });
  }, [arbol, moduloSearch]);

  const activeModulo = useMemo(
    () => arbol.find((m) => m.id === activeModuloId) || null,
    [arbol, activeModuloId],
  );

  // Counters per module
  const countByModulo = useMemo(() => {
    const map = new Map();
    arbol.forEach((m) => {
      let active = 0;
      let total = 0;
      (m.submodulos || []).forEach((s) => {
        (s.privilegios || []).forEach((p) => {
          total++;
          if (selectedSet.has(p.id)) active++;
        });
      });
      map.set(m.id, { active, total });
    });
    return map;
  }, [arbol, selectedSet]);

  const togglePriv = (privId) => {
    const next = new Set(selected);
    if (next.has(privId)) next.delete(privId);
    else next.add(privId);
    setValue("privilegio_ids", Array.from(next), { shouldDirty: true });
  };

  const toggleSubmodulo = (sub) => {
    const ids = (sub.privilegios || []).map((p) => p.id);
    const allOn = ids.every((id) => selectedSet.has(id));
    const next = new Set(selected);
    if (allOn) ids.forEach((id) => next.delete(id));
    else ids.forEach((id) => next.add(id));
    setValue("privilegio_ids", Array.from(next), { shouldDirty: true });
  };

  const toggleModulo = (mod) => {
    const ids = (mod.submodulos || []).flatMap((s) =>
      (s.privilegios || []).map((p) => p.id),
    );
    if (!ids.length) return;
    const allOn = ids.every((id) => selectedSet.has(id));
    const next = new Set(selected);
    if (allOn) ids.forEach((id) => next.delete(id));
    else ids.forEach((id) => next.add(id));
    setValue("privilegio_ids", Array.from(next), { shouldDirty: true });
  };

  const handleClonar = async () => {
    if (!perfil?.id) return;
    await clonarMut.mutateAsync(perfil.id);
    onClose();
  };

  const onSubmit = async (data) => {
    const payload = {
      perfil: data.perfil,
      desc_perfil: data.desc_perfil || undefined,
      privilegio_ids: data.privilegio_ids,
    };
    if (isEdit) await actualizarMut.mutateAsync({ id: perfil.id, ...payload });
    else await crearMut.mutateAsync(payload);
    onClose();
  };

  const isSaving = crearMut.isPending || actualizarMut.isPending;
  const isLoading = loadingArbol || (isEdit && loadingPerfil);

  const totalSelected = selected.length;
  const totalAvailable = useMemo(
    () =>
      arbol.reduce(
        (acc, m) =>
          acc + (m.submodulos || []).reduce((a, s) => a + (s.privilegios?.length || 0), 0),
        0,
      ),
    [arbol],
  );

  return (
    <Dialog open={open} onClose={onClose} maxWidth="lg" fullWidth fullScreen={isMobile}>
      <DialogTitle sx={{ pb: 1 }}>
        <Stack direction="row" alignItems="center" justifyContent="space-between" gap={1}>
          <Box>
            <Typography variant="h6" fontWeight={700}>
              {isEdit ? "Editar Perfil" : "Nuevo Perfil"}
              {isSistema && (
                <Chip
                  icon={<LockIcon fontSize="small" />}
                  label="Sistema"
                  size="small"
                  sx={{ ml: 1 }}
                />
              )}
            </Typography>
            <Typography variant="body2" color="text.secondary">
              {isEdit
                ? "Modificá los datos y permisos del perfil"
                : "Definí un nuevo rol y sus accesos"}
            </Typography>
          </Box>
          {isSistema && (
            <Tooltip title="Clonar este perfil para personalizarlo">
              <Button
                startIcon={<ContentCopyIcon />}
                onClick={handleClonar}
                disabled={clonarMut.isPending}
                size="small"
              >
                Clonar
              </Button>
            </Tooltip>
          )}
        </Stack>
      </DialogTitle>

      <form onSubmit={handleSubmit(onSubmit)}>
        <DialogContent dividers sx={{ p: 0 }}>
          {/* Datos básicos */}
          <Box
            sx={{
              display: "grid",
              gap: 2,
              gridTemplateColumns: { xs: "1fr", sm: "1fr 1fr" },
              p: 2,
              borderBottom: "1px solid",
              borderColor: "divider",
            }}
          >
            <TextField
              label="Nombre del Perfil *"
              placeholder="Ej: Vendedor Caja"
              fullWidth
              autoFocus
              size="small"
              disabled={isSistema}
              {...register("perfil", {
                required: "El nombre es requerido",
                minLength: { value: 3, message: "Mínimo 3 caracteres" },
              })}
              error={!!errors.perfil}
              helperText={errors.perfil?.message}
            />
            <TextField
              label="Descripción"
              placeholder="Funciones del rol"
              fullWidth
              size="small"
              disabled={isSistema}
              {...register("desc_perfil")}
            />
          </Box>

          {isSistema && (
            <Alert severity="info" sx={{ borderRadius: 0 }}>
              Este es un perfil del sistema y no puede editarse. Usá <b>Clonar</b> para crear una
              copia personalizable.
            </Alert>
          )}

          {isLoading ? (
            <Box sx={{ display: "flex", justifyContent: "center", py: 6 }}>
              <CircularProgress size={28} />
            </Box>
          ) : arbol.length === 0 ? (
            <Box sx={{ p: 4, textAlign: "center" }}>
              <Typography color="text.secondary">
                No hay módulos configurados. Corré el seed maestro de seguridad.
              </Typography>
            </Box>
          ) : (
            <Box
              sx={{
                display: "grid",
                gridTemplateColumns: { xs: "1fr", md: "260px 1fr" },
                minHeight: { md: 480 },
              }}
            >
              {/* ── Sidebar de módulos ───────────────────────────── */}
              <Box
                sx={{
                  borderRight: { md: "1px solid" },
                  borderBottom: { xs: "1px solid", md: 0 },
                  borderColor: "divider",
                  display: "flex",
                  flexDirection: "column",
                }}
              >
                <Box sx={{ p: 1.5, borderBottom: "1px solid", borderColor: "divider" }}>
                  <TextField
                    size="small"
                    fullWidth
                    placeholder="Buscar módulo..."
                    value={moduloSearch}
                    onChange={(e) => setModuloSearch(e.target.value)}
                    InputProps={{
                      startAdornment: (
                        <InputAdornment position="start">
                          <SearchIcon fontSize="small" />
                        </InputAdornment>
                      ),
                    }}
                  />
                  <Typography
                    variant="caption"
                    color="text.secondary"
                    sx={{ mt: 0.75, display: "block" }}
                  >
                    {totalSelected} / {totalAvailable} privilegios activos
                  </Typography>
                </Box>
                <List
                  dense
                  sx={{
                    flex: 1,
                    overflowY: "auto",
                    maxHeight: { xs: 200, md: "calc(100vh - 360px)" },
                    py: 0,
                  }}
                >
                  {filteredModulos.map((m) => {
                    const counts = countByModulo.get(m.id) || { active: 0, total: 0 };
                    const isActive = m.id === activeModuloId;
                    return (
                      <ListItemButton
                        key={m.id}
                        selected={isActive}
                        onClick={() => setActiveModuloId(m.id)}
                        sx={{
                          borderLeft: "3px solid",
                          borderColor: isActive ? "primary.main" : "transparent",
                        }}
                      >
                        <ListItemText
                          primary={
                            <Typography
                              variant="body2"
                              fontWeight={isActive ? 700 : 500}
                              noWrap
                            >
                              {m.descripcion || m.codigo}
                            </Typography>
                          }
                          secondary={
                            counts.total > 0 ? (
                              <Typography
                                variant="caption"
                                color={counts.active > 0 ? "primary.main" : "text.disabled"}
                              >
                                {counts.active}/{counts.total}
                              </Typography>
                            ) : (
                              <Typography variant="caption" color="text.disabled">
                                sin privilegios
                              </Typography>
                            )
                          }
                        />
                      </ListItemButton>
                    );
                  })}
                  {filteredModulos.length === 0 && (
                    <Box sx={{ p: 2, textAlign: "center" }}>
                      <Typography variant="caption" color="text.secondary">
                        Sin resultados
                      </Typography>
                    </Box>
                  )}
                </List>
              </Box>

              {/* ── Panel derecho: submódulos del módulo activo ──── */}
              <Box
                sx={{
                  p: 2,
                  overflowY: "auto",
                  maxHeight: { xs: 360, md: "calc(100vh - 360px)" },
                }}
              >
                {!activeModulo ? (
                  <Typography color="text.secondary">
                    Seleccioná un módulo a la izquierda
                  </Typography>
                ) : (
                  <>
                    <Stack
                      direction="row"
                      alignItems="center"
                      justifyContent="space-between"
                      sx={{ mb: 1.5 }}
                    >
                      <Box>
                        <Typography variant="h6" fontWeight={700}>
                          {activeModulo.descripcion || activeModulo.codigo}
                        </Typography>
                        <Typography variant="caption" color="text.secondary">
                          {activeModulo.codigo}
                        </Typography>
                      </Box>
                      <Button
                        size="small"
                        variant="outlined"
                        disabled={isSistema}
                        onClick={() => toggleModulo(activeModulo)}
                      >
                        Todo el módulo
                      </Button>
                    </Stack>

                    {!activeModulo.submodulos?.length && (
                      <Typography variant="body2" color="text.secondary">
                        Este módulo no tiene submódulos.
                      </Typography>
                    )}

                    <Stack spacing={1.5}>
                      {(activeModulo.submodulos || []).map((sub) => {
                        const privIds = (sub.privilegios || []).map((p) => p.id);
                        const activeCount = privIds.filter((id) => selectedSet.has(id))
                          .length;
                        const allOn = privIds.length > 0 && activeCount === privIds.length;
                        const someOn = activeCount > 0 && activeCount < privIds.length;

                        return (
                          <Box
                            key={sub.id}
                            sx={{
                              border: "1px solid",
                              borderColor: activeCount > 0 ? "primary.main" : "divider",
                              borderRadius: 1.5,
                              p: 1.5,
                            }}
                          >
                            <Stack
                              direction="row"
                              alignItems="center"
                              justifyContent="space-between"
                              sx={{ mb: 1 }}
                            >
                              <FormControlLabel
                                control={
                                  <Checkbox
                                    size="small"
                                    checked={allOn}
                                    indeterminate={someOn}
                                    onChange={() => toggleSubmodulo(sub)}
                                    disabled={isSistema || !privIds.length}
                                  />
                                }
                                label={
                                  <Box>
                                    <Typography variant="body2" fontWeight={700}>
                                      {sub.descripcion || sub.codigo}
                                      {sub.es_addon && (
                                        <Chip
                                          label="Addon"
                                          size="small"
                                          color="warning"
                                          variant="outlined"
                                          sx={{ ml: 0.75, height: 18, fontSize: "0.65rem" }}
                                        />
                                      )}
                                    </Typography>
                                    <Typography variant="caption" color="text.secondary">
                                      {sub.codigo} · {activeCount}/{privIds.length}
                                    </Typography>
                                  </Box>
                                }
                                sx={{ m: 0 }}
                              />
                            </Stack>

                            {privIds.length === 0 ? (
                              <Typography
                                variant="caption"
                                color="text.disabled"
                                sx={{ pl: 4 }}
                              >
                                Sin privilegios cargados
                              </Typography>
                            ) : (
                              <Box
                                sx={{
                                  display: "flex",
                                  flexWrap: "wrap",
                                  gap: 0.75,
                                  pl: 4,
                                }}
                              >
                                {(sub.privilegios || []).map((p) => {
                                  const isOn = selectedSet.has(p.id);
                                  const label =
                                    p.accion ||
                                    p.desc_privilegio ||
                                    p.codigo?.replace(/_/g, " ") ||
                                    "—";
                                  return (
                                    <Tooltip
                                      key={p.id}
                                      title={
                                        <>
                                          <div>
                                            <b>{p.codigo}</b>
                                          </div>
                                          {p.desc_privilegio && (
                                            <div>{p.desc_privilegio}</div>
                                          )}
                                        </>
                                      }
                                      placement="top"
                                    >
                                      <Chip
                                        size="small"
                                        label={label}
                                        onClick={
                                          isSistema ? undefined : () => togglePriv(p.id)
                                        }
                                        color={isOn ? "primary" : "default"}
                                        variant={isOn ? "filled" : "outlined"}
                                        sx={{
                                          fontSize: "0.7rem",
                                          height: 24,
                                          cursor: isSistema ? "default" : "pointer",
                                          fontWeight: isOn ? 700 : 400,
                                          opacity: isOn ? 1 : 0.7,
                                        }}
                                      />
                                    </Tooltip>
                                  );
                                })}
                              </Box>
                            )}
                          </Box>
                        );
                      })}
                    </Stack>
                  </>
                )}
              </Box>
            </Box>
          )}
        </DialogContent>

        <DialogActions sx={{ px: 3, py: 1.5, gap: 1 }}>
          <Button onClick={onClose} color="inherit">
            Cancelar
          </Button>
          <Button
            type="submit"
            variant="contained"
            disabled={isSaving || isSistema}
            sx={{ px: 4 }}
          >
            {isSaving ? "Guardando..." : isEdit ? "Guardar cambios" : "Crear perfil"}
          </Button>
        </DialogActions>
      </form>
    </Dialog>
  );
};
