"use client";

import { Search, X, Loader2, LayoutDashboard, Package, ShoppingBag, Users } from "lucide-react";
import { useRouter } from "next/navigation";
import React, { useEffect, useRef, useState, useTransition, useMemo } from "react";
import { cn } from "@/lib/utils";
import { Kbd } from "@/components/ui/kbd";
import { useDebounce } from "@/hooks/useDebounce";
import { globalSearch } from "@/actions/global-search";

const navItems = [
  { title: "Dashboard", href: "/dashboard", type: "Page", icon: LayoutDashboard },
  { title: "Alle Bestellungen", href: "/dashboard/orders/overview", type: "Page", icon: ShoppingBag },
  { title: "Kunden", href: "/dashboard/customers/overview", type: "Page", icon: Users },
  { title: "Benutzer", href: "/dashboard/users/overview", type: "Page", icon: Users },
  { title: "Mein Konto", href: "/dashboard/account", type: "Page", icon: Users },
  { title: "Einstellungen", href: "/dashboard/settings", type: "Page", icon: LayoutDashboard },
];

type SearchResult = {
  id: string;
  title: string;
  type: string;
  href: string;
  icon?: React.ElementType;
};

type ServerResults = {
  products: SearchResult[];
  orders: SearchResult[];
  users: SearchResult[];
};

/**
 * ⚡ Optimization: Memoized Search Item
 * Prevents re-renders of all search results during keyboard navigation.
 * Only the newly selected and previously selected items will re-render.
 */
const SearchItem = React.memo(({
  item,
  index,
  isSelected,
  Icon,
  onClick
}: {
  item: SearchResult;
  index: number;
  isSelected: boolean;
  Icon: React.ElementType;
  onClick: (href: string) => void;
}) => {
  const ItemIcon = item.icon || Icon;

  return (
    <div
      id={`nav-search-option-${index}`}
      role="option"
      aria-selected={isSelected}
      onClick={() => onClick(item.href)}
      className={cn(
        "flex items-center gap-2 px-3 py-2 text-sm rounded-sm cursor-pointer mx-1",
        isSelected ? "bg-accent text-accent-foreground" : "text-popover-foreground hover:bg-accent hover:text-accent-foreground"
      )}
    >
      <ItemIcon className="h-4 w-4 opacity-50" />
      <span className="truncate">{item.title}</span>
    </div>
  );
});

SearchItem.displayName = "SearchItem";

export function NavigationSearch() {
  const router = useRouter();
  const inputRef = useRef<HTMLInputElement>(null);
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const debouncedQuery = useDebounce(query, 300);
  const [isPending, startTransition] = useTransition();
  const [serverResults, setServerResults] = useState<ServerResults>({ products: [], orders: [], users: [] });

  /**
   * ⚡ Optimization: Client-side Search Cache
   * Store results for recently searched terms to avoid redundant server round-trips.
   * Expected Impact: Instant results for repeated queries; reduced server load.
   */
  const searchCache = useRef<Map<string, ServerResults>>(new Map());

  const [selectedIndex, setSelectedIndex] = useState(0);
  const [isMac, setIsMac] = useState(false);

  useEffect(() => {
    setIsMac(navigator.userAgent.toUpperCase().indexOf('MAC') >= 0 || navigator.platform.toUpperCase().indexOf('MAC') >= 0);

    const handleGlobalKeyDown = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
        e.preventDefault();
        inputRef.current?.focus();
      }
    };

    window.addEventListener("keydown", handleGlobalKeyDown);
    return () => window.removeEventListener("keydown", handleGlobalKeyDown);
  }, []);

  // Filter local nav items
  const filteredNavItems = useMemo(() => 
    navItems.filter((item) =>
      item.title.toLowerCase().includes(query.toLowerCase())
    ).map(item => ({ ...item, id: item.href, type: "Page" as const })),
    [query]
  );

  // Combine all results
  const allResults = useMemo(() => [
    ...filteredNavItems,
    ...serverResults.products,
    ...serverResults.orders,
    ...serverResults.users,
  ], [filteredNavItems, serverResults]);

  const hasResults = allResults.length > 0;

  // Fetch server results
  useEffect(() => {
    const trimmedQuery = debouncedQuery.trim();
    if (!trimmedQuery) {
      setServerResults({ products: [], orders: [], users: [] });
      return;
    }

    /*
      ⚡ Optimization: Cache Check
      Only call the server if we don't already have results for this exact query.
    */
    if (searchCache.current.has(trimmedQuery)) {
      setServerResults(searchCache.current.get(trimmedQuery)!);
      return;
    }

    startTransition(async () => {
      const results = await globalSearch({ query: trimmedQuery });
      if (results?.success) {
        setServerResults(results.data);
        // Store in cache for future use
        searchCache.current.set(trimmedQuery, results.data);
      }
    });
  }, [debouncedQuery]);

  const handleSelect = React.useCallback((href: string) => {
    setOpen(false);
    setQuery("");
    router.push(href);
  }, [router]);

  const handeKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === "ArrowDown") {
        e.preventDefault();
        if (allResults.length > 0) {
            setSelectedIndex(prev => (prev + 1) % allResults.length);
        }
    } else if (e.key === "ArrowUp") {
        e.preventDefault();
        if (allResults.length > 0) {
            setSelectedIndex(prev => (prev - 1 + allResults.length) % allResults.length);
        }
    } else if (e.key === "Enter") {
        e.preventDefault();
        if (allResults[selectedIndex]) {
            handleSelect(allResults[selectedIndex].href);
            inputRef.current?.blur();
        }
    } else if (e.key === "Escape") {
        inputRef.current?.blur();
        setOpen(false);
    }
  }

  const renderGroup = (title: string, items: SearchResult[], Icon: React.ElementType, startIndex: number) => {
    if (items.length === 0) return null;
    return (
      <div className="py-1" role="group" aria-label={title}>
        <div className="px-2 py-1 text-xs font-semibold text-muted-foreground">
          {title}
        </div>
        {items.map((item, i) => {
          const index = startIndex + i;
          return (
            <SearchItem
              key={item.id}
              item={item}
              index={index}
              isSelected={index === selectedIndex}
              Icon={Icon}
              onClick={handleSelect}
            />
          );
        })}
      </div>
    );
  };

  const handleClear = () => {
    setQuery("");
    setOpen(false);
    inputRef.current?.focus();
  };

  return (
    <div className="relative hidden lg:block w-64">
      <div className="relative">
        <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground pointer-events-none" />
        <input
          ref={inputRef}
          type="text"
          role="combobox"
          aria-autocomplete="list"
          aria-expanded={open && query.length > 0}
          aria-haspopup="listbox"
          aria-controls="nav-search-results"
          aria-activedescendant={open && hasResults ? `nav-search-option-${selectedIndex}` : undefined}
          aria-label="Zur Seite navigieren"
          placeholder="Suchen (Produkte, Bestellungen...)"
          className="w-full h-9 rounded-lg bg-muted/50 border border-transparent hover:border-primary/50 focus:border-primary focus:ring-1 focus:ring-primary pl-9 pr-8 text-sm outline-none transition-all"
          value={query}
          onChange={(e) => {
            setQuery(e.target.value);
            setOpen(true);
            setSelectedIndex(0);
          }}
          onFocus={() => setOpen(true)}
          onKeyDown={handeKeyDown}
        />
        {isPending ? (
            <Loader2 className="absolute right-2.5 top-2.5 h-4 w-4 animate-spin text-muted-foreground" />
        ) : query ? (
            <button
                type="button"
                aria-label="Suche löschen"
                onClick={handleClear}
                className="absolute right-2.5 top-2.5 h-4 w-4 text-muted-foreground hover:text-foreground focus:outline-none focus:ring-1 focus:ring-primary rounded-sm transition-colors"
            >
                <X className="h-4 w-4" />
            </button>
        ) : (
            <Kbd className="absolute right-2.5 top-2 h-5 hidden md:inline-flex text-xs">
                {isMac ? "⌘K" : "Ctrl K"}
            </Kbd>
        )}
      </div>

      {/* Screen reader announcements */}
      <div className="sr-only" role="status" aria-live="polite">
        {query && !isPending && (
            hasResults 
                ? `${allResults.length} ${allResults.length === 1 ? 'Ergebnis gefunden' : 'Ergebnisse gefunden'}`
                : "Keine Ergebnisse gefunden"
        )}
      </div>

      {open && query && (
        <div 
            id="nav-search-results"
            role="listbox"
            className="absolute top-full mt-2 w-full bg-popover rounded-md border shadow-md max-h-[80vh] overflow-y-auto z-50"
        >
          {hasResults ? (
            <div className="py-1">
                {renderGroup("Seiten", filteredNavItems, LayoutDashboard, 0)}
                {renderGroup("Produkte", serverResults.products, Package, filteredNavItems.length)}
                {renderGroup("Bestellungen", serverResults.orders, ShoppingBag, filteredNavItems.length + serverResults.products.length)}
                {renderGroup("Benutzer", serverResults.users, Users, filteredNavItems.length + serverResults.products.length + serverResults.orders.length)}
            </div>
          ) : (
            <div className="p-4 text-sm text-center text-muted-foreground">
                {isPending ? "Suche..." : "Keine Ergebnisse gefunden"}
            </div>
          )}
        </div>
      )}
    </div>
  );
}
