import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useState } from 'react'
import { 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 { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Separator } from '@/components/ui/separator'
import { toast } from 'sonner'

export const Route = createFileRoute('/_authenticated/roles/new')({
  component: NewRolePage,
})

function NewRolePage() {
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const { data: permsData } = useQuery(permissionListOptions())

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

  const mutation = useMutation({
    mutationFn: rbacMutations.createRole,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: rbacKeys.roles })
      toast.success('Role created')
      navigate({ to: '/roles' })
    },
    onError: (err) => toast.error(err.message),
  })

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

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

  function handleNameChange(value: string) {
    setName(value)
    if (!slug || slug === nameToSlug(name)) {
      setSlug(nameToSlug(value))
    }
  }

  function nameToSlug(n: string) {
    return n.toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_|_$/g, '')
  }

  function handleSubmit() {
    if (!name || !slug) {
      toast.error('Name and slug are required')
      return
    }
    mutation.mutate({
      name,
      slug,
      description: description || undefined,
      permissionSlugs: Array.from(selectedPerms),
    })
  }

  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">
      <h1 className="text-2xl font-bold">New Role</h1>

      <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) => handleNameChange(e.target.value)} placeholder="e.g. School Sales Rep" />
          </div>
          <div className="space-y-2">
            <Label>Slug *</Label>
            <Input value={slug} onChange={(e) => setSlug(e.target.value)} placeholder="auto-generated" className="font-mono" />
          </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>
        </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={handleSubmit} disabled={mutation.isPending}>
          {mutation.isPending ? 'Creating...' : 'Create Role'}
        </Button>
        <Button variant="secondary" onClick={() => navigate({ to: '/roles' })}>
          Cancel
        </Button>
      </div>
    </div>
  )
}
