import { Fragment, useEffect, useRef, useState } from "react";
import { Combobox, Dialog, Menu, Transition } from "@headlessui/react";
import useDebounce from "@/lib/hooks/useDebounce";
import Image from "next/image";
import { useRouter } from "next/router";
import { useSearch } from "@/lib/context/isOpenState";
import { ChevronDownIcon, ChevronRightIcon } from "@heroicons/react/24/outline";
import { BookOpenIcon, PlayIcon } from "@heroicons/react/20/solid";
import { useAniList } from "@/lib/anilist/useAnilist";
import { getFormat } from "@/utils/getFormat";
import SearchByImage from "./search/searchByImage";

type SearchType = "ANIME" | "MANGA";

export interface DataTypes {
  id: number;
  title: Title;
  coverImage: CoverImage;
  type: string;
  format: string;
  bannerImage?: string;
  isLicensed: boolean;
  genres: string[];
  startDate: StartDate;
}

interface Title {
  userPreferred: string;
}

interface CoverImage {
  medium: string;
}

interface StartDate {
  year: number;
}

export default function SearchPalette() {
  const { isOpen, setIsOpen } = useSearch();
  const { quickSearch } = useAniList();

  const [query, setQuery] = useState<string>("");
  const [data, setData] = useState<DataTypes[] | null>(null);
  const debounceSearch = useDebounce(query, 500);
  const [loading, setLoading] = useState<boolean>(false);
  const [type, setType] = useState<SearchType>("ANIME");

  const [nextPage, setNextPage] = useState<boolean>(false);

  let focusInput = useRef<HTMLInputElement>(null);
  const router = useRouter();

  function closeModal() {
    setIsOpen(false);
  }

  function handleChange(event: string): void {
    router.push(`/en/${type.toLowerCase()}/${event}`);
  }

  async function advance(): Promise<void> {
    setLoading(true);
    const res = await quickSearch({
      search: debounceSearch,
      type,
    });
    setData(res?.data?.Page?.results);
    setNextPage(res?.data?.Page?.pageInfo?.hasNextPage);
    setLoading(false);
  }

  useEffect(() => {
    advance();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [debounceSearch, type]);

  useEffect(() => {
    const handleKeyDown = (e: any) => {
      if (e.code === "KeyS" && e.ctrlKey) {
        // do your stuff
        e.preventDefault();
        setIsOpen((prev: boolean) => !prev);
        setData(null);
        setQuery("");
      }
    };

    window.addEventListener("keydown", handleKeyDown);

    return () => {
      window.removeEventListener("keydown", handleKeyDown);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <Transition appear show={isOpen} as={Fragment}>
      <Dialog
        as="div"
        className="relative z-[6969]"
        initialFocus={focusInput}
        onClose={closeModal}
      >
        <Transition.Child
          as={Fragment}
          enter="ease-out duration-300"
          enterFrom="opacity-0"
          enterTo="opacity-100"
          leave="ease-in duration-200"
          leaveFrom="opacity-100"
          leaveTo="opacity-0"
        >
          <div className="fixed inset-0 bg-black/90" />
        </Transition.Child>

        <div className="fixed inset-0 overflow-y-auto">
          <div className="flex min-h-full items-center justify-center p-4  text-center">
            <Transition.Child
              as={Fragment}
              enter="ease-out duration-200"
              enterFrom="opacity-0 scale-95"
              enterTo="opacity-100 scale-100"
              leave="ease-in duration-100"
              leaveFrom="opacity-100 scale-100"
              leaveTo="opacity-0 scale-95"
            >
              <Dialog.Panel className="w-full max-w-2xl max-h-[68dvh] transform text-left transition-all">
                <Combobox
                  as="div"
                  className="max-w-2xl mx-auto rounded-lg shadow-2xl relative flex flex-col"
                  onChange={(e: any) => {
                    handleChange(e);
                    setData(null);
                    setIsOpen(false);
                    setQuery("");
                  }}
                >
                  <div className="flex justify-between py-1 font-karla">
                    <div className="flex items-center px-2 gap-2">
                      <p>For quick access :</p>
                      <div className="bg-secondary text-white text-xs font-bold px-2 py-1 rounded-md">
                        <span>CTRL</span>
                      </div>
                      <span>+</span>
                      <div className="bg-secondary text-white text-xs font-bold px-2 py-1 rounded-md">
                        <span>S</span>
                      </div>
                    </div>
                    <div className="flex gap-1 items-center">
                      <Menu
                        as="div"
                        className="relative inline-block text-left"
                      >
                        <div>
                          <Menu.Button className="capitalize bg-secondary inline-flex w-full justify-center rounded px-3 py-2 text-sm font-medium text-white hover:bg-opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
                            {type.toLowerCase()}
                            <ChevronDownIcon
                              className="ml-2 -mr-1 h-5 w-5 text-violet-200 hover:text-violet-100"
                              // aria-hidden="true"
                            />
                          </Menu.Button>
                        </div>
                        <Transition
                          as={Fragment}
                          enter="transition ease-out duration-100"
                          enterFrom="transform opacity-0 scale-95"
                          enterTo="transform opacity-100 scale-100"
                          leave="transition ease-in duration-75"
                          leaveFrom="transform opacity-100 scale-100"
                          leaveTo="transform opacity-0 scale-95"
                        >
                          <Menu.Items className="absolute right-0 mt-2 w-56 origin-top-right divide-y divide-gray-100 rounded-md bg-primary shadow ring-1 ring-black ring-opacity-5 focus:outline-none">
                            <div className="px-1 py-1">
                              <Menu.Item>
                                {({ active }) => (
                                  <button
                                    title="Anime"
                                    onClick={() => setType("ANIME")}
                                    className={`${
                                      active
                                        ? "bg-secondary text-white"
                                        : "text-white"
                                    } group flex w-full items-center gap-3 rounded-md px-2 py-2 text-sm`}
                                  >
                                    <PlayIcon className="w-6 h-6" />
                                    <span>Anime</span>
                                  </button>
                                )}
                              </Menu.Item>
                              <Menu.Item>
                                {({ active }) => (
                                  <button
                                    title="Manga"
                                    onClick={() => setType("MANGA")}
                                    className={`${
                                      active
                                        ? "bg-secondary text-white"
                                        : "text-white"
                                    } group flex w-full items-center gap-3 rounded-md px-2 py-2 text-sm`}
                                  >
                                    <BookOpenIcon className="w-6 h-6" />
                                    <span>Manga</span>
                                  </button>
                                )}
                              </Menu.Item>
                            </div>
                          </Menu.Items>
                        </Transition>
                      </Menu>
                      <SearchByImage
                        searchPalette={true}
                        setIsOpen={setIsOpen}
                      />
                    </div>
                  </div>
                  <div className="flex items-center text-base font-medium rounded bg-secondary">
                    <Combobox.Input
                      ref={focusInput}
                      className="p-5 text-white w-full bg-transparent border-0 outline-none"
                      placeholder="Search something..."
                      onChange={(event) => setQuery(event.target.value)}
                    />
                  </div>
                  <Combobox.Options
                    static
                    className="bg-secondary rounded mt-2 max-h-[50dvh] overflow-y-auto flex flex-col scrollbar-thin scrollbar-thumb-primary scrollbar-thumb-rounded"
                  >
                    {!loading ? (
                      <Fragment>
                        {data && data?.length > 0
                          ? data?.map((i) => (
                              <Combobox.Option
                                key={i.id}
                                value={i.id}
                                className={({ active }) =>
                                  `flex items-center gap-3 p-5 ${
                                    active ? "bg-primary/40 cursor-pointer" : ""
                                  }`
                                }
                              >
                                <div className="shrink-0">
                                  <Image
                                    src={i.coverImage.medium}
                                    alt="coverImage"
                                    width={100}
                                    height={100}
                                    className="w-16 h-16 object-cover rounded"
                                  />
                                </div>
                                <div className="flex flex-col w-full h-full">
                                  <h3 className="font-karla font-semibold">
                                    {i.title.userPreferred}
                                  </h3>
                                  <p className="text-sm text-white/50">
                                    {i.startDate.year} {getFormat(i.format)}
                                  </p>
                                </div>
                              </Combobox.Option>
                            ))
                          : !loading &&
                            debounceSearch !== "" && (
                              <p className="flex-center font-karla gap-3 p-5">
                                No results found.
                              </p>
                            )}
                        {nextPage && (
                          <button
                            type="button"
                            title="View More"
                            onClick={() => {
                              router.push(
                                `/en/search/${type.toLowerCase()}/${
                                  query !== "" ? `?search=${query}` : ""
                                }`
                              );
                              setIsOpen(false);
                              setQuery("");
                            }}
                            className="flex-center font-karla gap-2 py-4 hover:bg-primary/30 cursor-pointer"
                          >
                            <span>View More</span>
                            <ChevronRightIcon className="w-4 h-4" />
                          </button>
                        )}
                      </Fragment>
                    ) : (
                      <div className="flex-center gap-3 p-5">
                        <div className="flex justify-center">
                          <div className="lds-ellipsis">
                            <span></span>
                            <span></span>
                            <span></span>
                            <span></span>
                          </div>
                        </div>
                      </div>
                    )}
                  </Combobox.Options>
                </Combobox>
              </Dialog.Panel>
            </Transition.Child>
          </div>
        </div>
      </Dialog>
    </Transition>
  );
}
