// components/ui/TagMultiCombobox.tsx
'use client';

import {
  Combobox,
  ComboboxButton,
  ComboboxInput,
  ComboboxOption,
  ComboboxOptions,
  Label,
} from '@headlessui/react';
import { ChevronDownIcon, CheckIcon } from '@heroicons/react/20/solid';
import { useEffect, useMemo, useState } from 'react';
import clsx from 'clsx';
import Badge from '@/components/ui/Badge';

export type TagOption = {
  id?: string | null;
  name: string;
};

type TagMultiComboboxProps = {
  label?: string;
  availableTags: TagOption[];
  value: TagOption[]; // ausgewählte Tags
  onChange: (next: TagOption[]) => void;
  placeholder?: string;
  className?: string;
};

export default function TagMultiCombobox({
  label = 'Tags',
  availableTags,
  value,
  onChange,
  placeholder = 'Tags auswählen oder neu eingeben …',
  className,
}: TagMultiComboboxProps) {
  const [query, setQuery] = useState('');
  const [allTags, setAllTags] = useState<TagOption[]>(availableTags);

  const selectedNames = useMemo(
    () => new Set(value.map((t) => t.name.toLowerCase())),
    [value],
  );

  useEffect(() => {
    setAllTags((prev) => {
      const byName = new Map(prev.map((t) => [t.name.toLowerCase(), t]));
      for (const t of availableTags) {
        const key = t.name.toLowerCase();
        if (!byName.has(key)) {
          byName.set(key, t);
        }
      }
      return Array.from(byName.values());
    });
  }, [availableTags]);

  const filteredTags = useMemo(() => {
    if (!query.trim()) return allTags;
    const q = query.toLowerCase();
    return allTags.filter((tag) => tag.name.toLowerCase().includes(q));
  }, [allTags, query]);

  function handleRemoveTag(tag: TagOption) {
    onChange(
      value.filter((t) => t.name.toLowerCase() !== tag.name.toLowerCase()),
    );
  }

  function handleToggleTag(tag: TagOption) {
    const key = tag.name.toLowerCase();
    if (selectedNames.has(key)) {
      onChange(value.filter((t) => t.name.toLowerCase() !== key));
    } else {
      onChange([...value, tag]);
    }
  }

  function handleCreateTagFromQuery() {
    const name = query.trim();
    if (!name) return;

    const existing = allTags.find(
      (t) => t.name.toLowerCase() === name.toLowerCase(),
    );

    if (existing) {
      if (!selectedNames.has(existing.name.toLowerCase())) {
        onChange([...value, existing]);
      }
      setQuery('');
      return;
    }

    const newTag: TagOption = {
      id: `__new-${Date.now()}`,
      name,
    };

    setAllTags((prev) => [...prev, newTag]);
    onChange([...value, newTag]);
    setQuery('');
  }

  return (
    <Combobox
      as="div"
      multiple
      value={value}
      // wir steuern das selbst über handleToggleTag / handleRemoveTag
      onChange={() => {}}
      className={clsx('w-full', className)}
    >
      <Label className="block text-sm font-medium text-gray-900 dark:text-white">
        {label}
      </Label>

      <div className="mt-2 relative">
        {/* Chips + Input in einem „Feld“ */}
        <div
          className={clsx(
            // neu: relative + extra padding rechts für den Pfeil
            'relative flex flex-wrap items-center gap-1 rounded-md bg-white px-2 py-1.5 text-sm text-gray-900 ' +
              'outline-1 -outline-offset-1 outline-gray-300 focus-within:outline-2 focus-within:-outline-offset-2 ' +
              'focus-within:outline-indigo-600 dark:bg-white/5 dark:text-white dark:outline-gray-700 ' +
              'dark:focus-within:outline-indigo-500 pr-8', // <– Platz für Chevron
          )}
        >
          {/* Ausgewählte Tags als Badges */}
          {value.map((tag) => (
            <Badge
              key={tag.id ?? tag.name}
              tone="blue"
              variant="flat"
              shape="pill"
              size="md"
              onRemove={() => handleRemoveTag(tag)}
            >
              {tag.name}
            </Badge>
          ))}

          {/* Eingabefeld */}
          <ComboboxInput
            className="flex-1 min-w-[6rem] bg-transparent border-0 px-1 py-0.5 text-sm text-gray-900 placeholder:text-gray-400 focus:outline-none dark:text-white dark:placeholder:text-gray-500"
            value={query}
            onChange={(event) => setQuery(event.target.value)}
            displayValue={() => ''}
            placeholder={value.length === 0 ? placeholder : undefined}
            onKeyDown={(event) => {
              if (event.key === 'Enter') {
                event.preventDefault();
                handleCreateTagFromQuery();
              } else if (
                event.key === 'Backspace' &&
                !query &&
                value.length > 0
              ) {
                const last = value[value.length - 1];
                handleRemoveTag(last);
              }
            }}
          />

          {/* Chevron immer rechts im Feld */}
          <ComboboxButton className="absolute inset-y-0 right-2 flex items-center text-gray-400 focus:outline-none">
            <ChevronDownIcon className="size-5" aria-hidden="true" />
          </ComboboxButton>
        </div>

        {/* Dropdown */}
        <ComboboxOptions
          transition
          className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-sm shadow-lg outline outline-black/5 data-leave:transition data-leave:duration-100 data-leave:ease-in data-closed:data-leave:opacity-0 dark:bg-gray-800 dark:shadow-none dark:-outline-offset-1 dark:outline-white/10"
        >
          {query.trim().length > 0 &&
            !allTags.some(
              (t) => t.name.toLowerCase() === query.trim().toLowerCase(),
            ) && (
              <ComboboxOption
                value={{ id: `__new-${query}`, name: query.trim() }}
                className="cursor-default select-none px-3 py-2 text-gray-900 data-focus:bg-indigo-600 data-focus:text-white data-focus:outline-hidden dark:text-gray-200 dark:data-focus:bg-indigo-500"
                onClick={(e) => {
                  e.preventDefault();
                  handleCreateTagFromQuery();
                }}
              >
                <span className="font-medium">
                  „{query.trim()}“ erstellen
                </span>
              </ComboboxOption>
            )}

          {filteredTags.length === 0 && query.trim().length === 0 && (
            <div className="px-3 py-2 text-gray-500 dark:text-gray-400 text-xs">
              Keine Tags vorhanden.
            </div>
          )}

          {filteredTags.map((tag) => {
            const isSelected = selectedNames.has(tag.name.toLowerCase());
            return (
              <ComboboxOption
                key={tag.id ?? tag.name}
                value={tag}
                className={({ active }) =>
                  clsx(
                    'flex cursor-default select-none items-center justify-between px-3 py-2 text-gray-900 dark:text-gray-100',
                    active && 'bg-indigo-600 text-white dark:bg-indigo-500',
                  )
                }
                onClick={(e) => {
                  e.preventDefault();
                  handleToggleTag(tag);
                }}
              >
                <span className="truncate">{tag.name}</span>
                {isSelected && (
                  <CheckIcon
                    className="size-4 text-indigo-600 dark:text-indigo-300 data-focus:text-white"
                    aria-hidden="true"
                  />
                )}
              </ComboboxOption>
            );
          })}
        </ComboboxOptions>
      </div>
    </Combobox>
  );
}
