// /components/GlobalSearch.tsx
'use client';

import { useEffect, useMemo, useRef, useState } from 'react';
import { Combobox } from '@headlessui/react';
import { MagnifyingGlassIcon } from '@heroicons/react/20/solid';
import clsx from 'clsx';

type DeviceSearchItem = {
  inventoryNumber: string;
  name: string | null;
  manufacturer: string | null;
  group: string | null;
  location: string | null;
};

type GlobalSearchProps = {
  onDeviceSelected?: (inventoryNumber: string) => void;
};

export default function GlobalSearch({ onDeviceSelected }: GlobalSearchProps) {
  const [query, setQuery] = useState('');
  const [allDevices, setAllDevices] = useState<DeviceSearchItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [loadError, setLoadError] = useState<string | null>(null);
  const [hasLoaded, setHasLoaded] = useState(false);
  const anchorRef = useRef<HTMLDivElement>(null);
  const [menuTop, setMenuTop] = useState<number | null>(null);

  // Geräte nur einmal laden, wenn das erste Mal gesucht wird
  useEffect(() => {
    if (!query.trim() || hasLoaded) return;

    let cancelled = false;
    setLoading(true);
    setLoadError(null);

    async function loadDevices() {
      try {
        const res = await fetch('/api/devices', {
          method: 'GET',
          headers: { 'Content-Type': 'application/json' },
          cache: 'no-store',
        });

        if (!res.ok) {
          throw new Error('Geräteliste konnte nicht geladen werden.');
        }

        const data = (await res.json()) as any[];

        if (!cancelled) {
          const mapped: DeviceSearchItem[] = data.map((d) => ({
            inventoryNumber: d.inventoryNumber,
            name: d.name ?? null,
            manufacturer: d.manufacturer ?? null,
            group: d.group ?? null,
            location: d.location ?? null,
          }));
          setAllDevices(mapped);
          setHasLoaded(true);
        }
      } catch (err: any) {
        console.error('Fehler beim Laden der Geräte für die Suche', err);
        if (!cancelled) {
          setLoadError(
            err instanceof Error
              ? err.message
              : 'Netzwerkfehler beim Laden der Geräteliste.',
          );
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }

    loadDevices();
    return () => {
      cancelled = true;
    };
  }, [query, hasLoaded]);

  const filteredDevices = useMemo(() => {
    const q = query.trim().toLowerCase();
    if (!q) return [] as DeviceSearchItem[];
    if (!allDevices.length) return [] as DeviceSearchItem[];

    const matches = allDevices.filter((d) => {
      const haystack = [
        d.inventoryNumber,
        d.name ?? '',
        d.manufacturer ?? '',
        d.group ?? '',
        d.location ?? '',
      ]
        .join(' ')
        .toLowerCase();

      return haystack.includes(q);
    });

    return matches.slice(0, 10); // max 10 Treffer
  }, [query, allDevices]);

  const hasMenu =
    query.trim().length > 0 && (loading || loadError || filteredDevices.length > 0);

  useEffect(() => {
    if (!hasMenu) {
      setMenuTop(null);
      return;
    }

    const update = () => {
      const el = anchorRef.current;
      if (!el) return;

      // Nur auf Mobile fix positionieren
      const isMobile = window.matchMedia('(max-width: 639px)').matches; // < sm
      if (!isMobile) {
        setMenuTop(null);
        return;
      }

      const rect = el.getBoundingClientRect();
      // +4px entspricht ungefähr "mt-1"
      setMenuTop(rect.bottom + 4);
    };

    update();
    window.addEventListener('resize', update);
    // capture=true, damit es auch in scroll-containern zuverlässig feuert
    window.addEventListener('scroll', update, true);

    return () => {
      window.removeEventListener('resize', update);
      window.removeEventListener('scroll', update, true);
    };
  }, [hasMenu, query, loading, loadError, filteredDevices.length]);

  const handleSelect = (item: DeviceSearchItem | null) => {
    if (!item) return;
    onDeviceSelected?.(item.inventoryNumber);
    // Query nach Auswahl leeren
    setQuery('');
  };

  return (
    <Combobox value={null} onChange={handleSelect} nullable>
      <div ref={anchorRef} className="relative w-full">
        {/* Suchfeld */}
        <MagnifyingGlassIcon
          aria-hidden="true"
          className="pointer-events-none absolute left-3 top-1/2 size-5 -translate-y-1/2 text-gray-400 dark:text-gray-500"
        />
        <Combobox.Input
          className="block w-full rounded-xl border-0 bg-gray-50 py-1.5 pl-10 pr-3 text-sm text-gray-900 shadow-xs ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-indigo-500 focus:outline-none dark:bg-gray-800 dark:text-white dark:ring-gray-700 dark:placeholder:text-gray-500"
          placeholder="Suchen…"
          aria-label="Suchen"
          displayValue={() => query}
          onChange={(event) => setQuery(event.target.value)}
        />

        {/* Dropdown-Menü unterhalb */}
        {hasMenu && (
          <Combobox.Options
            style={menuTop != null ? { top: menuTop } : undefined}
            className={clsx(
              // ✅ Mobile: wirklich Viewport-edge-to-edge
              'fixed z-50 max-h-80 inset-x-0 overflow-auto bg-white py-1 text-sm shadow-lg ring-1 ring-black/5',
              // optional: edge-to-edge fühlt sich ohne rounding oft besser an
              'rounded-none sm:rounded-md',
              // ✅ Ab sm: wieder "normal" unter dem Input, so wie vorher
              'sm:absolute sm:inset-x-0 sm:top-full sm:mt-1',
              'dark:bg-gray-800 dark:ring-white/10',
            )}
          >
            {loading && (
              <div className="px-3 py-2 text-xs text-gray-500 dark:text-gray-400">
                Suche wird vorbereitet …
              </div>
            )}

            {loadError && (
              <div className="px-3 py-2 text-xs text-rose-500">
                {loadError}
              </div>
            )}

            {!loading && !loadError && filteredDevices.length === 0 && (
              <div className="px-3 py-2 text-xs text-gray-500 dark:text-gray-400">
                Keine Treffer für „{query.trim()}“.
              </div>
            )}

            {!loading &&
              !loadError &&
              filteredDevices.map((device) => (
                <Combobox.Option
                  key={device.inventoryNumber}
                  value={device}
                  className={({ active }) =>
                    clsx(
                      'cursor-pointer w-full px-3 py-2',   // ⬅️ hier: w-full ergänzt
                      'flex flex-col gap-0.5',
                      active
                        ? 'bg-indigo-50 text-indigo-700 dark:bg-indigo-600/25 dark:text-white'
                        : 'text-gray-900 dark:text-gray-100',
                    )
                  }
                >
                  {({ active }) => (
                    <>
                      <div className="flex items-center justify-between">
                        <span className="text-xs font-medium uppercase tracking-wide text-gray-500 dark:text-gray-400">
                          Gerät
                        </span>
                        <span className="text-xs font-mono text-gray-500 dark:text-gray-400">
                          {device.inventoryNumber}
                        </span>
                      </div>
                      <div className="text-sm font-semibold">
                        {device.name || 'Ohne Bezeichnung'}
                      </div>
                      <div className="flex flex-wrap gap-x-2 text-xs text-gray-500 dark:text-gray-400">
                        {device.manufacturer && <span>{device.manufacturer}</span>}
                        {device.group && (
                          <span className="before:content-['·'] before:px-1">
                            {device.group}
                          </span>
                        )}
                        {device.location && (
                          <span className="before:content-['·'] before:px-1">
                            {device.location}
                          </span>
                        )}
                      </div>
                    </>
                  )}
                </Combobox.Option>
              ))}
          </Combobox.Options>
        )}
      </div>
    </Combobox>
  );
}
