import React, { useEffect, useState } from "react";
import {
  Dialog,
  DialogTitle,
  DialogContent,
  DialogActions,
  Button,
  TextField,
  Grid,
  Table,
  TableHead,
  TableBody,
  TableRow,
  TableCell,
  Checkbox,
  Typography,
  Box,
  IconButton,
  CircularProgress,
} from "@mui/material";
import CloseIcon from "@mui/icons-material/Close";
import {
  useGetPermissionMatrixQuery,
  useCreateRoleMutation,
  useUpdateRoleMutation,
} from "../../../Api/attoDeskApi";
import { IRole } from "../../../Api/Interface/api.interface";
import { useNotifier } from "../../../Core/Notifier";

interface CreateRoleModalProps {
  open: boolean;
  handleClose: () => void;
  roleToEdit: IRole | null;
}

const ACTIONS = ["view", "create", "edit", "delete"] as const;
type Action = (typeof ACTIONS)[number];

const CreateRoleModal: React.FC<CreateRoleModalProps> = ({ open, handleClose, roleToEdit }) => {
  const { showErrorMessage, showMessage } = useNotifier();
  const { data: matrixData, isLoading: matrixLoading } = useGetPermissionMatrixQuery(undefined, {
    skip: !open,
  });
  const [createRole, { isLoading: creating }] = useCreateRoleMutation();
  const [updateRole, { isLoading: updating }] = useUpdateRoleMutation();

  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [checked, setChecked] = useState<Record<number, boolean>>({});

  const isEditing = Boolean(roleToEdit);
  const isSaving = creating || updating;
  const modules = matrixData?.data ?? [];

  useEffect(() => {
    if (!open) return;

    setName(roleToEdit?.name ?? "");
    setDescription(roleToEdit?.description ?? "");

    if (roleToEdit && matrixData?.data) {
      const activeKeys = new Set<string>();
      roleToEdit.modules.forEach((m) => {
        m.actions.forEach((a) => activeKeys.add(`${m.module}.${a}`));
      });

      const initialChecked: Record<number, boolean> = {};
      matrixData.data.forEach((group) => {
        group.permissions.forEach((p) => {
          initialChecked[p.id] = activeKeys.has(p.key);
        });
      });
      setChecked(initialChecked);
    } else {
      setChecked({});
    }
  }, [open, roleToEdit, matrixData]);

  const isModuleAllChecked = (moduleKey: string) => {
    const group = modules.find((g) => g.module === moduleKey);
    if (!group) return false;
    return group.permissions.every((p) => checked[p.id]);
  };

  const isColumnAllChecked = (action: Action) => {
    const allIdsForAction = modules.flatMap((g) =>
      g.permissions.filter((p) => p.action === action).map((p) => p.id)
    );
    if (allIdsForAction.length === 0) return false;
    return allIdsForAction.every((id) => checked[id]);
  };

  const toggleCell = (permissionId: number, value: boolean) => {
    setChecked((prev) => ({ ...prev, [permissionId]: value }));
  };

  const toggleModuleRow = (moduleKey: string) => {
    const group = modules.find((g) => g.module === moduleKey);
    if (!group) return;
    const shouldCheck = !isModuleAllChecked(moduleKey);
    setChecked((prev) => {
      const next = { ...prev };
      group.permissions.forEach((p) => {
        next[p.id] = shouldCheck;
      });
      return next;
    });
  };

  const toggleColumn = (action: Action) => {
    const shouldCheck = !isColumnAllChecked(action);
    setChecked((prev) => {
      const next = { ...prev };
      modules.forEach((g) => {
        g.permissions
          .filter((p) => p.action === action)
          .forEach((p) => {
            next[p.id] = shouldCheck;
          });
      });
      return next;
    });
  };

  const handleSubmit = async () => {
    if (!name.trim()) {
      showErrorMessage("Role name is required");
      return;
    }

    const permission_ids = Object.entries(checked)
      .filter(([, isChecked]) => isChecked)
      .map(([id]) => Number(id));

    try {
      if (isEditing && roleToEdit) {
        await updateRole({
          id: roleToEdit.id,
          name,
          description,
          permission_ids,
        }).unwrap();
        showMessage("Role updated successfully");
      } else {
        await createRole({ name, description, permission_ids }).unwrap();
        showMessage("Role created successfully");
      }
      handleClose();
    } catch (error: any) {
      showErrorMessage(error?.data?.message || "Failed to save role");
    }
  };

  return (
    <Dialog open={open} onClose={handleClose} maxWidth="md" fullWidth>
      <DialogTitle sx={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        {isEditing ? "Edit Role" : "Create New Role"}
        <IconButton onClick={handleClose} size="small">
          <CloseIcon fontSize="small" />
        </IconButton>
      </DialogTitle>

      <DialogContent dividers>
        <Grid container spacing={2} sx={{ mb: 2 }}>
          <Grid item xs={6}>
            <TextField
              label="Role Name *"
              fullWidth
              size="small"
              value={name}
              onChange={(e) => setName(e.target.value)}
              disabled={Boolean(roleToEdit?.is_system)}
            />
          </Grid>
          <Grid item xs={6}>
            <TextField
              label="Description"
              fullWidth
              size="small"
              value={description}
              onChange={(e) => setDescription(e.target.value)}
            />
          </Grid>
        </Grid>

        <Typography sx={{ fontWeight: 500, mb: 1 }}>Permission Matrix</Typography>

        {matrixLoading ? (
          <Box display="flex" justifyContent="center" py={4}>
            <CircularProgress size={28} />
          </Box>
        ) : (
          <Box sx={{ border: "0.5px solid", borderColor: "divider", borderRadius: 1, maxHeight: 360, overflow: "auto" }}>
            <Table size="small" stickyHeader>
              <TableHead>
                <TableRow>
                  <TableCell sx={{ fontWeight: 500 }}>Module</TableCell>
                  {ACTIONS.map((action) => (
                    <TableCell
                      key={action}
                      align="center"
                      sx={{ fontWeight: 500, cursor: "pointer", textTransform: "capitalize" }}
                      onClick={() => toggleColumn(action)}
                    >
                      {action}
                    </TableCell>
                  ))}
                  <TableCell align="center" sx={{ fontWeight: 500 }}>
                    All
                  </TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {modules.map((group) => (
                  <TableRow key={group.module} hover>
                    <TableCell>
                      <Typography variant="body2">{group.label}</Typography>
                      <Typography variant="caption" color="text.secondary">
                        {group.module}
                      </Typography>
                    </TableCell>
                    {ACTIONS.map((action) => {
                      const permission = group.permissions.find((p) => p.action === action);
                      if (!permission) {
                        return <TableCell key={action} align="center" />;
                      }
                      return (
                        <TableCell key={action} align="center">
                          <Checkbox
                            size="small"
                            checked={Boolean(checked[permission.id])}
                            onChange={(e) => toggleCell(permission.id, e.target.checked)}
                          />
                        </TableCell>
                      );
                    })}
                    <TableCell align="center">
                      <Checkbox
                        size="small"
                        checked={isModuleAllChecked(group.module)}
                        onChange={() => toggleModuleRow(group.module)}
                      />
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </Box>
        )}

        <Typography variant="caption" color="text.secondary" sx={{ display: "block", mt: 1 }}>
          Click column headers to toggle all modules for that action. Click "All" to toggle all actions for a module.
        </Typography>
      </DialogContent>

      <DialogActions>
        <Button onClick={handleClose}>Cancel</Button>
        <Button variant="contained" onClick={handleSubmit} disabled={isSaving}>
          {isSaving ? <CircularProgress size={18} /> : isEditing ? "Save Changes" : "Create Role"}
        </Button>
      </DialogActions>
    </Dialog>
  );
};

export default CreateRoleModal;
