import * as React from "react";
import { X, Check, ChevronsUpDown, Search, User, Users } from "lucide-react";
import { cn } from "@/lib/utils";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Separator } from "@/components/ui/separator";

export interface ComboboxOption {
  value: number;
  label: string;
  department?: string;
  role?: string;
}

interface ComboboxMultiProps {
  options: ComboboxOption[];
  selectedValues: number[];
  onValuesChange: (values: number[]) => void;
  placeholder?: string;
  emptyText?: string;
  label?: string;
}

export function ComboboxMulti({
  options,
  selectedValues,
  onValuesChange,
  placeholder = "Select options",
  emptyText = "No options found.",
  label,
}: ComboboxMultiProps) {
  const [isOpen, setIsOpen] = React.useState(false);
  const [searchTerm, setSearchTerm] = React.useState("");
  const containerRef = React.useRef<HTMLDivElement>(null);
  
  // Safety checks
  const safeOptions = Array.isArray(options) ? options : [];
  const safeSelectedValues = Array.isArray(selectedValues) ? selectedValues : [];
  
  // Close dropdown when clicking outside
  React.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);
  }, []);

  // Filter options based on search term
  const filteredOptions = React.useMemo(() => {
    if (!searchTerm) return safeOptions;
    
    return safeOptions.filter(option => 
      option.label.toLowerCase().includes(searchTerm.toLowerCase())
    );
  }, [safeOptions, searchTerm]);

  // Toggle option selection
  const toggleOption = React.useCallback((value: number) => {
    try {
      if (safeSelectedValues.includes(value)) {
        onValuesChange(safeSelectedValues.filter(v => v !== value));
      } else {
        onValuesChange([...safeSelectedValues, value]);
      }
    } catch (error) {
      console.error("Error toggling option selection:", error);
    }
  }, [safeSelectedValues, onValuesChange]);

  // Select all options
  const selectAll = React.useCallback(() => {
    try {
      const allValues = safeOptions.map(option => option.value);
      onValuesChange(allValues);
    } catch (error) {
      console.error("Error selecting all options:", error);
    }
  }, [safeOptions, onValuesChange]);

  // Clear all selections (except any that should be preserved)
  const clearAll = React.useCallback(() => {
    try {
      onValuesChange([]);
    } catch (error) {
      console.error("Error clearing selections:", error);
    }
  }, [onValuesChange]);

  // Get selected option names for display
  const getSelectedOptionLabels = React.useCallback(() => {
    const selectedCount = safeSelectedValues.length;
    
    if (selectedCount === 0) {
      return placeholder;
    } else if (selectedCount === 1) {
      const option = safeOptions.find(o => o.value === safeSelectedValues[0]);
      return option ? option.label : '1 selected';
    } else if (selectedCount <= 2) {
      return safeSelectedValues
        .map(value => safeOptions.find(option => option.value === value)?.label)
        .filter(Boolean)
        .join(", ");
    } else {
      return `${selectedCount} attendees selected`;
    }
  }, [safeOptions, safeSelectedValues, placeholder]);

  // Calculate unselected options count
  const unselectedCount = React.useMemo(() => {
    return safeOptions.length - safeSelectedValues.length;
  }, [safeOptions, safeSelectedValues]);

  return (
    <div className="space-y-2">
      {label && <Label>{label}</Label>}
      <div ref={containerRef} className="relative">
        <div
          className={cn(
            "flex min-h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background cursor-pointer",
            isOpen && "ring-2 ring-ring ring-offset-2"
          )}
          onClick={() => setIsOpen(!isOpen)}
        >
          <div className="flex items-center gap-2 flex-1 truncate">
            <Users className="h-4 w-4 text-muted-foreground" />
            <span className={safeSelectedValues.length === 0 ? "text-muted-foreground" : ""}>
              {getSelectedOptionLabels()}
            </span>
          </div>
          <ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50" />
        </div>

        {isOpen && (
          <div className="absolute z-50 mt-1 w-full overflow-auto rounded-md border bg-popover shadow-md">
            <div className="sticky top-0 bg-popover p-2 border-b">
              <div className="relative mb-2">
                <Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-foreground" />
                <Input
                  placeholder="Search employees..."
                  value={searchTerm}
                  onChange={(e) => setSearchTerm(e.target.value)}
                  className="h-9 pl-8"
                  onClick={(e) => e.stopPropagation()}
                />
              </div>
              
              {safeOptions.length > 3 && (
                <div className="flex justify-between items-center">
                  <p className="text-xs text-muted-foreground">
                    {safeSelectedValues.length} of {safeOptions.length} selected
                  </p>
                  <div className="flex gap-2">
                    <Button 
                      type="button" 
                      variant="ghost" 
                      size="sm"
                      className="h-7 text-xs"
                      onClick={(e) => {
                        e.stopPropagation();
                        selectAll();
                      }}
                      disabled={safeSelectedValues.length === safeOptions.length}
                    >
                      Select All
                    </Button>
                    <Button 
                      type="button" 
                      variant="ghost" 
                      size="sm"
                      className="h-7 text-xs"
                      onClick={(e) => {
                        e.stopPropagation();
                        clearAll();
                      }}
                      disabled={safeSelectedValues.length === 0}
                    >
                      Clear All
                    </Button>
                  </div>
                </div>
              )}
            </div>
            
            <div className="max-h-60 overflow-auto">
              {filteredOptions.length === 0 ? (
                <div className="py-6 px-2 text-sm text-center text-muted-foreground">
                  {emptyText}
                </div>
              ) : (
                <div className="py-1">
                  {filteredOptions.map((option) => (
                    <div
                      key={option.value}
                      className={cn(
                        "flex items-center justify-between py-1.5 px-2 text-sm rounded-sm cursor-pointer",
                        safeSelectedValues.includes(option.value) 
                          ? "bg-primary text-primary-foreground" 
                          : "hover:bg-accent hover:text-accent-foreground"
                      )}
                      onClick={(e) => {
                        e.stopPropagation();
                        toggleOption(option.value);
                      }}
                    >
                      <div className="flex items-center gap-2">
                        <div className={cn(
                          "flex h-5 w-5 items-center justify-center rounded-full border",
                          safeSelectedValues.includes(option.value) 
                            ? "border-primary-foreground" 
                            : "border-muted-foreground"
                        )}>
                          <User className="h-3 w-3" />
                        </div>
                        <span>{option.label}</span>
                        {option.role && (
                          <Badge variant="outline" className="ml-2 text-xs py-0">
                            {option.role}
                          </Badge>
                        )}
                      </div>
                      {safeSelectedValues.includes(option.value) && (
                        <Check className="h-4 w-4" />
                      )}
                    </div>
                  ))}
                </div>
              )}
            </div>
          </div>
        )}

        {safeSelectedValues.length > 0 && (
          <div className="flex flex-wrap gap-1 mt-2">
            {safeSelectedValues.map(value => {
              const option = safeOptions.find(o => o.value === value);
              if (!option) return null;
              
              return (
                <Badge 
                  key={value} 
                  variant="secondary"
                  className="flex items-center gap-1"
                >
                  {option.label}
                  <button
                    type="button"
                    onClick={(e) => {
                      e.stopPropagation();
                      toggleOption(value);
                    }}
                    className="ml-1 rounded-full hover:bg-accent p-0.5"
                  >
                    <X className="h-3 w-3" />
                    <span className="sr-only">Remove {option.label}</span>
                  </button>
                </Badge>
              );
            })}
          </div>
        )}
      </div>
    </div>
  );
} 