import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import {
  storageFolderPermissionsOptions, storageFolderMutations, storageFolderKeys,
} from '@/api/storage'
import { roleListOptions } from '@/api/rbac'
import { userListOptions } from '@/api/users'
import type { UserRecord } from '@/api/users'
import type { Role } from '@/types/rbac'
import type { StorageFolderPermission } from '@/types/storage'
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 FolderPermissionsDialogProps {
  folderId: string
  folderName: string
  isPublic: boolean
  open: boolean
  onOpenChange: (open: boolean) => void
}

const ACCESS_LEVELS = [
  { value: 'traverse', label: 'Traverse', variant: 'outline' as const },
  { 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 FolderPermissionsDialog({ folderId, folderName, isPublic, open, onOpenChange }: FolderPermissionsDialogProps) {
  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({
    ...storageFolderPermissionsOptions(folderId),
    enabled: open && !!folderId,
  })
  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) => storageFolderMutations.update(folderId, { isPublic: newIsPublic }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: storageFolderKeys.all })
      queryClient.invalidateQueries({ queryKey: storageFolderKeys.detail(folderId) })
      toast.success(isPublic ? 'Folder set to private' : 'Folder set to public')
    },
    onError: (err) => toast.error(err.message),
  })

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

  const removePermissionMutation = useMutation({
    mutationFn: (permId: string) => storageFolderMutations.removePermission(permId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: storageFolderKeys.permissions(folderId) })
      toast.success('Permission removed')
    },
    onError: (err) => toast.error(err.message),
  })

  function getPermissionLabel(perm: StorageFolderPermission): { icon: typeof Shield; name: string } {
    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' }
  }

  function handleAdd(e: React.FormEvent) {
    e.preventDefault()
    if (!assigneeId) return
    addPermissionMutation.mutate()
  }

  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 — {folderName}
          </DialogTitle>
        </DialogHeader>

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

          {/* Current permissions */}
          <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>

          {/* Add permission form */}
          <form onSubmit={handleAdd} className="space-y-3">
            <Label className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
              Add Permission
            </Label>

            {/* Role / User toggle */}
            <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">
              {/* Assignee select */}
              <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>

              {/* Access level 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>
  )
}
