import { useRequest, useToggle } from 'ahooks'
import { debounce } from 'lodash'
import { CheckIcon, UserIcon } from 'lucide-react'
import { initials, cn } from '@repo/ui/lib/utils'
import { formatCPF } from '@brazilian-utils/brazilian-utils'
import { Avatar, AvatarFallback } from '@repo/ui/components/ui/avatar'
import { Abbr } from '@repo/ui/components/abbr'
import {
  InputGroup,
  InputGroupAddon,
  InputGroupInput
} from '@repo/ui/components/ui/input-group'

import {
  Popover,
  PopoverContent,
  PopoverTrigger
} from '@repo/ui/components/ui/popover'
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList
} from '@repo/ui/components/ui/command'
import { Spinner } from '@repo/ui/components/ui/spinner'

interface AsyncComboboxProps {
  value: any
  title: string
  onChange: (props: any) => void
  onSearch: (search: string) => Promise<any[]>
}
export function AsyncCombobox({
  title,
  value,
  onSearch,
  onChange
}: AsyncComboboxProps) {
  const [open, { set }] = useToggle()
  const {
    data = [],
    loading,
    runAsync
  } = useRequest(onSearch, { manual: true, defaultParams: [''] })

  return (
    <Popover open={open} onOpenChange={set}>
      <PopoverTrigger asChild>
        <InputGroup>
          <InputGroupInput
            readOnly
            value={value?.name || ''}
            placeholder={title}
            className="cursor-pointer"
            autoComplete="off"
          />
          <InputGroupAddon>
            <UserIcon />
          </InputGroupAddon>

          {loading && (
            <InputGroupAddon align="inline-end">
              <Spinner />
            </InputGroupAddon>
          )}
        </InputGroup>
      </PopoverTrigger>

      <PopoverContent className="lg:w-84 p-0" align="start">
        <Command shouldFilter={false}>
          <CommandInput
            placeholder={title}
            autoComplete="off"
            onValueChange={debounce(runAsync, 300)}
          />

          <CommandList>
            <CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>
            <CommandGroup>
              {data.map(({ id, name, email, cpf }) => (
                <CommandItem
                  key={id}
                  value={id}
                  className="cursor-pointer"
                  onSelect={() => {
                    onChange?.({ id, name, email, cpf })
                    set(false)
                  }}
                >
                  <div className="flex gap-2.5 items-start">
                    <Avatar className="size-10 hidden lg:block">
                      <AvatarFallback className="border">
                        {initials(name)}
                      </AvatarFallback>
                    </Avatar>

                    <ul>
                      <li className="font-bold">
                        <Abbr>{name}</Abbr>
                      </li>
                      <li className="text-muted-foreground text-sm">
                        <Abbr>{email}</Abbr>
                      </li>
                      {cpf && (
                        <li className="text-muted-foreground text-sm">
                          {formatCPF(cpf)}
                        </li>
                      )}
                    </ul>
                  </div>

                  <CheckIcon
                    className={cn(
                      'ml-auto',
                      value?.id === id ? 'opacity-100' : 'opacity-0'
                    )}
                  />
                </CommandItem>
              ))}
            </CommandGroup>
          </CommandList>
        </Command>
      </PopoverContent>
    </Popover>
  )
}
