import React, { useEffect, useState } from 'react';
import api from '../../utils/api';
import { Card } from '../../components/ui/card';
import { Button } from '../../components/ui/button';
import { Input } from '../../components/ui/input';
import { Label } from '../../components/ui/label';
import { Textarea } from '../../components/ui/textarea';
import { Checkbox } from '../../components/ui/checkbox';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '../../components/ui/dialog';
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
} from '../../components/ui/alert-dialog';
import { toast } from 'sonner';
import { Shield, Plus, Edit, Trash2, Lock, ChevronDown, ChevronUp } from 'lucide-react';

const AdminRoles = () => {
  const [roles, setRoles] = useState([]);
  const [permissions, setPermissions] = useState([]);
  const [selectedRole, setSelectedRole] = useState(null);
  const [rolePermissions, setRolePermissions] = useState([]);
  const [selectedPermissions, setSelectedPermissions] = useState([]);
  const [loading, setLoading] = useState(true);
  const [showCreateModal, setShowCreateModal] = useState(false);
  const [showEditModal, setShowEditModal] = useState(false);
  const [showDeleteDialog, setShowDeleteDialog] = useState(false);
  const [showPermissionsModal, setShowPermissionsModal] = useState(false);
  const [expandedModules, setExpandedModules] = useState({});
  const [savingPermissions, setSavingPermissions] = useState(false);
  const [formData, setFormData] = useState({
    code: '',
    name: '',
    description: '',
    permissions: []
  });

  const formatRoleSlug = (value) => (
    value
      .toLowerCase()
      .trim()
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/_+/g, '-')
      .replace(/^_+|_+$/g, '')
  );

  useEffect(() => {
    fetchRoles();
    fetchPermissions();
  }, []);

  const fetchRoles = async () => {
    try {
      const response = await api.get('/admin/roles');
      setRoles(response.data);
      setLoading(false);
    } catch (error) {
      toast.error('Failed to fetch roles');
      setLoading(false);
    }
  };

  const fetchPermissions = async () => {
    try {
      const response = await api.get('/admin/permissions');
      setPermissions(response.data);

      // Expand all modules by default
      const modules = [...new Set(response.data.map(p => p.module))];
      const expanded = {};
      modules.forEach(module => {
        expanded[module] = true;
      });
      setExpandedModules(expanded);
    } catch (error) {
      toast.error('Failed to fetch permissions');
    }
  };

  const fetchRolePermissions = async (roleId) => {
    try {
      const response = await api.get(`/admin/roles/${roleId}/permissions`);
      setRolePermissions(response.data.permissions);
      setSelectedPermissions(response.data.permissions.map(p => p.code));
    } catch (error) {
      toast.error('Failed to fetch role permissions');
    }
  };

  const handleCreateRole = async () => {
    try {
      await api.post('/admin/roles', {
        code: formData.code,
        name: formData.name,
        description: formData.description,
        permission_codes: formData.permissions
      });
      toast.success('Role created successfully');
      setShowCreateModal(false);
      setFormData({ code: '', name: '', description: '', permissions: [] });
      fetchRoles();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to create role');
    }
  };

  const handleUpdateRole = async () => {
    try {
      await api.put(`/admin/roles/${selectedRole.id}`, {
        name: formData.name,
        description: formData.description
      });
      toast.success('Role updated successfully');
      setShowEditModal(false);
      fetchRoles();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to update role');
    }
  };

  const handleDeleteRole = async () => {
    try {
      await api.delete(`/admin/roles/${selectedRole.id}`);
      toast.success('Role deleted successfully');
      setShowDeleteDialog(false);
      setSelectedRole(null);
      fetchRoles();
    } catch (error) {
      toast.error(error.response?.data?.detail || 'Failed to delete role');
    }
  };

  const handleSavePermissions = async () => {
    setSavingPermissions(true);
    try {
      await api.put(`/admin/roles/${selectedRole.id}/permissions`, {
        permission_codes: selectedPermissions
      });
      toast.success('Permissions updated successfully');
      setShowPermissionsModal(false);
      fetchRoles();
    } catch (error) {
      toast.error('Failed to update permissions');
    } finally {
      setSavingPermissions(false);
    }
  };

  const togglePermission = (permissionCode) => {
    setSelectedPermissions(prev => {
      if (prev.includes(permissionCode)) {
        return prev.filter(p => p !== permissionCode);
      } else {
        return [...prev, permissionCode];
      }
    });
  };

  const addPermissions = (permissionCodes) => {
    setSelectedPermissions(prev => [...new Set([...prev, ...permissionCodes])]);
  };

  const removePermissions = (permissionCodes) => {
    setSelectedPermissions(prev => prev.filter(code => !permissionCodes.includes(code)));
  };

  const toggleModule = (module) => {
    setExpandedModules(prev => ({
      ...prev,
      [module]: !prev[module]
    }));
  };

  const groupPermissionsByModule = () => {
    const grouped = {};
    permissions.forEach(perm => {
      if (!grouped[perm.module]) {
        grouped[perm.module] = [];
      }
      grouped[perm.module].push(perm);
    });
    return grouped;
  };

  if (loading) {
    return (
      <div className="flex justify-center items-center h-64">
        <div className="text-gray-500">Loading roles...</div>
      </div>
    );
  }

  const groupedPermissions = groupPermissionsByModule();

  return (
    <div className="space-y-6">
      {/* Action Bar */}
      <div className="flex justify-between items-center">
        <p className="text-muted-foreground">
          Create and manage custom roles with specific permissions
        </p>
        <Button className="btn-lavender" onClick={() => setShowCreateModal(true)}>
          <Plus className="w-4 h-4 mr-2" />
          Create Role
        </Button>
      </div>

      {/* Roles Grid */}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        {roles.map(role => (
          <Card key={role.id} className="p-6">
            <div className="flex items-start justify-between mb-4">
              <div className="flex items-center">
                <Shield className="w-5 h-5 text-blue-600 mr-2" />
                <div>
                  <h3 className="font-semibold">{role.name}</h3>
                  <p className="text-sm text-gray-500">{role.code}</p>
                </div>
              </div>
              {role.is_system_role && (
                <Lock className="w-4 h-4 text-gray-400" title="System Role" />
              )}
            </div>

            <p className="text-sm text-gray-600 mb-4 min-h-[40px]">
              {role.description || 'No description'}
            </p>

            <div className="flex items-center justify-between mb-4">
              <span className="text-sm text-gray-500">
                {role.permission_count} permissions
              </span>
            </div>

            <div className="flex gap-2">
              <Button
                size="sm"
                variant="outline"
                onClick={() => {
                  setSelectedRole(role);
                  fetchRolePermissions(role.id);
                  setShowPermissionsModal(true);
                }}
              >
                Manage Permissions
              </Button>
              {!role.is_system_role && (
                <>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => {
                      setSelectedRole(role);
                      setFormData({
                        name: role.name,
                        description: role.description || ''
                      });
                      setShowEditModal(true);
                    }}
                  >
                    <Edit className="w-3 h-3" />
                  </Button>
                  <Button
                    size="sm"
                    variant="destructive"
                    onClick={() => {
                      setSelectedRole(role);
                      setShowDeleteDialog(true);
                    }}
                  >
                    <Trash2 className="w-3 h-3" />
                  </Button>
                </>
              )}
            </div>
          </Card>
        ))}
      </div>

      {/* Create Role Modal */}
      <Dialog open={showCreateModal} onOpenChange={setShowCreateModal}>
        <DialogContent className="max-w-2xl max-h-[80vh] overflow-y-auto scrollbar-dashboard scrollbar-dashboard">
          <DialogHeader>
            <DialogTitle>Create New Role</DialogTitle>
            <DialogDescription>
              Create a custom role with specific permissions for your team members.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">

            <div>
              <Label>Role Name *</Label>
              <Input
                placeholder="e.g., Content Editor, Finance Manager"
                value={formData.name}
                onChange={(e) => {
                  const nextName = e.target.value;
                  setFormData(prev => {
                    const prevAuto = formatRoleSlug(prev.name);
                    const isAuto = !prev.code || prev.code === prevAuto;
                    return {
                      ...prev,
                      name: nextName,
                      code: isAuto ? formatRoleSlug(nextName) : prev.code
                    };
                  });
                }}
              />
            </div>
            <div>
              <Label>Role Slug *</Label>
              <Input
                placeholder="e.g., content_editor, finance_manager"
                value={formData.code}
                onChange={(e) => setFormData({ ...formData, code: e.target.value })}
              />
              <p className="text-xs text-gray-500 mt-1">
                Lowercase, no spaces. Used internally to identify the role.
              </p>
            </div>

            <div>
              <Label>Description</Label>
              <Textarea
                placeholder="Describe what this role can do..."
                value={formData.description}
                onChange={(e) => setFormData({ ...formData, description: e.target.value })}
              />
            </div>

            <div>
              <Label>Permissions</Label>
              <p className="text-sm text-gray-600 mb-3">
                Select permissions for this role. You can also add permissions later.
              </p>
              <div className="border rounded-lg p-4 max-h-64 overflow-y-auto scrollbar-dashboard">
                {Object.entries(groupedPermissions).map(([module, perms]) => {
                  const moduleCodes = perms.map(perm => perm.code);
                  const selectedCount = moduleCodes.filter(code => formData.permissions.includes(code)).length;
                  const hasPermissions = moduleCodes.length > 0;
                  const isAllSelected = hasPermissions && selectedCount === moduleCodes.length;
                  const isNoneSelected = selectedCount === 0;

                  return (
                    <div key={module} className="mb-4">
                      <div className="flex items-center justify-between mb-2">
                        <button
                          type="button"
                          onClick={() => toggleModule(module)}
                          className="flex items-center text-left font-medium hover:text-blue-600"
                        >
                          {expandedModules[module] ? (
                            <ChevronUp className="w-4 h-4 mr-1" />
                          ) : (
                            <ChevronDown className="w-4 h-4 mr-1" />
                          )}
                          {module.charAt(0).toUpperCase() + module.slice(1)} ({perms.length})
                        </button>
                        <div className="flex items-center gap-3">
                          <button
                            type="button"
                            onClick={() => {
                              setFormData(prev => ({
                                ...prev,
                                permissions: [...new Set([...prev.permissions, ...moduleCodes])]
                              }));
                            }}
                            disabled={!hasPermissions || isAllSelected}
                            className="text-xs font-medium text-gray-500 hover:text-brand-purple disabled:opacity-50 disabled:cursor-not-allowed"
                          >
                            Select all
                          </button>
                          <button
                            type="button"
                            onClick={() => {
                              setFormData(prev => ({
                                ...prev,
                                permissions: prev.permissions.filter(code => !moduleCodes.includes(code))
                              }));
                            }}
                            disabled={!hasPermissions || isNoneSelected}
                            className="text-xs font-medium text-gray-500 hover:text-brand-purple disabled:opacity-50 disabled:cursor-not-allowed"
                          >
                            Deselect all
                          </button>
                        </div>
                      </div>
                      {expandedModules[module] && (
                        <div className="space-y-2 ml-5">
                          {perms.map(perm => (
                            <div key={perm.code} className="flex items-center">
                              <Checkbox
                                checked={formData.permissions.includes(perm.code)}
                                onCheckedChange={() => {
                                  setFormData(prev => ({
                                    ...prev,
                                    permissions: prev.permissions.includes(perm.code)
                                      ? prev.permissions.filter(p => p !== perm.code)
                                      : [...prev.permissions, perm.code]
                                  }));
                                }}
                              />
                              <label className="ml-2 text-sm">
                                <span className="font-medium">{perm.name}</span>
                                <span className="text-gray-500 ml-2">({perm.code})</span>
                              </label>
                            </div>
                          ))}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setShowCreateModal(false)}>
              Cancel
            </Button>
            <Button onClick={handleCreateRole}>
              Create Role
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Edit Role Modal */}
      <Dialog open={showEditModal} onOpenChange={setShowEditModal}>
        <DialogContent >
          <DialogHeader>
            <DialogTitle>Edit Role</DialogTitle>
            <DialogDescription>
              Update role name and description. Code cannot be changed.
            </DialogDescription>
          </DialogHeader>

          <div className="space-y-4">

            <div>
              <Label>Role Name *</Label>
              <Input
                value={formData.name}
                onChange={(e) => setFormData({ ...formData, name: e.target.value })}
              />
            </div>

            <div>
              <Label>Role Slug</Label>
              <Input value={selectedRole?.code || ''} disabled />
            </div>

            <div>
              <Label>Description</Label>
              <Textarea
                value={formData.description}
                onChange={(e) => setFormData({ ...formData, description: e.target.value })}
              />
            </div>
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setShowEditModal(false)}>
              Cancel
            </Button>
            <Button onClick={handleUpdateRole}>
              Save Changes
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Manage Permissions Modal */}
      <Dialog open={showPermissionsModal} onOpenChange={setShowPermissionsModal}>
        <DialogContent className="max-w-3xl max-h-[80vh] overflow-y-auto scrollbar-dashboard">
          <DialogHeader>
            <DialogTitle>Manage Permissions: {selectedRole?.name}</DialogTitle>
            <DialogDescription>
              Select which permissions this role should have.
            </DialogDescription>
          </DialogHeader>

          <div className="border rounded-lg p-4">
            {Object.entries(groupedPermissions).map(([module, perms]) => {
              const moduleCodes = perms.map(perm => perm.code);
              const selectedCount = moduleCodes.filter(code => selectedPermissions.includes(code)).length;
              const hasPermissions = moduleCodes.length > 0;
              const isAllSelected = hasPermissions && selectedCount === moduleCodes.length;
              const isNoneSelected = selectedCount === 0;

              return (
                <div key={module} className="mb-6">
                  <div className="flex items-center justify-between mb-3">
                    <button
                      type="button"
                      onClick={() => toggleModule(module)}
                      className="flex items-center text-left font-medium text-lg hover:text-blue-600"
                    >
                      {expandedModules[module] ? (
                        <ChevronUp className="w-5 h-5 mr-2" />
                      ) : (
                        <ChevronDown className="w-5 h-5 mr-2" />
                      )}
                      {module.charAt(0).toUpperCase() + module.slice(1)} ({perms.length})
                    </button>
                    <div className="flex items-center gap-3">
                      <button
                        type="button"
                        onClick={() => addPermissions(moduleCodes)}
                        disabled={!hasPermissions || isAllSelected}
                        className="text-xs font-medium text-gray-500 hover:text-brand-purple disabled:opacity-50 disabled:cursor-not-allowed"
                      >
                        Select all
                      </button>
                      <button
                        type="button"
                        onClick={() => removePermissions(moduleCodes)}
                        disabled={!hasPermissions || isNoneSelected}
                        className="text-xs font-medium text-gray-500 hover:text-brand-purple disabled:opacity-50 disabled:cursor-not-allowed"
                      >
                        Deselect all
                      </button>
                    </div>
                  </div>
                  {expandedModules[module] && (
                    <div className="space-y-3 ml-7">
                      {perms.map(perm => (
                        <div key={perm.code} className="flex items-start">
                          <Checkbox
                            checked={selectedPermissions.includes(perm.code)}
                            onCheckedChange={() => togglePermission(perm.code)}
                          />
                          <div className="ml-3">
                            <label className="font-medium text-sm">
                              {perm.name}
                            </label>
                            <p className="text-xs text-gray-500">{perm.description}</p>
                            <span className="text-xs text-gray-400">{perm.code}</span>
                          </div>
                        </div>
                      ))}
                    </div>
                  )}
                </div>
              );
            })}
          </div>

          <DialogFooter>
            <Button variant="outline" onClick={() => setShowPermissionsModal(false)}>
              Cancel
            </Button>
            <Button onClick={handleSavePermissions} disabled={savingPermissions}>
              {savingPermissions ? 'Saving...' : 'Save Permissions'}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete Confirmation */}
      <AlertDialog open={showDeleteDialog} onOpenChange={setShowDeleteDialog}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete Role?</AlertDialogTitle>
            <AlertDialogDescription>
              Are you sure you want to delete the role "{selectedRole?.name}"?
              This action cannot be undone. Users with this role will need to be reassigned.
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction onClick={handleDeleteRole} className="bg-red-600">
              Delete Role
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>

      {savingPermissions && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40">
          <div className="bg-white rounded-xl shadow-lg px-6 py-5 text-center">
            <div className="mx-auto h-10 w-10 animate-spin rounded-full border-4 border-[var(--neutral-800)] border-t-transparent" />
            <p className="mt-4 text-sm font-medium text-gray-700">Saving permissions...</p>
          </div>
        </div>
      )}
    </div>
  );
};

export default AdminRoles;
