import { PublicationAtom } from "@/recoil/atoms/publication";
import { useState, useEffect, useCallback, useRef, ReactNode } from "react";
import { useRecoilValue } from "recoil";
import { TTCQueryResolver } from "../ttcQuery/TTCResolvers";

export function Resolver({ resolver }: { resolver: string }) {
  const parser = useRecoilValue(PublicationAtom);
  const [res] = useState(new TTCQueryResolver(parser));
  const [content, setContent] = useState<ReactNode>("");
  useEffect(() => {
    let resolved = res.resolve(resolver);

    setContent(
      typeof resolved?.display === "function" ? (
        <resolved.display />
      ) : (
        resolved?.display
      )
    );
  }, [resolver, res]);
  return <span>{content}</span>;
}

export function OnDemandResolver({
  resolver,
  template,
  title,
}: {
  resolver: string;
  template: string;
  title?: string;
}) {
  const parser = useRecoilValue(PublicationAtom);
  const res = useRef(new TTCQueryResolver(parser));
  const [content, setContent] = useState<ReactNode>("");
  const generateContent = useCallback(() => {
    let content = template || "$x";
    const stackIdxs = Array.from(new Set(content.match(/\$(?:\d+|x)/g)));
    for (const idx of stackIdxs) {
      let thing = res.current.getFromStack(idx);
      if (Array.isArray(thing)) thing = thing.at(0);
      if (typeof thing.display === "function")
        content = content.replaceAll(idx, thing.display() as string);
      else content = content.replaceAll(idx, thing.display as string);
    }
    setContent(content);
  }, [res, template]);

  const resolve = useCallback(() => {
    res.current.resolve(resolver, true);
    generateContent();
  }, [res, resolver, generateContent]);

  return (
    <div className="my-2 rounded-md p-1 bg-black/20 w-min">
      <button
        className="text-primary-600"
        onMouseDown={() => setContent("")}
        onClick={resolve}
      >
        {title ?? "Resolve"}
      </button>
      <br />
      {!!content && <span>{content}</span>}
    </div>
  );
}
