import type { SelectChangeEvent } from '@mui/material';

import React, { useState, useEffect } from 'react';

import { Edit as EditIcon, Security as SecurityIcon } from '@mui/icons-material';
import {
  Box,
  Grid,
  Card,
  Chip,
  Alert,
  Select,
  Button,
  Divider,
  MenuItem,
  Typography,
  InputLabel,
  FormControl,
  FormHelperText,
  CircularProgress,
} from '@mui/material';

import { useRoleStore } from 'src/shared/api/stores/roleStore';
import { useUserStore } from 'src/shared/api/stores/userStore';

import { toast } from 'src/shared/components/snackbar';
import { BaseUser, IAdmin } from 'src/contexts/types/user';

type Props = {
  currentUser?: BaseUser;
};

const AdminRoleSelector = ({ currentUser }: Props) => {
  const [selectedAdminRoles, setSelectedAdminRoles] = useState<number[]>([]);
  const [initialAdminRoles, setInitialAdminRoles] = useState<number[]>([]);
  const [error, setError] = useState('');
  const [validationError, setValidationError] = useState('');
  const { getAllRoles, roles: administrationRoles, loading: roleLoading } = useRoleStore();
  const { updateAdminRoles, loading: userLoading } = useUserStore();

  // Fix: Use proper loading state
  const loading = roleLoading || userLoading;

  useEffect(() => {
    const fetchRoles = async () => {
      try {
        if (!administrationRoles?.length) {
          await getAllRoles();
        }
      } catch (err) {
        console.error('Erreur lors du chargement des rôles:', err);
        setError('Erreur lors du chargement des rôles');
      }
    };

    fetchRoles();
  }, [administrationRoles?.length, currentUser, getAllRoles]);

  useEffect(() => {
    const admin = currentUser as IAdmin;
    if (admin?.roles?.length) {
      const userRoleIds = admin.roles.map((role) => role.id);
      setSelectedAdminRoles(userRoleIds);
      setInitialAdminRoles(userRoleIds);
    } else {
      setSelectedAdminRoles([]);
      setInitialAdminRoles([]);
    }
  }, [currentUser]);

  const arraysEqual = (a: number[], b: number[]) => {
    if (a.length !== b.length) return false;
    const sortedA = [...a].sort();
    const sortedB = [...b].sort();
    return sortedA.every((val, index) => val === sortedB[index]);
  };

  const validateSelection = (): boolean => {
    if (selectedAdminRoles.length === 0) {
      setValidationError('Au moins un rôle doit être sélectionné');
      return false;
    }
    setValidationError('');
    return true;
  };

  const handleRoleChange = (event: SelectChangeEvent<number[]>) => {
    const { value } = event.target;
    const newValue = typeof value === 'string' ? value.split(',').map((v) => Number(v)) : value;
    setSelectedAdminRoles(newValue);

    if (validationError && newValue.length > 0) {
      setValidationError('');
    }
  };

  const updateAdminRole = async () => {
    if (!validateSelection()) {
      return;
    }
    try {
      if (currentUser && currentUser.id) {
        if (currentUser?.status !== 'ACTIVE') {
          toast.error("Impossible de modifier les roles d'un admin non activé");
          return;
        }
        await updateAdminRoles(currentUser.id, selectedAdminRoles);
        toast.success('Rôles modifiés avec succès !');
        setInitialAdminRoles(selectedAdminRoles);
      }
    } catch (e: any) {
      const errorMessage = e?.message || 'Une erreur est survenue lors de la mise à jour';
      toast.error(errorMessage);
    }
  };

  if (loading || !administrationRoles) {
    return (
      <Grid container spacing={3}>
        <Grid item xs={12}>
          <Card sx={{ p: 3, textAlign: 'center' }}>
            <CircularProgress />
            <Typography sx={{ mt: 2 }}>Chargement des rôles...</Typography>
          </Card>
        </Grid>
      </Grid>
    );
  }

  return (
    <Grid container spacing={3}>
      <Grid item xs={12}>
        <Card sx={{ p: 3 }}>
          <Typography variant="h6" sx={{ mb: 2 }}>
            <SecurityIcon sx={{ mr: 1, verticalAlign: 'middle' }} />
            Rôles administrateur
          </Typography>
          <Divider sx={{ mb: 3 }} />

          {error && (
            <Alert severity="error" sx={{ mb: 2 }}>
              {error}
            </Alert>
          )}

          <FormControl fullWidth error={!!validationError} sx={{ mb: 2 }} disabled={loading}>
            <InputLabel id="select-admin-roles-label">Sélectionner les rôles</InputLabel>

            <Select
              multiple
              value={selectedAdminRoles}
              onChange={handleRoleChange}
              label="Sélectionner les rôles"
              renderValue={(selected) => (
                <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5, pt: 0.5, pb: 0.5 }}>
                  {(selected as number[]).map((value) => {
                    const role = administrationRoles.find((r) => r.id === value);
                    return <Chip key={value} label={role?.name || value} size="small" />;
                  })}
                </Box>
              )}
              MenuProps={{
                PaperProps: {
                  style: {
                    maxHeight: 300,
                  },
                },
              }}
            >
              {administrationRoles.map((role) => (
                <MenuItem key={role.id} value={role.id}>
                  <Box>
                    <Typography variant="body1">{role.name}</Typography>
                    {role.description && (
                      <Typography variant="body2" color="text.secondary">
                        {role.description}
                      </Typography>
                    )}
                  </Box>
                </MenuItem>
              ))}
            </Select>

            {validationError && <FormHelperText>{validationError}</FormHelperText>}
          </FormControl>

          <Box sx={{ mt: 3, display: 'flex', justifyContent: 'flex-end' }}>
            <Button
              startIcon={loading ? <CircularProgress size={16} /> : <EditIcon />}
              variant="contained"
              onClick={updateAdminRole}
              disabled={
                loading ||
                selectedAdminRoles.length === 0 ||
                arraysEqual(selectedAdminRoles, initialAdminRoles)
              }
            >
              {loading ? 'Modification...' : 'Modifier les rôles'}
            </Button>
          </Box>
        </Card>
      </Grid>
    </Grid>
  );
};

export default AdminRoleSelector;
