import { createFileRoute, useNavigate } from '@tanstack/react-router'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useState } from 'react'
import { rolePageOptions, rbacKeys, rbacMutations } from '@/api/rbac'
import { usePagination } from '@/hooks/use-pagination'
import { DataTable, type Column } from '@/components/shared/data-table'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { Input } from '@/components/ui/input'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { Plus, MoreVertical, Pencil, Trash2, Shield, Search } from 'lucide-react'
import { toast } from 'sonner'
import { useAuthStore } from '@/stores/auth.store'
import type { Role } from '@/types/rbac'

export const Route = createFileRoute('/_authenticated/roles/')({
  validateSearch: (search: Record<string, unknown>) => ({
    page: Number(search.page) || 1,
    limit: Number(search.limit) || 25,
    q: (search.q as string) || undefined,
    sort: (search.sort as string) || undefined,
    order: (search.order as 'asc' | 'desc') || 'asc',
  }),
  component: RolesListPage,
})

function RolesListPage() {
  const navigate = useNavigate()
  const queryClient = useQueryClient()
  const hasPermission = useAuthStore((s) => s.hasPermission)
  const { params, setPage, setSearch, setSort } = usePagination()
  const [searchInput, setSearchInput] = useState(params.q ?? '')

  const { data, isLoading } = useQuery(rolePageOptions(params))

  const deleteMutation = useMutation({
    mutationFn: rbacMutations.deleteRole,
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: rbacKeys.roles })
      queryClient.invalidateQueries({ queryKey: ['roles', 'list'] })
      toast.success('Role deleted')
    },
    onError: (err) => toast.error(err.message),
  })

  function handleSearchSubmit(e: React.FormEvent) {
    e.preventDefault()
    setSearch(searchInput)
  }

  const roleColumns: Column<Role>[] = [
    {
      key: 'name',
      header: 'Name',
      sortable: true,
      render: (row) => (
        <div className="flex items-center gap-2">
          <Shield className="h-4 w-4 text-muted-foreground" />
          <span className="font-medium">{row.name}</span>
        </div>
      ),
    },
    {
      key: 'slug',
      header: 'Slug',
      sortable: true,
      render: (row) => <span className="font-mono text-sm text-muted-foreground">{row.slug}</span>,
    },
    {
      key: 'description',
      header: 'Description',
      render: (row) => <span className="text-sm text-muted-foreground">{row.description ?? '-'}</span>,
    },
    {
      key: 'type',
      header: 'Type',
      render: (row) =>
        row.isSystem ? <Badge variant="secondary">System</Badge> : <Badge>Custom</Badge>,
    },
    {
      key: 'actions',
      header: '',
      render: (row) => (
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="ghost" size="sm" className="h-8 w-8 p-0">
              <MoreVertical className="h-4 w-4" />
            </Button>
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuItem onClick={() => navigate({ to: '/roles/$roleId', params: { roleId: row.id } })}>
              <Pencil className="mr-2 h-4 w-4" />
              Edit Permissions
            </DropdownMenuItem>
            {!row.isSystem && hasPermission('users.admin') && (
              <>
                <DropdownMenuSeparator />
                <DropdownMenuItem className="text-destructive" onClick={() => deleteMutation.mutate(row.id)}>
                  <Trash2 className="mr-2 h-4 w-4" />
                  Delete
                </DropdownMenuItem>
              </>
            )}
          </DropdownMenuContent>
        </DropdownMenu>
      ),
    },
  ]

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <h1 className="text-2xl font-bold">Roles</h1>
        {hasPermission('users.admin') && (
          <Button onClick={() => navigate({ to: '/roles/new' })}>
            <Plus className="mr-2 h-4 w-4" />
            New Role
          </Button>
        )}
      </div>

      <form onSubmit={handleSearchSubmit} className="flex gap-2 max-w-sm">
        <div className="relative flex-1">
          <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
          <Input
            placeholder="Search roles..."
            value={searchInput}
            onChange={(e) => setSearchInput(e.target.value)}
            className="pl-9"
          />
        </div>
        <Button type="submit" variant="secondary">Search</Button>
      </form>

      <DataTable
        columns={roleColumns}
        data={data?.data ?? []}
        loading={isLoading}
        page={params.page}
        totalPages={data?.pagination?.totalPages ?? 1}
        total={data?.pagination?.total ?? 0}
        sort={params.sort}
        order={params.order}
        onPageChange={setPage}
        onSort={setSort}
      />
    </div>
  )
}
