import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { vaultCategoryPermissionsOptions, vaultCategoryMutations, vaultKeys } from '@/api/vault'
import { roleListOptions } from '@/api/rbac'
import { userListOptions } from '@/api/users'
import type { UserRecord } from '@/api/users'
import type { Role } from '@/types/rbac'
import type { VaultCategoryPermission } from '@/types/vault'
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Label } from '@/components/ui/label'
import { Switch } from '@/components/ui/switch'
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'
import { Trash2, Shield, Users, User } from 'lucide-react'
import { toast } from 'sonner'

interface Props {
  categoryId: string
  categoryName: string
  isPublic: boolean
  open: boolean
  onOpenChange: (open: boolean) => void
}

const ACCESS_LEVELS = [
  { value: 'view', label: 'View', variant: 'secondary' as const },
  { value: 'edit', label: 'Edit', variant: 'default' as const },
  { value: 'admin', label: 'Admin', variant: 'destructive' as const },
]

export function CategoryPermissionsDialog({ categoryId, categoryName, isPublic, open, onOpenChange }: Props) {
  const queryClient = useQueryClient()
  const [assigneeType, setAssigneeType] = useState<'role' | 'user'>('role')
  const [assigneeId, setAssigneeId] = useState('')
  const [accessLevel, setAccessLevel] = useState('view')

  const { data: permissionsData, isLoading: permsLoading } = useQuery({
    ...vaultCategoryPermissionsOptions(categoryId),
    enabled: open && !!categoryId,
  })
  const { data: rolesData } = useQuery({ ...roleListOptions(), enabled: open })
  const { data: usersData } = useQuery({
    ...userListOptions({ page: 1, limit: 100, order: 'asc' }),
    enabled: open && assigneeType === 'user',
  })

  const permissions = permissionsData?.data ?? []
  const roles = rolesData?.data ?? []
  const users = usersData?.data ?? []

  const togglePublicMutation = useMutation({
    mutationFn: (newIsPublic: boolean) => vaultCategoryMutations.update(categoryId, { isPublic: newIsPublic }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: vaultKeys.categories })
      queryClient.invalidateQueries({ queryKey: vaultKeys.categoryDetail(categoryId) })
      toast.success(isPublic ? 'Category set to private' : 'Category set to public')
    },
    onError: (err) => toast.error(err.message),
  })

  const addPermissionMutation = useMutation({
    mutationFn: () => vaultCategoryMutations.addPermission(categoryId, {
      ...(assigneeType === 'role' ? { roleId: assigneeId } : { userId: assigneeId }),
      accessLevel,
    }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: vaultKeys.categoryPermissions(categoryId) })
      setAssigneeId('')
      setAccessLevel('view')
      toast.success('Permission added')
    },
    onError: (err) => toast.error(err.message),
  })

  const removePermissionMutation = useMutation({
    mutationFn: (permId: string) => vaultCategoryMutations.removePermission(permId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: vaultKeys.categoryPermissions(categoryId) })
      toast.success('Permission removed')
    },
    onError: (err) => toast.error(err.message),
  })

  function getPermissionLabel(perm: VaultCategoryPermission) {
    if (perm.roleId) {
      const role = roles.find((r: Role) => r.id === perm.roleId)
      return { icon: Users, name: role?.name ?? 'Unknown role' }
    }
    const user = users.find((u: UserRecord) => u.id === perm.userId)
    return { icon: User, name: user ? `${user.firstName} ${user.lastName}` : 'Unknown user' }
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Shield className="h-4 w-4" />
            Permissions — {categoryName}
          </DialogTitle>
        </DialogHeader>

        <div className="space-y-5">
          <div className="flex items-center justify-between rounded-lg border p-3">
            <div>
              <Label className="text-sm font-medium">Public category</Label>
              <p className="text-xs text-muted-foreground mt-0.5">Public categories are viewable by all users with vault access</p>
            </div>
            <Switch checked={isPublic} onCheckedChange={(checked) => togglePublicMutation.mutate(checked)} disabled={togglePublicMutation.isPending} />
          </div>

          <div>
            <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Permissions</Label>
            <div className="mt-2 space-y-1.5">
              {permsLoading ? (
                <p className="text-sm text-muted-foreground">Loading...</p>
              ) : permissions.length === 0 ? (
                <p className="text-sm text-muted-foreground">No specific permissions assigned</p>
              ) : (
                permissions.map((perm) => {
                  const { icon: Icon, name } = getPermissionLabel(perm)
                  const level = ACCESS_LEVELS.find((l) => l.value === perm.accessLevel)
                  return (
                    <div key={perm.id} className="flex items-center justify-between rounded-md border px-3 py-2">
                      <div className="flex items-center gap-2 min-w-0">
                        <Icon className="h-3.5 w-3.5 shrink-0 text-muted-foreground" />
                        <span className="text-sm truncate">{name}</span>
                      </div>
                      <div className="flex items-center gap-2 shrink-0">
                        <Badge variant={level?.variant ?? 'secondary'} className="text-xs">{level?.label ?? perm.accessLevel}</Badge>
                        <button type="button" onClick={() => removePermissionMutation.mutate(perm.id)} className="text-muted-foreground hover:text-destructive transition-colors" disabled={removePermissionMutation.isPending}>
                          <Trash2 className="h-3.5 w-3.5" />
                        </button>
                      </div>
                    </div>
                  )
                })
              )}
            </div>
          </div>

          <form onSubmit={(e) => { e.preventDefault(); if (assigneeId) addPermissionMutation.mutate() }} className="space-y-3">
            <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">Add Permission</Label>
            <div className="flex gap-1 rounded-md border p-0.5">
              <button type="button" onClick={() => { setAssigneeType('role'); setAssigneeId('') }} className={`flex-1 rounded-sm px-3 py-1.5 text-sm font-medium transition-colors ${assigneeType === 'role' ? 'bg-primary text-primary-foreground' : 'hover:bg-muted'}`}>Role</button>
              <button type="button" onClick={() => { setAssigneeType('user'); setAssigneeId('') }} className={`flex-1 rounded-sm px-3 py-1.5 text-sm font-medium transition-colors ${assigneeType === 'user' ? 'bg-primary text-primary-foreground' : 'hover:bg-muted'}`}>User</button>
            </div>
            <div className="flex gap-2">
              <Select value={assigneeId} onValueChange={setAssigneeId}>
                <SelectTrigger className="flex-1"><SelectValue placeholder={assigneeType === 'role' ? 'Select role...' : 'Select user...'} /></SelectTrigger>
                <SelectContent>
                  {assigneeType === 'role'
                    ? roles.map((role: Role) => <SelectItem key={role.id} value={role.id}>{role.name}</SelectItem>)
                    : users.map((user: UserRecord) => <SelectItem key={user.id} value={user.id}>{user.firstName} {user.lastName}</SelectItem>)
                  }
                </SelectContent>
              </Select>
              <Select value={accessLevel} onValueChange={setAccessLevel}>
                <SelectTrigger className="w-28"><SelectValue /></SelectTrigger>
                <SelectContent>
                  {ACCESS_LEVELS.map((level) => <SelectItem key={level.value} value={level.value}>{level.label}</SelectItem>)}
                </SelectContent>
              </Select>
            </div>
            <Button type="submit" size="sm" disabled={!assigneeId || addPermissionMutation.isPending} className="w-full">
              {addPermissionMutation.isPending ? 'Adding...' : 'Add Permission'}
            </Button>
          </form>
        </div>
      </DialogContent>
    </Dialog>
  )
}
