import { createFileRoute, useParams, useNavigate } from '@tanstack/react-router'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useState, useEffect } from 'react'
import { roleDetailOptions, permissionListOptions, rbacKeys, rbacMutations } from '@/api/rbac'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Textarea } from '@/components/ui/textarea'
import { Badge } from '@/components/ui/badge'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { Skeleton } from '@/components/ui/skeleton'
import { ArrowLeft } from 'lucide-react'
import { toast } from 'sonner'

export const Route = createFileRoute('/_authenticated/roles/$roleId')({
  component: RoleDetailPage,
})

function RoleDetailPage() {
  const { roleId } = useParams({ from: '/_authenticated/roles/$roleId' })
  const navigate = useNavigate()
  const queryClient = useQueryClient()

  const { data: role, isLoading: roleLoading } = useQuery(roleDetailOptions(roleId))
  const { data: permsData } = useQuery(permissionListOptions())

  const [name, setName] = useState('')
  const [description, setDescription] = useState('')
  const [selectedPerms, setSelectedPerms] = useState<Set<string>>(new Set())

  useEffect(() => {
    if (role) {
      setName(role.name)
      setDescription(role.description ?? '')
      setSelectedPerms(new Set(role.permissions ?? []))
    }
  }, [role])

  const updateMutation = useMutation({
    mutationFn: (data: Record<string, unknown>) => rbacMutations.updateRole(roleId, data),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: rbacKeys.role(roleId) })
      queryClient.invalidateQueries({ queryKey: rbacKeys.roles })
      toast.success('Role updated')
    },
    onError: (err) => toast.error(err.message),
  })

  function togglePermission(slug: string) {
    const next = new Set(selectedPerms)
    if (next.has(slug)) {
      next.delete(slug)
    } else {
      next.add(slug)
    }
    setSelectedPerms(next)
  }

  function toggleDomain(domain: string, allSlugs: string[]) {
    const allSelected = allSlugs.every((s) => selectedPerms.has(s))
    const next = new Set(selectedPerms)
    for (const slug of allSlugs) {
      if (allSelected) next.delete(slug)
      else next.add(slug)
    }
    setSelectedPerms(next)
  }

  function handleSave() {
    updateMutation.mutate({
      name,
      description: description || undefined,
      permissionSlugs: Array.from(selectedPerms),
    })
  }

  if (roleLoading) {
    return (
      <div className="space-y-4">
        <Skeleton className="h-8 w-48" />
        <Skeleton className="h-64 w-full" />
      </div>
    )
  }

  if (!role) {
    return <p className="text-muted-foreground">Role not found</p>
  }

  // Group permissions by domain
  const allPerms = permsData?.data ?? []
  const domains = new Map<string, typeof allPerms>()
  for (const p of allPerms) {
    const list = domains.get(p.domain) ?? []
    list.push(p)
    domains.set(p.domain, list)
  }

  return (
    <div className="space-y-6 max-w-2xl">
      <div className="flex items-center gap-3">
        <Button variant="ghost" size="sm" onClick={() => navigate({ to: '/roles', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
          <ArrowLeft className="h-4 w-4" />
        </Button>
        <div>
          <h1 className="text-2xl font-bold">{role.name}</h1>
          <div className="flex items-center gap-2 text-sm text-muted-foreground">
            <span className="font-mono">{role.slug}</span>
            {role.isSystem && <Badge variant="secondary">System</Badge>}
          </div>
        </div>
      </div>

      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Details</CardTitle>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="space-y-2">
            <Label>Name</Label>
            <Input value={name} onChange={(e) => setName(e.target.value)} />
          </div>
          <div className="space-y-2">
            <Label>Description</Label>
            <Textarea value={description} onChange={(e) => setDescription(e.target.value)} />
          </div>
        </CardContent>
      </Card>

      <Card>
        <CardHeader>
          <CardTitle className="text-lg">Permissions</CardTitle>
          <p className="text-sm text-muted-foreground">
            Select which permissions this role grants. Admin implies Edit and View.
          </p>
        </CardHeader>
        <CardContent className="space-y-6">
          {Array.from(domains.entries()).map(([domain, perms]) => {
            const slugs = perms.map((p) => p.slug)
            const allChecked = slugs.every((s) => selectedPerms.has(s))
            const someChecked = slugs.some((s) => selectedPerms.has(s))

            return (
              <div key={domain}>
                <div className="flex items-center gap-2 mb-2">
                  <input
                    type="checkbox"
                    checked={allChecked}
                    ref={(el) => { if (el) el.indeterminate = someChecked && !allChecked }}
                    onChange={() => toggleDomain(domain, slugs)}
                    className="rounded"
                  />
                  <span className="text-sm font-semibold capitalize">{domain}</span>
                </div>
                <div className="grid grid-cols-3 gap-2 pl-6">
                  {perms.map((p) => (
                    <label key={p.slug} className="flex items-center gap-2 text-sm cursor-pointer">
                      <input
                        type="checkbox"
                        checked={selectedPerms.has(p.slug)}
                        onChange={() => togglePermission(p.slug)}
                        className="rounded"
                      />
                      <span>{p.action}</span>
                    </label>
                  ))}
                </div>
                <Separator className="mt-4" />
              </div>
            )
          })}
        </CardContent>
      </Card>

      <div className="flex gap-2">
        <Button onClick={handleSave} disabled={updateMutation.isPending}>
          {updateMutation.isPending ? 'Saving...' : 'Save Changes'}
        </Button>
        <Button variant="secondary" onClick={() => navigate({ to: '/roles', search: { page: 1, limit: 25, q: undefined, sort: undefined, order: 'asc' as const } })}>
          Cancel
        </Button>
      </div>
    </div>
  )
}
