import { useState, useRef, useEffect } from "react";
import { Search, Plus, X, Loader2 } from "lucide-react";
import type { LucideIcon } from "lucide-react";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

export interface EntityOption {
  id: number;
  name: string;
  subtitle?: string;
}

interface EntitySearchSelectProps {
  value: EntityOption | null;
  onChange: (value: EntityOption | null) => void;
  onSearch: (query: string) => void;
  onCreateNew: () => void;
  options: EntityOption[];
  isLoading?: boolean;
  placeholder?: string;
  icon: LucideIcon;
  entityName: string;
  disabled?: boolean;
}

// Helper function to highlight matching text
function HighlightedText({ text, highlight }: { text: string; highlight: string }) {
  if (!highlight.trim()) {
    return <>{text}</>;
  }

  const regex = new RegExp(`(${highlight.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")})`, "gi");
  const parts = text.split(regex);

  return (
    <>
      {parts.map((part, index) =>
        regex.test(part) ? (
          <mark key={index} className="bg-primary/20 text-foreground rounded-sm px-0.5">
            {part}
          </mark>
        ) : (
          <span key={index}>{part}</span>
        )
      )}
    </>
  );
}

export function EntitySearchSelect({
  value,
  onChange,
  onSearch,
  onCreateNew,
  options,
  isLoading = false,
  placeholder = "Search...",
  icon: Icon,
  entityName,
  disabled = false,
}: EntitySearchSelectProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState("");
  const containerRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  // Handle search input changes
  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const query = e.target.value;
    setSearchQuery(query);
    onSearch(query);
  };

  // Handle selecting an option
  const handleSelect = (option: EntityOption) => {
    onChange(option);
    setIsOpen(false);
    setSearchQuery("");
  };

  // Handle clearing the selection
  const handleClear = (e: React.MouseEvent) => {
    e.stopPropagation();
    onChange(null);
    setSearchQuery("");
  };

  // Handle clicking "Create new"
  const handleCreateNew = () => {
    setIsOpen(false);
    setSearchQuery("");
    onCreateNew();
  };

  // Close dropdown when clicking outside
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    };

    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  // Focus input when dropdown opens
  useEffect(() => {
    if (isOpen && inputRef.current) {
      inputRef.current.focus();
    }
  }, [isOpen]);

  // Trigger initial search when opening
  useEffect(() => {
    if (isOpen) {
      onSearch(searchQuery);
    }
  }, [isOpen]);

  return (
    <div ref={containerRef} className="relative">
      {/* Selected Value Display / Trigger */}
      {value ? (
        <div
          className={cn(
            "flex items-center gap-2 h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm",
            !disabled && "cursor-pointer hover:bg-muted/50",
            disabled && "opacity-50 cursor-not-allowed"
          )}
          onClick={() => !disabled && setIsOpen(true)}
        >
          <Icon className="h-4 w-4 text-muted-foreground flex-shrink-0" />
          <div className="flex-1 min-w-0">
            <span className="truncate block">{value.name}</span>
            {value.subtitle && (
              <span className="text-xs text-muted-foreground truncate block">{value.subtitle}</span>
            )}
          </div>
          {!disabled && (
            <Button
              type="button"
              variant="ghost"
              size="sm"
              className="h-5 w-5 p-0 hover:bg-muted"
              onClick={handleClear}
            >
              <X className="h-3 w-3" />
            </Button>
          )}
        </div>
      ) : (
        <div
          className={cn(
            "flex items-center gap-2 h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm text-muted-foreground",
            !disabled && "cursor-pointer hover:bg-muted/50",
            disabled && "opacity-50 cursor-not-allowed"
          )}
          onClick={() => !disabled && setIsOpen(true)}
        >
          <Icon className="h-4 w-4 flex-shrink-0" />
          <span>{placeholder}</span>
        </div>
      )}

      {/* Dropdown */}
      {isOpen && (
        <div className="absolute z-[100] top-full left-0 right-0 mt-1 bg-popover border border-border rounded-md shadow-lg overflow-hidden">
          {/* Search Input */}
          <div className="p-2 border-b">
            <div className="relative">
              <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
              <Input
                ref={inputRef}
                value={searchQuery}
                onChange={handleSearchChange}
                placeholder={`Search by name or email...`}
                className="pl-8 h-9"
              />
            </div>
          </div>

          {/* Options List */}
          <div className="max-h-[200px] overflow-y-auto">
            {isLoading ? (
              <div className="flex items-center justify-center py-4">
                <Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
              </div>
            ) : options.length > 0 ? (
              <div className="py-1">
                {options.map((option) => (
                  <button
                    key={option.id}
                    type="button"
                    className="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-muted/50 transition-colors text-left"
                    onClick={() => handleSelect(option)}
                  >
                    <Icon className="h-4 w-4 text-muted-foreground flex-shrink-0" />
                    <div className="flex-1 min-w-0">
                      <span className="block truncate">
                        <HighlightedText text={option.name} highlight={searchQuery} />
                      </span>
                      {option.subtitle && (
                        <span className="text-xs text-muted-foreground truncate block">
                          <HighlightedText text={option.subtitle} highlight={searchQuery} />
                        </span>
                      )}
                    </div>
                  </button>
                ))}
              </div>
            ) : (
              <div className="py-4 text-center text-sm text-muted-foreground">
                No {entityName.toLowerCase()} found
              </div>
            )}
          </div>

          {/* Create New Button */}
          <div className="p-2 border-t">
            <Button
              type="button"
              variant="ghost"
              size="sm"
              className="w-full justify-start gap-2 text-primary hover:text-primary hover:bg-primary/10"
              onClick={handleCreateNew}
            >
              <Plus className="h-4 w-4" />
              Create new {entityName.toLowerCase()}
            </Button>
          </div>
        </div>
      )}
    </div>
  );
}
