import { useMemo, useState } from 'react';

type Props = {
  name: string;
  options: string[];
  initialValue: string[];
  placeholder?: string;
};

export default function TagInput({ name, options, initialValue, placeholder }: Props) {
  const [tags, setTags] = useState<string[]>(initialValue);
  const [query, setQuery] = useState('');

  const availableOptions = useMemo(
    () => options.filter((option) => !tags.includes(option)),
    [options, tags],
  );

  const suggestions = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return availableOptions;
    return availableOptions.filter((option) => option.toLowerCase().includes(q));
  }, [availableOptions, query]);

  const trimmedQuery = query.trim();
  const exactMatch =
    trimmedQuery.length > 0 &&
    availableOptions.some((option) => option.toLowerCase() === trimmedQuery.toLowerCase());

  function addTag(value: string) {
    const trimmed = value.trim();
    if (!trimmed || tags.includes(trimmed)) return;
    setTags([...tags, trimmed]);
    setQuery('');
  }

  function removeTag(value: string) {
    setTags(tags.filter((tag) => tag !== value));
  }

  return (
    <div>
      <div className="flex flex-wrap gap-1.5 rounded-field border border-base-300 bg-base-100 p-2">
        {tags.map((tag) => (
          <span key={tag} className="badge badge-secondary badge-lg gap-1">
            {tag}
            <button type="button" onClick={() => removeTag(tag)} className="ms-1 opacity-70 hover:opacity-100" aria-label={`Remove ${tag}`}>
              ×
            </button>
          </span>
        ))}
        <input
          type="text"
          value={query}
          placeholder={placeholder}
          onChange={(e) => setQuery(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === 'Enter' || e.key === ',') {
              e.preventDefault();
              addTag(query);
            } else if (e.key === 'Backspace' && !query && tags.length > 0) {
              removeTag(tags[tags.length - 1]);
            }
          }}
          className="min-w-32 flex-1 bg-transparent outline-none px-1 py-0.5 text-sm"
        />
      </div>

      {(suggestions.length > 0 || (trimmedQuery && !exactMatch)) && (
        <div className="mt-1 flex flex-wrap gap-1.5">
          {suggestions.map((option) => (
            <button
              key={option}
              type="button"
              onClick={() => addTag(option)}
              className="btn btn-xs btn-outline"
            >
              {option}
            </button>
          ))}
          {trimmedQuery && !exactMatch && (
            <button type="button" onClick={() => addTag(query)} className="btn btn-xs btn-primary btn-outline">
              + "{trimmedQuery}"
            </button>
          )}
        </div>
      )}

      {/* Include text typed but not yet committed with Enter/comma so it isn't silently dropped. */}
      <input
        type="hidden"
        name={name}
        value={(trimmedQuery && !tags.includes(trimmedQuery) ? [...tags, trimmedQuery] : tags).join(',')}
      />
    </div>
  );
}
