"use client";

import * as React from "react";
import { Check, ChevronsUpDown, X, UserCircle, Search } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";

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

interface MultiSelectProps {
  options: MultiSelectOption[];
  selected: string[];
  onChange: (values: string[]) => void;
  placeholder?: string;
  className?: string;
  emptyMessage?: string;
  searchPlaceholder?: string;
  selectAllLabel?: string;
  deselectAllLabel?: string;
  alwaysShowAvatar?: boolean;
}

export function MultiSelect({
  options,
  selected,
  onChange,
  placeholder = "Select items...",
  className,
  emptyMessage = "No items found.",
  searchPlaceholder = "Search...",
  selectAllLabel = "Select All",
  deselectAllLabel = "Deselect All",
  alwaysShowAvatar = false,
}: MultiSelectProps) {
  const [open, setOpen] = React.useState(false);
  const [searchQuery, setSearchQuery] = React.useState("");
  const [triggerWidth, setTriggerWidth] = React.useState<number | undefined>(undefined);
  const triggerRef = React.useRef<HTMLButtonElement>(null);

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

  // Reset search when popover closes
  React.useEffect(() => {
    if (!open) {
      setSearchQuery("");
    }
  }, [open]);

  React.useEffect(() => {
    if (triggerRef.current) {
      setTriggerWidth(triggerRef.current.offsetWidth);
    }
  }, [open]);

  React.useEffect(() => {
    const updateWidth = () => {
      if (triggerRef.current) {
        setTriggerWidth(triggerRef.current.offsetWidth);
      }
    };

    updateWidth();
    window.addEventListener('resize', updateWidth);

    return () => {
      window.removeEventListener('resize', updateWidth);
    };
  }, []);

  const handleUnselect = (item: string) => {
    onChange(selected.filter((i) => i !== item));
  };

  const handleSelect = (value: string) => {
    if (selected.includes(value)) {
      onChange(selected.filter((item) => item !== value));
    } else {
      onChange([...selected, value]);
    }
  };

  const handleClearAll = () => {
    onChange([]);
  };

  const handleSelectAll = () => {
    onChange(options.map((option) => option.value));
  };

  return (
    <Popover open={open} onOpenChange={setOpen} modal={false}>
      <PopoverTrigger asChild>
        <Button
          ref={triggerRef}
          variant="outline"
          role="combobox"
          aria-expanded={open}
          className={cn(
            "h-auto min-h-10 w-full justify-between rounded hover:bg-transparent cursor-pointer",
            className
          )}
        >
          <div className="flex gap-1.5 flex-wrap max-h-24 overflow-y-auto flex-1">
            {selected.length === 0 && (
              <span className="text-muted-foreground">{placeholder}</span>
            )}
            {selected.length > 0 &&
              selected.map((item) => {
                const option = options.find((opt) => opt.value === item);
                return (
                  <Badge
                    variant="secondary"
                    key={item}
                    className={cn(
                      "h-6 rounded-full flex items-center gap-1 pe-1.5 bg-primary/10 hover:bg-primary/15 transition-colors border border-primary/20",
                      option?.avatar ? "ps-1" : "ps-2"
                    )}
                    onClick={(e) => {
                      e.stopPropagation();
                      handleUnselect(item);
                    }}
                  >
                    {(option?.avatar || alwaysShowAvatar) && (
                      <Avatar className="h-4 w-4 ring-1 ring-primary/20">
                        <AvatarImage src={option?.avatar} alt={option?.label} />
                        <AvatarFallback />
                      </Avatar>
                    )}
                    <span className="text-xs font-medium text-foreground whitespace-nowrap">{option?.label}</span>
                    <span
                      role="button"
                      tabIndex={0}
                      className="ring-offset-background rounded-full outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 hover:bg-destructive/20 transition-colors cursor-pointer"
                      onKeyDown={(e) => {
                        if (e.key === "Enter") {
                          handleUnselect(item);
                        }
                      }}
                      onMouseDown={(e) => {
                        e.preventDefault();
                        e.stopPropagation();
                      }}
                      onClick={(e) => {
                        e.stopPropagation();
                        handleUnselect(item);
                      }}
                    >
                      <X className=" size-4 text-muted-foreground hover:text-destructive" />
                    </span>
                  </Badge>
                );
              })}
          </div>
          <ChevronsUpDown className="h-4 w-4 shrink-0 opacity-50 ms-2" />
        </Button>
      </PopoverTrigger>
      <PopoverContent
        className="p-0"
        align="start"
        style={{ width: triggerWidth ? `${triggerWidth}px` : 'auto' }}
      >
        <div className="flex flex-col">
          {/* Search Input */}
          <div className="flex items-center gap-2 border-b px-3 py-2">
            <Search className="size-4 shrink-0 opacity-50" />
            <Input
              placeholder={searchPlaceholder}
              value={searchQuery}
              onChange={(e) => setSearchQuery(e.target.value)}
              className="h-8 border-0 p-0 focus-visible:ring-0 focus-visible:ring-offset-0"
            />
          </div>

          {/* Options List */}
          <div
            className="p-1"
            style={{
              maxHeight: '208px',
              overflowY: 'auto',
            }}
            onWheel={(e) => {
              e.stopPropagation();
              const target = e.currentTarget;
              if (e.deltaY < 0 && target.scrollTop === 0) return;
              if (e.deltaY > 0 && target.scrollTop + target.clientHeight >= target.scrollHeight) return;
            }}
          >
            {filteredOptions.length === 0 ? (
              <div className="py-6 text-center text-sm text-muted-foreground">
                {emptyMessage}
              </div>
            ) : (
              <>
                {/* Select/Deselect All */}
                <button
                  type="button"
                  onClick={() => {
                    if (selected.length === options.length) {
                      handleClearAll();
                    } else {
                      handleSelectAll();
                    }
                  }}
                  className="relative flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors duration-150 hover:bg-accent/40 hover:text-accent-foreground"
                >
                  <Check
                    className={cn(
                      "me-2 h-4 w-4",
                      selected.length === options.length
                        ? "opacity-100"
                        : "opacity-0"
                    )}
                  />
                  <span className="font-medium">
                    {selected.length === options.length
                      ? deselectAllLabel
                      : selectAllLabel}
                  </span>
                </button>

                {/* Individual Options */}
                {filteredOptions.map((option) => (
                  <button
                    type="button"
                    key={option.value}
                    onClick={() => handleSelect(option.value)}
                    className="relative flex w-full cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none transition-colors duration-150 hover:bg-accent/40 hover:text-accent-foreground"
                  >
                    <Check
                      className={cn(
                        "me-2 h-4 w-4",
                        selected.includes(option.value)
                          ? "opacity-100"
                          : "opacity-0"
                      )}
                    />
                    {(option.avatar || alwaysShowAvatar) && (
                      <Avatar className="h-6 w-6 me-2">
                        <AvatarImage src={option.avatar} alt={option.label} />
                        <AvatarFallback />
                      </Avatar>
                    )}
                    {option.label}
                  </button>
                ))}
              </>
            )}
          </div>
        </div>
      </PopoverContent>
    </Popover>
  );
}
