import { getAllWikiPaths, getWikiContent } from "../../../lib/wiki/api";
import WikiPage from "../../../interfaces/WikiPage";
import DashLayout from "../../../layouts/DashLayout";
import Link from "next/link";
import { m } from "framer-motion";
import PageBody from "../../../components/wiki/PageBody";
import { ReactElement, useEffect, useState } from "react";
import Image from "next/image";

interface WikiLandingPageProps {
  children: React.ReactNode;
  page: WikiPage;
}

interface TableOfContentsItem {
  id: string;
  type: string;
  text: string;
}

function WikiLandingPage(props: WikiLandingPageProps) {
  const [wikiContent, setWikiContent] = useState<ReactElement>(<></>);
  const [indexContent, setIndexContent] = useState<TableOfContentsItem[]>([]);
  const [showMobileIndex, setShowMobileIndex] = useState<boolean>(false);

  // needed for proper hydration due to replacing some elements
  useEffect(() => {
    setWikiContent(<PageBody page={props.page}>{props.page.content}</PageBody>);
  }, [props.page]);

  useEffect(() => {
    const toc: TableOfContentsItem[] = [];
    const headings = document.querySelectorAll("h2, h3");
    // store the heading text, id, and type, keep order
    headings.forEach((heading) => {
      const id = heading.getAttribute("id");
      const type = heading.tagName.toLowerCase();
      const text = heading.textContent;
      if (id && type && text) {
        toc.push({ id, type, text });
      }
    });
    setIndexContent(toc);
  }, [wikiContent]);

  const dirPath = props.page.path.split("/").map((path, index) => {
    // if home page, don't show
    if (path === "home") return <></>;
    return (
      <div key={path} className="flex flex-row">
        <span className="mx-2 flex items-center text-white">
          <m.svg
            viewBox={"0 0 24 24"}
            width={20}
            height={20}
            origin="center"
            color="currentColor"
            fill="currentColor"
            stroke="currentColor"
            strokeWidth="2"
            strokeLinecap="round"
            strokeLinejoin="round"
          >
            <m.path d="M6.23 20.23 8 22l10-10L8 2 6.23 3.77 14.46 12z" />
          </m.svg>
        </span>
        <Link
          href={`/wiki/${props.page.language}/${props.page.path
            .split("/")
            .slice(0, index + 1)
            .join("/")}`}
        >
          <p className="hover:text-orange-400">{path}</p>
        </Link>
      </div>
    );
  });

  return (
    <div className="flex w-full flex-col items-center justify-center p-3 font-plusJakarta ">
      <div className="inline-grid h-full w-full max-w-screen-2xl grid-cols-10">
        {/* Desktop Header */}
        <div className="col-span-10 mb-2 hidden grid-cols-10 lg:inline-grid">
          {/* Title */}
          <div className="col-span-2 flex items-center justify-center">
            <div className="text-2xl text-white">
              <p>toffee wiki</p>
            </div>
            <Image
              className="h-auto w-auto"
              src="/img/logo.webp"
              alt="toffee logo"
              width={64}
              height={64}
            />
          </div>
          {/* Dir Path */}
          <div className="col-span-8 ml-3 mb-3 mt-3 flex text-left text-xl">
            <div className="flex w-auto flex-row items-center justify-start rounded-full bg-black p-2 px-4">
              <Link href="/wiki">
                <p className="hover:text-orange-400">home</p>
              </Link>
              {dirPath}
            </div>
          </div>
        </div>
        {/* Sidebar */}
        <div className="col-span-2 hidden w-full flex-col items-center justify-center lg:block">
          <div className="w-full rounded-tl-2xl rounded-bl-2xl border-r-2 border-orange-400 border-opacity-60 bg-zinc-800 bg-opacity-70 p-6 text-left text-6xl text-white">
            <div className="text-2xl">Contents</div>
            <div className="mt-4 text-left text-orange-400">
              {indexContent.map((item) => {
                return (
                  // increase indent based on heading level
                  <div
                    style={{
                      paddingLeft: `${(parseInt(item.type[1]) - 2) * 1.25}rem`,
                    }}
                    className="text-xl"
                    key={item.id}
                  >
                    <Link href={`#${item.id}`}>
                      <p className="mt-2 overflow-hidden overflow-ellipsis whitespace-nowrap hover:text-white">
                        {item.text}
                      </p>
                    </Link>
                  </div>
                );
              })}
            </div>
          </div>
        </div>
        <div className="col-span-10 mb-6 lg:hidden">
          {/* Dir Path Mobile */}
          <div className="col-span-8 flex text-left text-xl">
            <div className="flex w-auto flex-row items-center justify-start rounded-full bg-black p-2 px-4">
              <Link href="/wiki">
                <p className="hover:text-orange-400">home</p>
              </Link>
              {dirPath}
            </div>
          </div>
        </div>
        {/* Mobile "Side"-bar */}
        <div className="col-span-10 mb-6 lg:hidden">
          <div className="w-full rounded-2xl rounded-tl-2xl bg-zinc-800 bg-opacity-70 p-6 text-left text-6xl text-white">
            <div
              className="flex cursor-pointer flex-row justify-between text-2xl"
              onClick={() => setShowMobileIndex(!showMobileIndex)}
            >
              <div>Contents</div>
              <m.svg
                className="pointer-events-auto mt-2 ml-3 cursor-pointer lg:hidden"
                origin="center"
                width="20"
                height="21"
                viewBox="0 0 330 330"
                x={0}
                y={0}
                animate={{ rotate: showMobileIndex ? 180 : 0 }}
              >
                <m.path
                  d="M325.607,79.393c-5.857-5.857-15.355-5.858-21.213,0.001l-139.39,139.393L25.607,79.393  c-5.857-5.857-15.355-5.858-21.213,0.001c-5.858,5.858-5.858,15.355,0,21.213l150.004,150c2.813,2.813,6.628,4.393,10.606,4.393  s7.794-1.581,10.606-4.394l149.996-150C331.465,94.749,331.465,85.251,325.607,79.393z"
                  fill="white"
                  stroke="white"
                  strokeWidth="15"
                  strokeLinecap="round"
                />
              </m.svg>
            </div>

            <m.div
              className="overflow-hidden text-left text-orange-400"
              animate={{
                height: showMobileIndex ? "auto" : 0,
                marginTop: showMobileIndex ? "0.5rem" : 0,
              }}
            >
              {indexContent.map((item) => {
                return (
                  // increase indent based on heading level
                  <div
                    style={{
                      paddingLeft: `${(parseInt(item.type[1]) - 2) * 2}rem`,
                    }}
                    className="text-xl"
                    key={item.id}
                  >
                    <Link href={`#${item.id}`}>
                      <p className="mt-2 overflow-hidden overflow-ellipsis whitespace-nowrap hover:text-white">
                        {item.text}
                      </p>
                    </Link>
                  </div>
                );
              })}
            </m.div>
          </div>
        </div>
        {/* Main content */}
        <div className="col-span-10 rounded-2xl bg-zinc-800 bg-opacity-70 px-6 pb-5 text-center text-6xl text-white lg:col-span-8 lg:rounded-tl-none">
          <m.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            transition={{ delay: 0.3 }}
            key={props.page.slug}
          >
            <div className="w-full px-3">{wikiContent}</div>
          </m.div>
        </div>
      </div>
    </div>
  );
}

type Params = {
  params: {
    slug: string[];
  };
};

export async function getStaticProps({ params }: Params) {
  // only language
  if (params.slug.length < 2) {
    // if langauge is two letters, redirect to its home
    if (params.slug[0].length === 2 && params.slug[0].match(/^[a-z]+$/i)) {
      return {
        redirect: {
          destination: `/wiki/${params.slug[0]}/home`,
        },
      };
    }
    // else, 404 to prevemt building pointless pages (e.g. /wiki/this-is-not-a-language x 580258538 times)
    return {
      notFound: true,
    };
  }
  // slug[0] = language
  // slug[1...n] = page path
  const lang = params.slug[0];
  const path = params.slug.slice(1).join("/");
  const pageData = getWikiContent(lang, path);

  // if no content, 404
  if (!pageData) {
    return {
      notFound: true,
    };
  }

  return {
    props: {
      page: {
        slug: params.slug,
        content: pageData.content,
        language: lang,
        path: path,
        data: pageData.data,
      },
    },
  };
}

export async function getStaticPaths() {
  const paths = getAllWikiPaths();

  return {
    paths: paths.map((path) => {
      return {
        params: {
          slug: path.split("/"),
        },
      };
    }),
    fallback: "blocking",
  };
}

WikiLandingPage.getLayout = function getLayout(page: React.ReactNode) {
  const metaTags = {
    title: "Wiki - toffee",
    description: "Wiki for toffee",
  };
  return <DashLayout metaTags={metaTags}>{page}</DashLayout>;
};

export default WikiLandingPage;