import { useEffect, useRef, useState } from "preact/hooks";
import useDebouncedCallback from "@lib/hooks/useDebouncedCallback.ts";
import { IconGhost, IconLoader2, IconSearch } from "@components/icons.tsx";
import { useEventListener } from "@lib/hooks/useEventListener.ts";
import { SearchResponse } from "https://raw.githubusercontent.com/bradenmacdonald/typesense-deno/main/src/Typesense/Documents.ts";
import { Recipe } from "@lib/resource/recipes.ts";
import { Movie } from "@lib/resource/movies.ts";
import { Article } from "@lib/resource/articles.ts";
import { useTraceUpdate } from "@lib/hooks/useTraceProps.ts";
import { SearchResult } from "@lib/types.ts";
import { resources } from "@lib/resources.ts";
import { isLocalImage } from "@lib/string.ts";

export const RedirectSearchHandler = () => {
  useEventListener("keydown", (e: KeyboardEvent) => {
    if (e?.target?.nodeName == "INPUT") return;

    if (
      e.key === "?" &&
      window.location.search === ""
    ) {
      window.location.href += "?q=";
    }
  });

  return <></>;
};

const SearchResultImage = ({ src }: { src: string }) => {
  const imageSrc = isLocalImage(src)
    ? `/api/images?image=${src}&width=50&height=50`
    : src;

  return (
    <img
      class="object-cover w-12 h-12 rounded-full"
      src={imageSrc}
      alt="preview image"
    />
  );
};

export const SearchResultItem = (
  { item, showEmoji = false }: {
    item: NonNullable<SearchResult["hits"]>[number];
    showEmoji?: boolean;
  },
) => {
  const doc = item.document;
  const resourceType = resources[doc.type];
  const href = (resourceType) ? `${resourceType.link}/${doc.id}` : "";
  return (
    <a
      href={href}
      class="p-2 text-white flex gap-4 items-center rounded-2xl hover:bg-gray-700"
    >
      {doc?.image && <SearchResultImage src={doc.image} />}
      {`${showEmoji && resourceType ? resourceType.emoji : ""}`} {doc?.name}
    </a>
  );
};

export const SearchResultList = (
  { result, showEmoji }: { result: SearchResult; showEmoji?: boolean },
) => {
  return (
    <div class="mt-4">
      {result?.hits
        ? (
          <div class="flex flex-col gap-4">
            {result.hits.map((hit) => (
              <SearchResultItem item={hit} showEmoji={showEmoji} />
            ))}
          </div>
        )
        : <div style={{ color: "#818181" }}>No Results</div>}
    </div>
  );
};

const SearchComponent = (
  { q, type }: { q: string; type?: string },
) => {
  const [searchQuery, setSearchQuery] = useState(q);
  const [data, setData] = useState<SearchResult>();
  const [isLoading, setIsLoading] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  if ("history" in globalThis) {
    const u = new URL(window.location.href);
    if (u.searchParams.get("q") !== searchQuery) {
      u.searchParams.set("q", searchQuery);
      window.history.replaceState({}, "", u);
    }
  }

  const fetchData = async (query: string) => {
    try {
      setIsLoading(true);
      const fetchUrl = new URL(window.location.href);
      fetchUrl.pathname = "/api/resources";
      if (query) {
        fetchUrl.searchParams.set("q", encodeURIComponent(query));
      } else {
        return;
      }
      if (type) {
        fetchUrl.searchParams.set("type", type);
      }
      const response = await fetch(fetchUrl);
      const jsonData = await response.json();
      setData(jsonData);
      setIsLoading(false);
    } catch (error) {
      console.error("Error fetching data:", error);
      setIsLoading(false);
    }
  };

  useEffect(() => {
    if (inputRef.current && searchQuery?.length === 0) {
      inputRef.current?.focus();
    }
  }, [inputRef.current, searchQuery]);

  const debouncedFetchData = useDebouncedCallback(fetchData, 500); // Debounce the fetchData function with a delay of 500ms

  const handleInputChange = (event: Event) => {
    const target = event.target as HTMLInputElement;
    if (target.value !== searchQuery) {
      setSearchQuery(target.value);
      debouncedFetchData(target.value); // Call the debounced fetch function with the updated search query
    }
  };

  useEffect(() => {
    debouncedFetchData(q);
  }, []);

  console.log({ data, isLoading });
  return (
    <div class="mt-2">
      <div
        class="flex items-center gap-1 rounded-xl w-full shadow-2xl"
        style={{ background: "#2B2930", color: "#818181" }}
      >
        {isLoading
          ? <IconLoader2 class="w-4 h-4 ml-4 mr-2 animate-spin" />
          : <IconSearch class="w-4 h-4 ml-4 mr-2" />}
        <input
          type="text"
          style={{ fontSize: "1.2em" }}
          class="bg-transparent py-3 w-full"
          ref={inputRef}
          value={searchQuery}
          onInput={handleInputChange}
        />
      </div>
      {data?.hits?.length && !isLoading
        ? <SearchResultList showEmoji={!type} result={data} />
        : isLoading
        ? <div />
        : (
          <div
            class="flex items-center gap-2 p-2 my-4 mx-3"
            style={{ color: "#818181" }}
          >
            <IconGhost class="animate-hover" />
            No Results
          </div>
        )}
    </div>
  );
};

export default SearchComponent;
