import { useState, useMemo } from "react";
import { Input } from "~/components/ui/input";
import { Button } from "~/components/ui/button";
import { Check, ChevronsUpDown, X } from "lucide-react";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "~/components/ui/popover";
import { cn } from "~/lib/utils";

interface Participant {
  id: string;
  name: string;
}

interface ParticipantSelectorProps {
  participants: Participant[];
  value: string;
  onValueChange: (value: string) => void;
  placeholder?: string;
  disabled?: boolean;
}

/**
 * Searchable participant selector optimized for large lists (305+ items)
 * Only renders filtered results to maintain performance
 */
export function ParticipantSelector({
  participants,
  value,
  onValueChange,
  placeholder = "Select participant...",
  disabled = false,
}: ParticipantSelectorProps) {
  const [open, setOpen] = useState(false);
  const [search, setSearch] = useState("");

  // Find selected participant
  const selectedParticipant = useMemo(
    () => participants.find((p) => p.id === value),
    [participants, value]
  );

  // Filter participants based on search (case-insensitive)
  const filteredParticipants = useMemo(() => {
    if (!search) return participants;

    const searchLower = search.toLowerCase();
    return participants.filter((p) =>
      p.name.toLowerCase().includes(searchLower)
    );
  }, [participants, search]);

  // Limit displayed results to prevent DOM overload
  const displayedParticipants = useMemo(
    () => filteredParticipants.slice(0, 50),
    [filteredParticipants]
  );

  const handleSelect = (participantId: string) => {
    onValueChange(participantId);
    setOpen(false);
    setSearch("");
  };

  const handleClear = (e: React.MouseEvent) => {
    e.stopPropagation();
    onValueChange("");
    setSearch("");
  };

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <PopoverTrigger asChild>
        <Button
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className="w-full justify-between"
          disabled={disabled}
        >
          <span className="truncate">
            {selectedParticipant ? selectedParticipant.name : placeholder}
          </span>
          <div className="flex items-center gap-1">
            {selectedParticipant && !disabled && (
              <X
                className="h-4 w-4 shrink-0 opacity-50 hover:opacity-100"
                onClick={handleClear}
              />
            )}
            <ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50" />
          </div>
        </Button>
      </PopoverTrigger>
      <PopoverContent className="w-[400px] p-0" align="start">
        <div className="flex flex-col">
          {/* Search input */}
          <div className="p-2 border-b">
            <Input
              placeholder="Search participants..."
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="h-9"
              autoFocus
            />
          </div>

          {/* Results */}
          <div className="max-h-[300px] overflow-y-auto">
            {displayedParticipants.length === 0 ? (
              <div className="p-4 text-sm text-muted-foreground text-center">
                No participants found.
              </div>
            ) : (
              <>
                {displayedParticipants.map((participant) => (
                  <button
                    key={participant.id}
                    onClick={() => handleSelect(participant.id)}
                    className={cn(
                      "w-full flex items-center gap-2 px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground cursor-pointer text-left",
                      participant.id === value && "bg-accent"
                    )}
                  >
                    <Check
                      className={cn(
                        "h-4 w-4 shrink-0",
                        participant.id === value ? "opacity-100" : "opacity-0"
                      )}
                    />
                    <span className="truncate">{participant.name}</span>
                  </button>
                ))}
                {filteredParticipants.length > 50 && (
                  <div className="p-2 text-xs text-muted-foreground text-center border-t">
                    Showing 50 of {filteredParticipants.length} results. Keep typing to refine...
                  </div>
                )}
              </>
            )}
          </div>
        </div>
      </PopoverContent>
    </Popover>
  );
}
