"use client";

import * as React from "react";
import { useRouter } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { Loader2 } from "lucide-react";
import {
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
} from "@/components/ui/command";
import { useDebounce } from "@/hooks/use-debounce";
import { useAuthToken } from "@/hooks/use-auth-token";
import {
  fetchGlobalSearch,
  GLOBAL_SEARCH_MIN_CHARS,
} from "@/features/global-search/fetch-global-search";
import { HighlightSearchText } from "@/features/global-search/highlight-search-text";
import { globalSearchKeys } from "@/features/global-search/query-keys";
import { GLOBAL_SEARCH_NAV_ITEMS } from "@/features/global-search/nav-items";
import { GLOBAL_SEARCH_MODULES } from "@/features/global-search/search-modules";
import { cn } from "@/lib/utils";

type GlobalSearchDialogProps = {
  open: boolean;
  onOpenChange: (open: boolean) => void;
};

function SearchResultItem({
  icon: Icon,
  label,
  subtitle,
  badge,
  query,
}: {
  icon: React.ComponentType<{ className?: string }>;
  label: string;
  subtitle?: string;
  badge?: string;
  query: string;
}) {
  return (
    <div className="flex min-w-0 flex-1 items-center gap-3">
      <Icon className="size-4 shrink-0 text-muted-foreground" />
      <div className="min-w-0 flex-1">
        <p className="truncate text-sm font-medium">
          <HighlightSearchText text={label} query={query} />
        </p>
        {subtitle ? (
          <p className="truncate text-xs text-muted-foreground">
            <HighlightSearchText text={subtitle} query={query} />
          </p>
        ) : null}
      </div>
      {badge ? (
        <span className="shrink-0 rounded-md border border-border/70 bg-background px-1.5 py-0.5 text-[10px] font-semibold uppercase tracking-wide text-foreground group-data-[selected=true]/search-item:border-white/30 group-data-[selected=true]/search-item:bg-white/20 group-data-[selected=true]/search-item:text-accent-foreground">
          {badge}
        </span>
      ) : null}
    </div>
  );
}

export function GlobalSearchDialog({ open, onOpenChange }: GlobalSearchDialogProps) {
  const router = useRouter();
  const { token } = useAuthToken();
  const [query, setQuery] = React.useState("");
  const debouncedQuery = useDebounce(query, 100);
  const trimmed = debouncedQuery.trim();
  const searchActive = trimmed.length >= GLOBAL_SEARCH_MIN_CHARS;

  React.useEffect(() => {
    if (!open) setQuery("");
  }, [open]);

  const { data, isFetching, isLoading, isPlaceholderData } = useQuery({
    queryKey: globalSearchKeys.query(trimmed),
    queryFn: ({ signal }) => fetchGlobalSearch(trimmed, signal),
    enabled: !!token && open && searchActive,
    placeholderData: (previous) => previous,
    staleTime: 60_000,
    gcTime: 300_000,
  });

  const results = data ?? {
    leads: [],
    salesDeals: [],
    customers: [],
    tasks: [],
  };

  const activeModules = React.useMemo(
    () =>
      GLOBAL_SEARCH_MODULES.map((module) => ({
        ...module,
        items: module.getItems(results),
      })).filter((module) => module.items.length > 0),
    [results],
  );

  const totalResults = activeModules.reduce(
    (count, module) => count + module.items.length,
    0,
  );

  const filteredNav = React.useMemo(() => {
    if (searchActive) return [];
    const q = trimmed.toLowerCase();
    if (!q) return GLOBAL_SEARCH_NAV_ITEMS;
    return GLOBAL_SEARCH_NAV_ITEMS.filter((item) => {
      const haystack = `${item.label} ${item.keywords ?? ""}`.toLowerCase();
      return haystack.includes(q);
    });
  }, [searchActive, trimmed]);

  const navigate = React.useCallback(
    (href: string) => {
      onOpenChange(false);
      router.push(href);
    },
    [onOpenChange, router],
  );

  const showLoading = searchActive && isLoading && !data;
  const showRefining = searchActive && isFetching && !isLoading;
  const showEmpty =
    searchActive &&
    !showLoading &&
    totalResults === 0 &&
    !isFetching &&
    !isPlaceholderData;

  return (
    <CommandDialog
      open={open}
      onOpenChange={onOpenChange}
      title="Search SalesHub"
      description="Search leads, deals, customers, and tasks"
      className="max-w-xl"
      shouldFilter={false}
    >
      <CommandInput
        placeholder="Search leads, sales deals, customers, tasks…"
        value={query}
        onValueChange={setQuery}
      />
      {showRefining ? (
        <div className="flex items-center gap-2 border-b px-3 py-1.5 text-[11px] text-muted-foreground">
          <Loader2 className="size-3 animate-spin" />
          Updating results…
        </div>
      ) : null}
      <CommandList className="max-h-[min(420px,60vh)]">
        {showLoading ? (
          <div className="flex items-center justify-center gap-2 py-8 text-sm text-muted-foreground">
            <Loader2 className="size-4 animate-spin" />
            Searching…
          </div>
        ) : null}

        {showEmpty ? (
          <CommandEmpty>No results for &ldquo;{trimmed}&rdquo;</CommandEmpty>
        ) : null}

        {!searchActive && filteredNav.length > 0 ? (
          <CommandGroup heading="Go to">
            {filteredNav.map((item) => (
              <CommandItem
                key={item.id}
                className="group/search-item"
                value={`${item.label} ${item.keywords ?? ""}`}
                onSelect={() => navigate(item.href)}
              >
                <HighlightSearchText text={item.label} query={trimmed} />
              </CommandItem>
            ))}
          </CommandGroup>
        ) : null}

        {!searchActive && !trimmed ? (
          <p className="px-3 py-4 text-center text-xs text-muted-foreground">
            Type at least {GLOBAL_SEARCH_MIN_CHARS} characters to search across
            leads, sales deals, customers, and tasks.
          </p>
        ) : null}

        {searchActive
          ? activeModules.map((module) => (
              <CommandGroup key={module.id} heading={module.heading}>
                {module.items.map((item) => (
                  <CommandItem
                    key={module.getKey(item)}
                    className="group/search-item"
                    value={module.getCommandValue(item)}
                    onSelect={() => navigate(module.getHref(item))}
                  >
                    <SearchResultItem
                      icon={module.icon}
                      label={module.getLabel(item)}
                      subtitle={module.getSubtitle(item)}
                      badge={module.badge}
                      query={trimmed}
                    />
                  </CommandItem>
                ))}
              </CommandGroup>
            ))
          : null}

        {searchActive && totalResults > 0 ? (
          <>
            <CommandSeparator />
            <p
              className={cn(
                "px-3 py-2 text-center text-[11px] text-muted-foreground",
              )}
            >
              {totalResults} result{totalResults === 1 ? "" : "s"} — use ↑↓ to
              navigate, Enter to open
            </p>
          </>
        ) : null}
      </CommandList>
    </CommandDialog>
  );
}
