'use client';
import { useState, ReactNode } from 'react';
import { Button } from './button';
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from './command';
import { cn } from '@/lib/utils';
import { ChevronsUpDown, X } from 'lucide-react';
import { Skeleton } from './skeleton';

interface Option {
  label: ReactNode;
  value: string | number | object | null;
}

interface SearchableSelectProps {
  options: Option[];
  value?: Option['value'];
  onChange: (value: Option['value'] | null) => void;
  onSearch?: (term: string) => void;
  loading?: boolean;
  placeholder?: string;
  className?: string;
  buttonClassName?: string;
  shouldFilter?: boolean;
  isClearable?: boolean;
  defaultValue?: string | number | readonly string[];
}

export function SearchableSelect({
  options,
  value,
  onChange,
  onSearch,
  loading,
  placeholder = 'Select...',
  className,
  buttonClassName,
  shouldFilter = true,
  isClearable = false,
  defaultValue,
}: SearchableSelectProps) {
  const [isOpen, setIsOpen] = useState(false);
  const selectedOption = options.find((opt) => JSON.stringify(opt.value) === JSON.stringify(value));

  const handleSearch = (term: string) => {
    onSearch?.(term);
  };

  const handleClear = (e: React.MouseEvent) => {
    e.stopPropagation();
    onChange(null);
    setIsOpen(false);
  };

  const handleSelect = (option: Option) => {
    onChange(option.value);
    setIsOpen(false);
  };

  return (
    <div className={cn('relative', className)}>
      <div className='relative'>
        <Button
          variant='outline'
          role='combobox'
          type='button'
          aria-expanded={isOpen}
          onClick={() => setIsOpen(!isOpen)}
          className={cn(
            'w-full justify-between text-sm text-neutral-800 rounded-sm',
            'bg-neutral-200 hover:bg-neutral-300',
            isClearable && selectedOption && 'pr-8',
            buttonClassName
          )}
        >
          <span className='flex-1 text-left truncate'>
            {selectedOption ? selectedOption.label : <span>{placeholder}</span>}
          </span>
          <ChevronsUpDown
            className={cn(
              'ml-1 h-3 w-3 shrink-0 transition-transform duration-200',
              isOpen ? 'transform rotate-180' : ''
            )}
          />
        </Button>
        {isClearable && selectedOption && (
          <button
            type='button'
            onClick={handleClear}
            className='absolute right-2 top-1/2 -translate-y-1/2 p-1 text-neutral-800'
          >
            <X className='h-4 w-4' />
          </button>
        )}
      </div>

      <Command
        className={cn(
          'absolute top-[calc(100%+4px)] h-auto left-0 w-full rounded-sm border border-neutral-300 bg-neutral-200 z-10',
          !isOpen && 'hidden'
        )}
        shouldFilter={shouldFilter}
      >
        <CommandInput
          placeholder='Search...'
          className='p-2 h-9 text-sm text-neutral-800 placeholder:text-neutral-500'
          onValueChange={handleSearch}
          autoFocus
          defaultValue={defaultValue}
        />
        <CommandList className='z-50'>
          <CommandGroup className='max-h-[145px] overflow-y-auto scrollbar-thin'>
            {!loading &&
              options.length > 0 &&
              options.map((option) => (
                <CommandItem
                  key={JSON.stringify(option.value)}
                  value={JSON.stringify(option.value)}
                  onSelect={() => handleSelect(option)}
                  className={cn(
                    'text-sm cursor-pointer text-neutral-800 h-9',
                    'data-[selected=true]:text-neutral-200 data-[selected=true]:bg-neutral-800'
                  )}
                >
                  <div className='flex items-center gap-2'>{option.label}</div>
                </CommandItem>
              ))}
          </CommandGroup>
          {loading && (
            <div className='flex items-center gap-2 flex-col p-2'>
              {[...Array(5)].map((_, i) => (
                <Skeleton key={i} className='h-5 w-full bg-neutral-700' />
              ))}
            </div>
          )}
          {!loading && options.length === 0 && (
            <CommandEmpty className='text-sm text-neutral-800 text-center py-5'>No options found</CommandEmpty>
          )}
        </CommandList>
      </Command>
    </div>
  );
}
