"use client"

import { useState, useEffect } from "react"
import { useForm } from "react-hook-form"
import { zodResolver } from "@hookform/resolvers/zod"
import { sanitizeInput } from "@/lib/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 "@/lib/data/roles"

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 "{role.name}"? 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>
  )
}
