"use client";
import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react";
import { useApiClient } from "../../lib/apiClient";
import { components } from "../../lib/gen";

const DEBOUNCE_MS = 250;

type User = components["schemas"]["SimpleProfileInfoSchema"];
type Genre = components["schemas"]["GenreSchema"];

type ResultItem =
  | { type: "user"; user: User }
  | { type: "genre"; genre: Genre };

export default function SearchInput({
  onSearch,
}: {
  onSearch: (user: User | string) => void;
}) {
  const [isFocused, setIsFocused] = useState(false);
  const [value, setValue] = useState("");
  const [results, setResults] = useState<ResultItem[]>([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [showDropdown, setShowDropdown] = useState(false);
  const [selectedIdx, setSelectedIdx] = useState<number>(-1);
  const apiClient = useApiClient();
  const debounceRef = useRef<NodeJS.Timeout | null>(null);
  const inputRef = useRef<HTMLInputElement>(null);
  const router = useRouter();

  useEffect(() => {
    if (!isFocused) {
      setShowDropdown(false);
      setSelectedIdx(-1);
      return;
    }
    if (!value.trim()) {
      setResults([]);
      setShowDropdown(false);
      setSelectedIdx(-1);
      return;
    }
    setLoading(true);
    setError(null);
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(async () => {
      try {
        const userQuery = {
          name: `user${value}`,
          search_type: "user" as const,
          term: value,
          from_index: 0,
          size: 10,
          rank_by: "trending" as const,
        };
        const genreQuery = {
          name: `platform_genre${value}`,
          search_type: "platform_genre" as const,
          term: value,
          from_index: 0,
          size: 10,
          rank_by: "most_relevant" as const,
        };
        const res = await apiClient.POST("/api/search", {
          body: { search_queries: [userQuery, genreQuery] },
        });
        // The response is a SearchResult, with .result[key].result[]
        let userResults: User[] = [];
        let genreResults: Genre[] = [];
        if (res.data && res.data.result) {
          Object.entries(res.data.result).forEach(([key, base]) => {
            if (base && Array.isArray(base.result)) {
              base.result.forEach((item) => {
                if (
                  item &&
                  typeof item === "object" &&
                  (item as any).entity_type === "simple_profile_schema"
                ) {
                  userResults.push(item as User);
                } else if (
                  item &&
                  typeof item === "object" &&
                  (item as any).entity_type === "genre_schema"
                ) {
                  genreResults.push(item as Genre);
                }
              });
            }
          });
        }
        // Add up to 2 genres at the top, then up to 8 users
        const genreItems: ResultItem[] = genreResults
          .slice(0, 2)
          .map((genre) => ({ type: "genre" as const, genre }));
        const userItems: ResultItem[] = userResults
          .slice(0, 8)
          .map((user) => ({ type: "user" as const, user }));
        setResults([...genreItems, ...userItems]);
        setShowDropdown(true);
        setSelectedIdx(-1);
      } catch (err) {
        setError("Failed to search");
        setResults([]);
        setShowDropdown(true);
        setSelectedIdx(-1);
      } finally {
        setLoading(false);
      }
    }, DEBOUNCE_MS);
    // Cleanup
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, [value, isFocused, apiClient]);

  // Keyboard navigation
  useEffect(() => {
    if (!isFocused || !showDropdown) return;
    function handleKeyDown(e: KeyboardEvent) {
      if (e.key === "ArrowDown") {
        e.preventDefault();
        setSelectedIdx((idx) => {
          let next = idx + 1;
          if (next >= results.length) next = 0;
          return next;
        });
      } else if (e.key === "ArrowUp") {
        e.preventDefault();
        setSelectedIdx((idx) => {
          let prev = idx - 1;
          if (prev < 0) prev = results.length - 1;
          return prev;
        });
      } else if (e.key === "Enter") {
        if (selectedIdx >= 0 && selectedIdx < results.length) {
          const selected = results[selectedIdx];
          if (selected.type === "user") {
            const user = selected.user;
            setIsFocused(false);
            setShowDropdown(false);
            setValue(user.display_name || user.handle || "");
            onSearch(user);
            router.push(`/profile/${user.handle}`);
          } else if (selected.type === "genre") {
            const genre = selected.genre;
            setIsFocused(false);
            setShowDropdown(false);
            setValue(genre.genre);
            onSearch(genre.genre);
            router.push(`/style/${encodeURIComponent(genre.genre)}`);
          }
        }
      } else if (e.key === "Escape") {
        setIsFocused(false);
        setShowDropdown(false);
      }
    }
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [isFocused, showDropdown, results, selectedIdx, onSearch, router]);

  // Close dropdown on click outside
  useEffect(() => {
    if (!isFocused) return;
    function handleClick(e: MouseEvent) {
      if (inputRef.current && !inputRef.current.contains(e.target as Node)) {
        setIsFocused(false);
        setShowDropdown(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, [isFocused]);

  return (
    <div className="w-full relative">
      <input
        ref={inputRef}
        type="text"
        placeholder="Search..."
        value={value}
        onChange={(e) => {
          setValue(e.target.value);
          setSelectedIdx(-1);
        }}
        onFocus={() => setIsFocused(true)}
        className="w-full bg-gray-500/60 backdrop-blur-xl border border-black/[.08] dark:border-white/[.145] rounded-[20px] px-4 py-3 text-sm placeholder-foreground/60 text-foreground focus:outline-none focus:ring-2 focus:ring-blue-500/50 transition-all"
        autoComplete="off"
      />
      {isFocused && showDropdown && (
        <div className="absolute left-0 right-0 mt-2 bg-gray-700/95 backdrop-blur-xl border border-black/[.08] dark:border-white/[.145] rounded-[16px] shadow-2xl z-50 overflow-hidden">
          {loading ? (
            <div className="p-4 text-center text-foreground/60 text-sm">
              Loading...
            </div>
          ) : error ? (
            <div className="p-4 text-center text-red-500 text-sm">{error}</div>
          ) : results.length === 0 ? (
            <div className="p-4 text-center text-foreground/60 text-sm">
              No users found
            </div>
          ) : (
            <ul>
              {results.map((item, idx) =>
                item.type === "user" ? (
                  <li
                    key={item.user.external_user_id}
                    className={`flex items-center gap-3 px-4 py-2 hover:bg-blue-600/30 cursor-pointer transition-colors ${
                      idx === selectedIdx ? "bg-blue-600/50" : ""
                    }`}
                    onMouseEnter={() => setSelectedIdx(idx)}
                    onMouseDown={(e) => {
                      // Use onMouseDown to avoid input blur before click
                      e.preventDefault();
                      setIsFocused(false);
                      setShowDropdown(false);
                      setValue(
                        item.user.display_name || item.user.handle || ""
                      );
                      onSearch(item.user);
                      router.push(`/profile/${item.user.handle}`);
                    }}
                  >
                    <img
                      src={item.user.avatar_image_url || "/default-avatar.png"}
                      alt={item.user.display_name || item.user.handle || "User"}
                      className="w-8 h-8 rounded-full object-cover bg-gray-400"
                    />
                    <div className="flex flex-col min-w-0">
                      <span className="font-medium text-white truncate">
                        {item.user.display_name || item.user.handle}
                      </span>
                      <span className="text-xs text-foreground/60 truncate">
                        @{item.user.handle}
                      </span>
                    </div>
                  </li>
                ) : (
                  <li
                    key={"genre-" + item.genre.genre}
                    className={`flex items-center gap-3 px-4 py-2 hover:bg-blue-600/30 cursor-pointer select-none transition-colors font-medium text-white text-base ${
                      idx === selectedIdx ? "bg-blue-600/50" : ""
                    }`}
                    onMouseEnter={() => setSelectedIdx(idx)}
                    onMouseDown={(e) => {
                      // Use onMouseDown to avoid input blur before click
                      e.preventDefault();
                      setIsFocused(false);
                      setShowDropdown(false);
                      setValue(item.genre.genre);
                      onSearch(item.genre.genre);
                      router.push(
                        `/style/${encodeURIComponent(item.genre.genre)}`
                      );
                    }}
                  >
                    <span className="truncate">{item.genre.genre}</span>
                  </li>
                )
              )}
            </ul>
          )}
        </div>
      )}
    </div>
  );
}
