'use client';

import { useMemo, useState } from 'react';
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from '@/components/ui/popover';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
import { Check, ChevronDown, Search, X } from 'lucide-react';

export interface MultiSelectOption {
  value: string;
  label: string;
}

interface Props {
  options: MultiSelectOption[];
  value: string[];
  onChange: (next: string[]) => void;
  placeholder?: string;
  searchPlaceholder?: string;
  className?: string;
  /** Hide the search box when option count is below this threshold. */
  searchThreshold?: number;
  /** Optional max-height for the option list (px). */
  maxListHeight?: number;
}

export function MultiSelect({
  options,
  value,
  onChange,
  placeholder = 'Any',
  searchPlaceholder = 'Search…',
  className = '',
  searchThreshold = 8,
  maxListHeight = 300,
}: Props) {
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState('');

  const valueSet = useMemo(() => new Set(value), [value]);

  const filtered = useMemo(() => {
    const s = search.trim().toLowerCase();
    if (!s) return options;
    return options.filter((o) => o.label.toLowerCase().includes(s));
  }, [options, search]);

  const selectedLabels = useMemo(() => {
    if (value.length === 0) return null;
    if (value.length === 1) {
      return options.find((o) => o.value === value[0])?.label ?? value[0];
    }
    return `${value.length} selected`;
  }, [value, options]);

  function toggle(optValue: string) {
    if (valueSet.has(optValue)) {
      onChange(value.filter((v) => v !== optValue));
    } else {
      onChange([...value, optValue]);
    }
  }

  function clear(e: React.MouseEvent) {
    e.stopPropagation();
    onChange([]);
  }

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          className={`justify-between font-normal ${className}`}
        >
          <span className="truncate">
            {selectedLabels ?? (
              <span className="text-muted-foreground">{placeholder}</span>
            )}
          </span>
          <span className="flex items-center gap-1 shrink-0 ml-2">
            {value.length > 0 && (
              <Badge
                variant="secondary"
                className="h-5 px-1.5 text-xs hover:bg-destructive hover:text-destructive-foreground"
                onClick={clear}
              >
                <X className="w-3 h-3" />
              </Badge>
            )}
            <ChevronDown className="w-4 h-4 opacity-50" />
          </span>
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="p-0 w-[var(--radix-popover-trigger-width)] min-w-[260px] max-w-[calc(100vw-1rem)]"
        align="start"
        collisionPadding={8}
      >
        {options.length >= searchThreshold && (
          <div className="p-2 border-b">
            <div className="relative">
              <Search className="w-4 h-4 absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground" />
              <Input
                value={search}
                onChange={(e) => setSearch(e.target.value)}
                placeholder={searchPlaceholder}
                className="pl-8 h-8"
              />
            </div>
          </div>
        )}
        <div
          className="overflow-y-auto py-1"
          style={{ maxHeight: maxListHeight }}
        >
          {filtered.length === 0 ? (
            <div className="px-3 py-6 text-sm text-muted-foreground text-center">
              No matches
            </div>
          ) : (
            filtered.map((opt) => {
              const checked = valueSet.has(opt.value);
              return (
                <div
                  key={opt.value}
                  role="option"
                  aria-selected={checked}
                  tabIndex={0}
                  onClick={() => toggle(opt.value)}
                  onKeyDown={(e) => {
                    if (e.key === 'Enter' || e.key === ' ') {
                      e.preventDefault();
                      toggle(opt.value);
                    }
                  }}
                  className="flex items-center gap-2 w-full px-3 py-1.5 text-sm hover:bg-accent cursor-pointer select-none focus:bg-accent focus:outline-none"
                >
                  <span
                    className={`w-4 h-4 shrink-0 rounded-sm border flex items-center justify-center transition ${
                      checked
                        ? 'bg-primary border-primary text-primary-foreground'
                        : 'border-input bg-background'
                    }`}
                    aria-hidden="true"
                  >
                    {checked && <Check className="w-3 h-3" strokeWidth={3} />}
                  </span>
                  <span className="truncate">{opt.label}</span>
                </div>
              );
            })
          )}
        </div>
      </PopoverContent>
    </Popover>
  );
}
