import { useBoolean, useRequest, useToggle } from 'ahooks'
import { CheckIcon, UserIcon, XIcon, AlertTriangleIcon } from 'lucide-react'
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 { initials, cn } from '@repo/ui/lib/utils'
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'
import { Button } from '@repo/ui/components/ui/button'

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

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

          {value && (
            <InputGroupAddon align="inline-end" className="mr-0">
              <Button
                variant="link"
                size="icon-sm"
                className="cursor-pointer text-muted-foreground"
                onClick={(e) => {
                  e.preventDefault()
                  onChange?.(undefined)
                  set(false)
                }}
              >
                <XIcon />
              </Button>
            </InputGroupAddon>
          )}

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

      <PopoverContent className="lg:w-84 p-0" align="start">
        <Command
          shouldFilter={false}
          className={cn(
            !searched && '**:data-[slot=command-input-wrapper]:border-b-0'
          )}
        >
          <CommandInput
            placeholder={placeholder}
            autoComplete="off"
            onValueChange={runAsync}
          />

          {searched ? (
            <CommandList>
              <CommandEmpty>Nenhum resultado encontrado.</CommandEmpty>

              <CommandGroup>
                {data.map(({ id, name, email, cpf }) => (
                  <CommandItem
                    key={id}
                    value={id}
                    className="cursor-pointer"
                    disabled={!cpf}
                    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>
                        ) : (
                          <li className="flex gap-1 items-center text-red-400">
                            <AlertTriangleIcon className="text-red-400" />
                            Inelegível
                          </li>
                        )}
                      </ul>
                    </div>

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