'use client';

import { useEffect, useRef, useState } from 'react';
import type { ObjektOption, SelectedObjekt } from '@/types/logbuch';

interface Props {
  selected: SelectedObjekt[];
  onChange: (objekte: SelectedObjekt[]) => void;
}

export default function ObjektSelector({ selected, onChange }: Props) {
  const [all, setAll] = useState<ObjektOption[]>([]);
  const [search, setSearch] = useState('');
  const [dropdownOpen, setDropdownOpen] = useState(false);
  const wrapperRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    fetch('/api/objekte')
      .then((r) => { if (!r.ok) throw new Error('Fehler'); return r.json(); })
      .then(setAll)
      .catch(() => {});
  }, []);

  useEffect(() => {
    function handleOutside(e: MouseEvent) {
      if (wrapperRef.current && !wrapperRef.current.contains(e.target as Node)) {
        setDropdownOpen(false);
      }
    }
    if (dropdownOpen) document.addEventListener('mousedown', handleOutside);
    return () => document.removeEventListener('mousedown', handleOutside);
  }, [dropdownOpen]);

  const selectedNames = new Set(selected.map((o) => o.Name.toLowerCase()));
  const available = all.filter((o) => !selectedNames.has(o.Name.toLowerCase()));
  const filtered = search
    ? available.filter((o) => o.Name.toLowerCase().startsWith(search.toLowerCase()))
    : available;

  const searchTrimmed = search.trim();
  const alreadySelected = searchTrimmed !== '' && selectedNames.has(searchTrimmed.toLowerCase());
  const exactAvailableMatch = available.find((o) => o.Name.toLowerCase() === searchTrimmed.toLowerCase());
  const showAddNew = searchTrimmed !== '' && !alreadySelected && !exactAvailableMatch;

  function add(obj: ObjektOption) {
    onChange([...selected, { ID: obj.ID, Name: obj.Name }]);
    setSearch('');
    inputRef.current?.focus();
  }

  function addNew(name: string) {
    const trimmed = name.trim();
    if (!trimmed || selectedNames.has(trimmed.toLowerCase())) return;
    const existing = all.find((o) => o.Name.toLowerCase() === trimmed.toLowerCase());
    if (existing) {
      onChange([...selected, { ID: existing.ID, Name: existing.Name }]);
    } else {
      onChange([...selected, { ID: null, Name: trimmed }]);
    }
    setSearch('');
    inputRef.current?.focus();
  }

  function remove(name: string) {
    onChange(selected.filter((o) => o.Name !== name));
  }

  function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (e.key !== 'Enter') return;
    e.preventDefault();
    if (filtered.length === 1 && !showAddNew) {
      add(filtered[0]);
    } else if (filtered.length === 0 && searchTrimmed) {
      addNew(searchTrimmed);
    }
  }

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap gap-2">
        {selected.map((o) => (
          <span
            key={o.Name}
            className="inline-flex items-center gap-2 bg-green-100 text-green-800 text-base px-3 py-1.5 rounded-full"
          >
            {o.Name}
            <button
              type="button"
              onClick={() => remove(o.Name)}
              className="flex items-center justify-center w-7 h-7 rounded-full text-green-600 hover:bg-red-100 hover:text-red-600 font-bold text-xl leading-none"
              aria-label={`${o.Name} entfernen`}
            >
              ×
            </button>
          </span>
        ))}
      </div>

      <div ref={wrapperRef} className="relative">
        <input
          ref={inputRef}
          type="text"
          value={search}
          onChange={(e) => { setSearch(e.target.value); setDropdownOpen(true); }}
          onFocus={() => setDropdownOpen(true)}
          onKeyDown={handleKeyDown}
          placeholder="Objekt suchen oder neu eingeben..."
          className="w-full px-3 py-2 border-2 border-gray-400 rounded-lg bg-white text-sm text-gray-900 focus:border-blue-500 focus:outline-none"
        />
        {dropdownOpen && (filtered.length > 0 || showAddNew) && (
          <div className="absolute z-50 left-0 right-0 mt-1 bg-white border-2 border-gray-400 rounded-lg shadow-lg max-h-60 overflow-y-auto">
            {filtered.map((o) => (
              <button
                key={o.ID}
                type="button"
                onClick={() => add(o)}
                className="w-full text-left px-4 py-2 text-sm text-gray-900 hover:bg-blue-50 active:bg-blue-100 border-b border-gray-100 last:border-0"
              >
                {o.Name}
              </button>
            ))}
            {showAddNew && (
              <button
                type="button"
                onClick={() => addNew(searchTrimmed)}
                className="w-full text-left px-4 py-2 text-sm text-blue-700 hover:bg-blue-50 active:bg-blue-100 border-t border-gray-200 font-medium"
              >
                + &bdquo;{searchTrimmed}&ldquo; hinzufügen
              </button>
            )}
          </div>
        )}
      </div>
    </div>
  );
}
