"use client";

import React, { ReactElement, useState } from "react";
import { DocsContentMetadata } from "@/app/common/documentation";
import {
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from "@/app/components/ui/command";
import { Button, ButtonProps } from "@/app/components/ui/button";
import { useRouter } from "next/navigation";
import { cn } from "@/app/common/utils";

export function CommandMenu({ ...props }: ButtonProps): ReactElement {
  const router = useRouter();

  /**
   * Whether to show the search
   */
  const [open, setOpen] = useState<boolean>(false);

  /**
   * The pages that were found
   */
  const [pages, setPages] = useState<DocsContentMetadata[] | undefined>(undefined);

  // Handle keyboard shortcuts
  React.useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if ((e.key === "k" && (e.metaKey || e.ctrlKey)) || e.key === "/") {
        if (
          (e.target instanceof HTMLElement && e.target.isContentEditable) ||
          e.target instanceof HTMLInputElement ||
          e.target instanceof HTMLTextAreaElement ||
          e.target instanceof HTMLSelectElement
        ) {
          return;
        }

        e.preventDefault();
        setOpen(open => !open);
      }
    };

    return () => document.removeEventListener("keydown", down);
  }, []);

  /**
   * Search the documentation
   * for the given query.
   *
   * @param query the query to search for
   */
  async function searchDocs(query: string): Promise<void> {
    // Don't bother searching if the query is less than 3 characters
    if (query.length < 3) {
      setPages(undefined);
      return;
    }

    // Attempt to search for the query
    const response = await fetch(`/api/docs/search?query=${query}`);
    const pages: DocsContentMetadata[] = await response.json();
    setPages(pages);
  }

  return (
    <>
      <Button
        variant="outline"
        className={cn(
          "relative h-8 w-full justify-start rounded-[0.5rem] bg-background text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-64",
          props.className,
        )}
        onClick={() => setOpen(true)}
      >
        Search
      </Button>

      <CommandDialog open={open} onOpenChange={setOpen}>
        <CommandInput
          placeholder="Query..."
          onValueChange={async search => {
            await searchDocs(search);
          }}
        />
        <CommandList>
          <CommandEmpty>No results found.</CommandEmpty>
          {pages && (
            <CommandGroup heading="Suggestions">
              {pages.map(page => {
                return (
                  <CommandItem
                    key={page.slug}
                    onSelect={() => {
                      router.push(`/docs/${page.slug}`);
                      setOpen(false);
                    }}
                  >
                    {page.title}
                  </CommandItem>
                );
              })}
            </CommandGroup>
          )}
        </CommandList>
      </CommandDialog>
    </>
  );
}
