"use client";

import { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { sanitizeInput } from "@/core/security/sanitize";
import { Plus, Pencil, Trash2, Shield } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
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,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
  DialogFooter,
  DialogClose,
} from "@/components/ui/dialog";
import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Badge } from "@/components/ui/badge";
import { useToastEnhanced } from "@/hooks/use-toast-enhanced";
import {
  createRoleSchema,
  type CreateRoleInput,
} from "@/lib/validations/roles";
import {
  rolesDataStore,
  getPermissionsByCategory,
  type Role,
} from "@/roles/admin/services/roles.service";

export function ManageRolesClient() {
  const [roles, setRoles] = useState<Role[]>([]);
  const [isDialogOpen, setIsDialogOpen] = useState(false);
  const [editingRole, setEditingRole] = useState<Role | null>(null);
  const [selectedPermissions, setSelectedPermissions] = useState<string[]>([]);
  const toast = useToastEnhanced();

  const permissionsByCategory = getPermissionsByCategory();

  const {
    register,
    handleSubmit,
    reset,
    setValue,
    formState: { errors, isSubmitting },
  } = useForm<CreateRoleInput>({
    resolver: zodResolver(createRoleSchema),
    defaultValues: {
      name: "",
      description: "",
      permissions: [],
    },
  });

  useEffect(() => {
    setRoles(rolesDataStore.getAllRoles());
  }, []);

  useEffect(() => {
    setValue("permissions", selectedPermissions);
  }, [selectedPermissions, setValue]);

  const handlePermissionToggle = (permissionId: string) => {
    setSelectedPermissions((prev) =>
      prev.includes(permissionId)
        ? prev.filter((p) => p !== permissionId)
        : [...prev, permissionId]
    );
  };

  const handleSelectAllCategory = (category: string, permissions: string[]) => {
    const allSelected = permissions.every((p) =>
      selectedPermissions.includes(p)
    );
    if (allSelected) {
      setSelectedPermissions((prev) =>
        prev.filter((p) => !permissions.includes(p))
      );
    } else {
      setSelectedPermissions((prev) => [
        ...prev,
        ...permissions.filter((p) => !prev.includes(p)),
      ]);
    }
  };

  const openCreateDialog = () => {
    setEditingRole(null);
    setSelectedPermissions([]);
    reset({ name: "", description: "", permissions: [] });
    setIsDialogOpen(true);
  };

  const openEditDialog = (role: Role) => {
    setEditingRole(role);
    setSelectedPermissions(role.permissions);
    reset({
      name: role.name,
      description: role.description,
      permissions: role.permissions,
    });
    setIsDialogOpen(true);
  };

  const onSubmit = async (data: CreateRoleInput) => {
    const sanitizedData = {
      name: sanitizeInput(data.name),
      description: sanitizeInput(data.description),
      permissions: data.permissions,
    };

    if (editingRole) {
      rolesDataStore.updateRole(editingRole.id, sanitizedData);
      toast.success({
        title: "Role updated",
        description: `${sanitizedData.name} has been updated successfully.`,
      });
    } else {
      rolesDataStore.createRole(sanitizedData);
      toast.success({
        title: "Role created",
        description: `${sanitizedData.name} has been created successfully.`,
      });
    }

    setRoles(rolesDataStore.getAllRoles());
    setIsDialogOpen(false);
    reset();
    setSelectedPermissions([]);
    setEditingRole(null);
  };

  const handleDelete = (role: Role) => {
    rolesDataStore.deleteRole(role.id);
    setRoles(rolesDataStore.getAllRoles());
    toast.error({
      title: "Role deleted",
      description: `${role.name} has been deleted.`,
    });
  };

  return (
    <section aria-labelledby="roles-section" className="space-y-6">
      <div className="flex justify-end">
        <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
          <DialogTrigger asChild>
            <Button
              onClick={openCreateDialog}
              className="rounded-xl shadow-lg shadow-primary/25"
            >
              <Plus className="h-4 w-4 mr-2" aria-hidden="true" />
              Add New Role
            </Button>
          </DialogTrigger>
          <DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
            <DialogHeader>
              <DialogTitle>
                {editingRole ? "Edit Role" : "Create New Role"}
              </DialogTitle>
              <DialogDescription>
                {editingRole
                  ? "Update the role details and permissions."
                  : "Define a new role with specific permissions."}
              </DialogDescription>
            </DialogHeader>
            <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
              <div className="space-y-4">
                <div className="space-y-2">
                  <Label htmlFor="name">Role Name</Label>
                  <Input
                    id="name"
                    placeholder="e.g., Content Editor"
                    {...register("name")}
                    className="rounded-xl"
                    aria-describedby={errors.name ? "name-error" : undefined}
                  />
                  {errors.name && (
                    <p id="name-error" className="text-sm text-destructive">
                      {errors.name.message}
                    </p>
                  )}
                </div>

                <div className="space-y-2">
                  <Label htmlFor="description">Description</Label>
                  <Textarea
                    id="description"
                    placeholder="Describe the purpose of this role..."
                    {...register("description")}
                    className="rounded-xl"
                    aria-describedby={
                      errors.description ? "description-error" : undefined
                    }
                  />
                  {errors.description && (
                    <p
                      id="description-error"
                      className="text-sm text-destructive"
                    >
                      {errors.description.message}
                    </p>
                  )}
                </div>

                <div className="space-y-4">
                  <Label>Permissions</Label>
                  {errors.permissions && (
                    <p className="text-sm text-destructive">
                      {errors.permissions.message}
                    </p>
                  )}
                  <div className="space-y-4 border rounded-xl p-4 bg-muted/30">
                    {Object.entries(permissionsByCategory).map(
                      ([category, permissions]) => {
                        const categoryPermissionIds = permissions.map(
                          (p) => p.id
                        );
                        const allSelected = categoryPermissionIds.every((id) =>
                          selectedPermissions.includes(id)
                        );
                        const someSelected =
                          !allSelected &&
                          categoryPermissionIds.some((id) =>
                            selectedPermissions.includes(id)
                          );

                        return (
                          <div key={category} className="space-y-2">
                            <div className="flex items-center gap-2">
                              <Checkbox
                                id={`category-${category}`}
                                checked={allSelected}
                                ref={
                                  someSelected
                                    ? (el) => el && (el.indeterminate = true)
                                    : undefined
                                }
                                onCheckedChange={() =>
                                  handleSelectAllCategory(
                                    category,
                                    categoryPermissionIds
                                  )
                                }
                              />
                              <Label
                                htmlFor={`category-${category}`}
                                className="font-semibold cursor-pointer"
                              >
                                {category}
                              </Label>
                            </div>
                            <div className="grid grid-cols-1 sm:grid-cols-2 gap-2 ml-6">
                              {permissions.map((permission) => (
                                <div
                                  key={permission.id}
                                  className="flex items-start gap-2"
                                >
                                  <Checkbox
                                    id={permission.id}
                                    checked={selectedPermissions.includes(
                                      permission.id
                                    )}
                                    onCheckedChange={() =>
                                      handlePermissionToggle(permission.id)
                                    }
                                  />
                                  <div className="grid gap-0.5">
                                    <Label
                                      htmlFor={permission.id}
                                      className="text-sm font-normal cursor-pointer"
                                    >
                                      {permission.name}
                                    </Label>
                                    <p className="text-xs text-muted-foreground">
                                      {permission.description}
                                    </p>
                                  </div>
                                </div>
                              ))}
                            </div>
                          </div>
                        );
                      }
                    )}
                  </div>
                </div>
              </div>

              <DialogFooter>
                <DialogClose asChild>
                  <Button
                    type="button"
                    variant="outline"
                    className="rounded-xl bg-transparent"
                  >
                    Cancel
                  </Button>
                </DialogClose>
                <Button
                  type="submit"
                  disabled={isSubmitting}
                  className="rounded-xl"
                >
                  {isSubmitting
                    ? "Saving..."
                    : editingRole
                      ? "Update Role"
                      : "Create Role"}
                </Button>
              </DialogFooter>
            </form>
          </DialogContent>
        </Dialog>
      </div>

      <div className="grid gap-4 md:grid-cols-2">
        {roles.map((role) => (
          <Card key={role.id} className="admin-card rounded-xl border-0">
            <CardHeader className="flex flex-row items-start justify-between space-y-0 pb-2">
              <div className="space-y-1">
                <CardTitle className="flex items-center gap-2 text-lg">
                  <div className="h-8 w-8 rounded-lg bg-gradient-to-br from-primary/20 to-primary/5 flex items-center justify-center">
                    <Shield
                      className="h-4 w-4 text-primary"
                      aria-hidden="true"
                    />
                  </div>
                  {role.name}
                </CardTitle>
                <CardDescription>{role.description}</CardDescription>
              </div>
              <div className="flex gap-1">
                <Button
                  variant="ghost"
                  size="icon"
                  onClick={() => openEditDialog(role)}
                  className="rounded-lg hover:bg-muted"
                  aria-label={`Edit ${role.name}`}
                >
                  <Pencil className="h-4 w-4" aria-hidden="true" />
                </Button>
                <AlertDialog>
                  <AlertDialogTrigger asChild>
                    <Button
                      variant="ghost"
                      size="icon"
                      className="rounded-lg hover:bg-destructive/10 hover:text-destructive"
                      aria-label={`Delete ${role.name}`}
                    >
                      <Trash2 className="h-4 w-4" aria-hidden="true" />
                    </Button>
                  </AlertDialogTrigger>
                  <AlertDialogContent>
                    <AlertDialogHeader>
                      <AlertDialogTitle>Delete Role</AlertDialogTitle>
                      <AlertDialogDescription>
                        Are you sure you want to delete &quot;{role.name}&quot;?
                        This action cannot be undone.
                      </AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                      <AlertDialogCancel className="rounded-xl">
                        Cancel
                      </AlertDialogCancel>
                      <AlertDialogAction
                        onClick={() => handleDelete(role)}
                        className="bg-destructive text-destructive-foreground hover:bg-destructive/90 rounded-xl"
                      >
                        Delete
                      </AlertDialogAction>
                    </AlertDialogFooter>
                  </AlertDialogContent>
                </AlertDialog>
              </div>
            </CardHeader>
            <CardContent>
              <div className="flex flex-wrap gap-1">
                <Badge variant="secondary" className="text-xs rounded-lg">
                  {role.permissions.length} permission
                  {role.permissions.length !== 1 ? "s" : ""}
                </Badge>
              </div>
            </CardContent>
          </Card>
        ))}
      </div>
    </section>
  );
}
