'use client';

import * as React from 'react';
import { useParams, useRouter } from 'next/navigation';
import {
  assignPermissionsToRole,
  fetchPermissions,
  unassignPermissionsFromRole,
} from '@/network/apis/dashboard/permissions/permissions.apis';
import { fetchRoleById } from '@/modules/Roles/apis/roles.apis';
import {
  RiCheckboxCircleFill,
  RiErrorWarningFill,
  RiDeleteBin6Line,
  RiArrowLeftLine,
  RiEditLine,
  RiShieldCheckLine,
  RiAddLine,
  RiCloseLine,
} from '@remixicon/react';
import { useMutation, useQuery } from '@tanstack/react-query';
import { toast } from 'sonner';
import { Alert, AlertIcon, AlertTitle } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from '@/components/ui/dialog';
import { useDeleteRole } from '../../hooks/useDeleteRole';

type Permission = {
  id: number;
  name: string;
  name_en: string;
  name_ar: string;
  section: string;
  section_ar: string;
};

type Role = {
  id: number;
  name: string;
  name_ar: string;
  permissions: Permission[];
};

type PermissionItem = {
  id: number;
  name: string;
  name_en: string;
  name_ar: string;
};

type PermissionSection = {
  section: { en: string; ar: string };
  permissions: PermissionItem[];
};

export default function RoleDetails() {
  const router = useRouter();
  const params = useParams();
  const id = params?.id ? String(params.id) : undefined;
  const [isDeleteDialogOpen, setIsDeleteDialogOpen] = React.useState(false);
  const [showAssignPanel, setShowAssignPanel] = React.useState(false);

  const { mutate: deleteRole, isPending: isDeleting } = useDeleteRole();

  const {
    data: roleDetails,
    isLoading,
    isError,
    error,
    refetch,
  } = useQuery({
    queryKey: ['role_details', id],
    queryFn: async () => {
      if (!id) return;
      return await fetchRoleById(id);
    },
    enabled: !!id,
  });

  const { data: allSections } = useQuery({
    queryKey: ['all_permissions'],
    queryFn: async () => {
      const res = await fetchPermissions();
      return res ?? [];
    },
  });

  const [pendingPerms, setPendingPerms] = React.useState<string[]>([]);
  const [selectedPerm, setSelectedPerm] = React.useState<string>('');

  const assignedKeys = React.useMemo(() => {
    return new Set((roleDetails?.permissions ?? []).map((p) => p.name));
  }, [roleDetails]);

  const assignMutation = useMutation({
    mutationFn: async (perms: string[]) => {
      if (!id || perms.length === 0) return;
      await assignPermissionsToRole(id, perms);
    },
    onSuccess: () => {
      toast.custom(
        () => (
          <Alert variant="mono" icon="success" close={false}>
            <AlertIcon><RiCheckboxCircleFill /></AlertIcon>
            <AlertTitle>Permissions assigned successfully</AlertTitle>
          </Alert>
        ),
        { position: 'top-center' },
      );
      setPendingPerms([]);
      setSelectedPerm('');
      setShowAssignPanel(false);
      refetch();
    },
    onError: (err: unknown) => {
      toast.custom(
        () => (
          <Alert variant="mono" icon="destructive" close={false}>
            <AlertIcon><RiErrorWarningFill /></AlertIcon>
            <AlertTitle>{err instanceof Error ? err.message : 'Failed to assign'}</AlertTitle>
          </Alert>
        ),
        { position: 'top-center' },
      );
    },
  });

  const handleAssign = () => {
    const extra =
      selectedPerm && !pendingPerms.includes(selectedPerm) ? [selectedPerm] : [];
    const finalSet = new Set<string>([
      ...Array.from(assignedKeys),
      ...pendingPerms,
      ...extra,
    ]);
    const payload = Array.from(finalSet);
    if (payload.length) assignMutation.mutate(payload);
  };

  const unassignMutation = useMutation({
    mutationFn: async () => {
      if (!id) return;
      await unassignPermissionsFromRole(id);
    },
    onSuccess: () => {
      toast.custom(
        () => (
          <Alert variant="mono" icon="success" close={false}>
            <AlertIcon><RiCheckboxCircleFill /></AlertIcon>
            <AlertTitle>All permissions removed from role</AlertTitle>
          </Alert>
        ),
        { position: 'top-center' },
      );
      refetch();
    },
    onError: (err: unknown) => {
      toast.custom(
        () => (
          <Alert variant="mono" icon="destructive" close={false}>
            <AlertIcon><RiErrorWarningFill /></AlertIcon>
            <AlertTitle>{err instanceof Error ? err.message : 'Failed to remove'}</AlertTitle>
          </Alert>
        ),
        { position: 'top-center' },
      );
    },
  });

  const handleDeleteRole = () => {
    if (!id) return;
    deleteRole(id, {
      onSuccess: () => {
        toast.custom(
          () => (
            <Alert variant="mono" icon="success" close={false}>
              <AlertIcon><RiCheckboxCircleFill /></AlertIcon>
              <AlertTitle>Role deleted successfully</AlertTitle>
            </Alert>
          ),
          { position: 'top-center' },
        );
        setIsDeleteDialogOpen(false);
        router.push('/roles');
      },
      onError: (err: unknown) => {
        toast.custom(
          () => (
            <Alert variant="mono" icon="destructive" close={false}>
              <AlertIcon><RiErrorWarningFill /></AlertIcon>
              <AlertTitle>{err instanceof Error ? err.message : 'Failed to delete role'}</AlertTitle>
            </Alert>
          ),
          { position: 'top-center' },
        );
      },
    });
  };

  if (!id) {
    return <div className="p-6 text-sm text-muted-foreground">No role id provided.</div>;
  }

  if (isLoading) {
    return (
      <div className="flex items-center justify-center py-20">
        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
      </div>
    );
  }

  if (isError) {
    return (
      <div className="p-6 text-sm text-destructive">
        Failed to load role: {(error as Error)?.message ?? 'Unknown error'}
      </div>
    );
  }

  const role: Role | undefined = roleDetails;
  if (!role) return <div className="p-6 text-sm">Role not found.</div>;

  const sectionsMap =
    role.permissions?.reduce<Record<string, Permission[]>>((acc, p) => {
      const key = p.section || 'Other';
      (acc[key] ||= []).push(p);
      return acc;
    }, {}) || {};

  const pendingKeys = new Set(pendingPerms);

  const allPermissionOptions =
    (allSections ?? []).flatMap((sec: PermissionSection) =>
      sec.permissions.map((p) => ({
        value: p.name,
        label: p.name_en || p.name,
        section: sec.section.en,
      })),
    ) ?? [];

  const selectableOptions = allPermissionOptions.filter(
    (opt) => !assignedKeys.has(opt.value) && !pendingKeys.has(opt.value),
  );

  const addSelectedToPending = () => {
    if (!selectedPerm) return;
    if (pendingPerms.includes(selectedPerm)) return;
    setPendingPerms((s) => [...s, selectedPerm]);
    setSelectedPerm('');
  };

  const removePending = (name: string) => {
    setPendingPerms((s) => s.filter((p) => p !== name));
  };

  return (
    <div className="max-w-5xl mx-auto space-y-6">
      <div className="flex items-center justify-between">
        <div className="flex items-center gap-3">
          <Button variant="ghost" size="sm" onClick={() => router.push('/roles')}>
            <RiArrowLeftLine className="size-4" />
          </Button>
          <div>
            <h1 className="text-2xl font-bold tracking-tight">{role.name}</h1>
            <p className="text-muted-foreground text-sm">{role.name_ar}</p>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <Button variant="outline" onClick={() => router.push(`/roles/add/${id}`)}>
            <RiEditLine className="size-4 mr-1.5" />
            Edit
          </Button>
          <Button
            variant="outline"
            onClick={() => unassignMutation.mutate()}
            disabled={unassignMutation.isPending || !role.permissions?.length}
          >
            {unassignMutation.isPending ? 'Removing...' : 'Clear Permissions'}
          </Button>
          <Dialog open={isDeleteDialogOpen} onOpenChange={setIsDeleteDialogOpen}>
            <DialogTrigger asChild>
              <Button variant="outline" size="sm">
                <RiDeleteBin6Line className="size-4 text-destructive" />
              </Button>
            </DialogTrigger>
            <DialogContent>
              <DialogHeader>
                <DialogTitle>Delete Role</DialogTitle>
                <DialogDescription>
                  Are you sure you want to delete the role &ldquo;{role.name}&rdquo;? This action
                  cannot be undone.
                </DialogDescription>
              </DialogHeader>
              <DialogFooter>
                <Button
                  variant="outline"
                  onClick={() => setIsDeleteDialogOpen(false)}
                  disabled={isDeleting}
                >
                  Cancel
                </Button>
                <Button
                  variant="destructive"
                  onClick={handleDeleteRole}
                  disabled={isDeleting}
                >
                  {isDeleting ? 'Deleting...' : 'Delete Role'}
                </Button>
              </DialogFooter>
            </DialogContent>
          </Dialog>
        </div>
      </div>

      <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
        <Card>
          <CardContent className="flex items-center gap-4 p-5">
            <div className="flex items-center justify-center size-11 rounded-xl bg-primary/10">
              <RiShieldCheckLine className="size-5 text-primary" />
            </div>
            <div>
              <p className="text-2xl font-bold">{role.permissions?.length ?? 0}</p>
              <p className="text-xs text-muted-foreground">Total Permissions</p>
            </div>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="flex items-center gap-4 p-5">
            <div className="flex items-center justify-center size-11 rounded-xl bg-green-500/10">
              <RiShieldCheckLine className="size-5 text-green-600" />
            </div>
            <div>
              <p className="text-2xl font-bold">{Object.keys(sectionsMap).length}</p>
              <p className="text-xs text-muted-foreground">Sections Covered</p>
            </div>
          </CardContent>
        </Card>
        <Card>
          <CardContent className="flex items-center gap-4 p-5">
            <div className="flex items-center justify-center size-11 rounded-xl bg-violet-500/10">
              <RiShieldCheckLine className="size-5 text-violet-600" />
            </div>
            <div>
              <p className="text-2xl font-bold">{selectableOptions.length}</p>
              <p className="text-xs text-muted-foreground">Available to Add</p>
            </div>
          </CardContent>
        </Card>
      </div>

      <Card>
        <CardHeader className="flex-row items-center justify-between">
          <CardTitle className="text-base">Assigned Permissions</CardTitle>
          <Button
            variant="outline"
            size="sm"
            onClick={() => setShowAssignPanel(!showAssignPanel)}
          >
            <RiAddLine className="size-4 mr-1" />
            {showAssignPanel ? 'Hide' : 'Add Permissions'}
          </Button>
        </CardHeader>
        <CardContent>
          {showAssignPanel && (
            <div className="mb-6 p-4 border rounded-xl bg-accent/20 space-y-3">
              <div className="flex flex-wrap items-center gap-3">
                <Select value={selectedPerm} onValueChange={setSelectedPerm}>
                  <SelectTrigger className="min-w-[300px]">
                    <SelectValue placeholder="Select a permission to add" />
                  </SelectTrigger>
                  <SelectContent className="max-h-80">
                    {selectableOptions.length === 0 ? (
                      <div className="px-2 py-2 text-sm text-muted-foreground">
                        All permissions are already assigned
                      </div>
                    ) : (
                      selectableOptions.map((opt) => (
                        <SelectItem key={opt.value} value={opt.value}>
                          {opt.label}{' '}
                          <span className="text-muted-foreground text-xs">
                            — {opt.section}
                          </span>
                        </SelectItem>
                      ))
                    )}
                  </SelectContent>
                </Select>
                <Button type="button" variant="outline" size="sm" onClick={addSelectedToPending}>
                  Add to Queue
                </Button>
                <Button
                  type="button"
                  size="sm"
                  onClick={handleAssign}
                  disabled={
                    assignMutation.isPending ||
                    (!selectedPerm && pendingPerms.length === 0)
                  }
                >
                  {assignMutation.isPending ? 'Assigning...' : 'Save Changes'}
                </Button>
              </div>
              {pendingPerms.length > 0 && (
                <div className="flex flex-wrap gap-2">
                  {pendingPerms.map((p) => (
                    <Badge key={p} variant="info" className="flex items-center gap-1.5 pr-1">
                      {p}
                      <button
                        type="button"
                        className="hover:bg-white/20 rounded-full p-0.5"
                        onClick={() => removePending(p)}
                      >
                        <RiCloseLine className="size-3" />
                      </button>
                    </Badge>
                  ))}
                </div>
              )}
            </div>
          )}

          {Object.keys(sectionsMap).length > 0 ? (
            <div className="space-y-4">
              {Object.entries(sectionsMap).map(([section, perms]) => (
                <div key={section} className="border rounded-xl overflow-hidden">
                  <div className="px-4 py-2.5 bg-accent/40 flex items-center justify-between">
                    <div className="flex items-center gap-2">
                      <RiShieldCheckLine className="size-4 text-muted-foreground" />
                      <span className="font-medium text-sm">{section}</span>
                    </div>
                    <Badge variant="mono" appearance="outline" className="text-xs">
                      {perms.length} permission{perms.length !== 1 ? 's' : ''}
                    </Badge>
                  </div>
                  <div className="p-4">
                    <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-2">
                      {perms.map((p) => (
                        <div
                          key={p.id}
                          className="flex items-start gap-2 p-2.5 rounded-lg border bg-accent/10"
                        >
                          <RiCheckboxCircleFill className="size-4 text-green-500 mt-0.5 shrink-0" />
                          <div className="min-w-0">
                            <p className="text-sm font-medium truncate">
                              {p.name_en}
                            </p>
                            <p className="text-xs text-muted-foreground truncate">
                              {p.name_ar}
                            </p>
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="text-center py-12 text-muted-foreground">
              <RiShieldCheckLine className="size-12 mx-auto mb-3 opacity-30" />
              <p className="text-sm">No permissions assigned to this role yet.</p>
              <p className="text-xs mt-1">
                Click &ldquo;Add Permissions&rdquo; above to get started.
              </p>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
