import { createElements } from "@/lib/tcmd";
import React, { FC, Suspense, useEffect, useMemo, useState } from "react";

import { MDSkeletonLoader } from "../loader";
import { DevTool } from "../devtools/Toolbox";

interface Props {
  body: string;
  escapeTOC?: (tokens: Token[]) => boolean;
  parserId: string;
  title: string;
}

export const TTCMD: FC<Props> = (
  { body, parserId, escapeTOC = () => false, title },
) => {
  const elements = useMemo(() => createElements(body), [body]);

  const [toc, start, end] = useMemo(() => {
    const tocHead = elements.findIndex((t) =>
      t.content.includes("Table of Contents")
    );
    if (tocHead > -1) {
      const hr = elements.slice(tocHead).findIndex((t) => t.type === "hr");
      if (hr > -1) {
        const end = hr + 1;
        return [elements.slice(tocHead, end), tocHead, end - tocHead];
      }
    }
    return [[], 0, 0];
  }, [elements]);

  // const hasEscapedTOC = useMemo(() => toc && escapeTOC(toc), [escapeTOC, toc])
  const [hasEscapedTOC, setHasEscapedTOC] = useState<boolean>();

  useEffect(() => {
    setHasEscapedTOC(escapeTOC(toc));
  }, [escapeTOC, toc]);

  return (
    <Suspense fallback={<MDSkeletonLoader />}>
      <DevTool id={parserId}>
        <button
          className="btn-primary"
          onClick={() =>
            navigator.clipboard.writeText(JSON.stringify(elements, null, 2))}
        >
          Copy AST for {title}
        </button>
      </DevTool>
      {hasEscapedTOC !== undefined &&
        (
          <TTCMDRenderer
            tokens={hasEscapedTOC
              ? [...elements].toSpliced(start, end)
              : elements}
          />
        )}
    </Suspense>
  );
};

export const TTCMDRenderer: FC<{ tokens: Token[] }> = (
  { tokens },
) => {
  const tada = useMemo(
    () => (
      <>
        {renderer(tokens)}
      </>
    ),
    [tokens],
  );
  if (!tokens.length) {
    const audio = new Audio(
      "https://assets.mixkit.co/active_storage/sfx/221/221-preview.mp3",
    );
    audio.onload = () => {
      audio.play();
    };
  }
  return (
    <div className="text-lg">
      {tada}
    </div>
  );
};

function renderer(tokens: Token[]) {
  return tokens.map((t) => <div className="p" key={t.uuid}>{t.render(t)}</div>);
}
