import { useQuery } from "@tanstack/react-query";
import type {
  GetTemplateFunctionSummaryResponse,
  TemplateFunction,
} from "@yaakapp-internal/plugins";
import { atom, useAtomValue, useSetAtom } from "jotai";
import { useMemo, useState } from "react";
import type { TwigCompletionOption } from "../components/core/Editor/twig/completion";
import { rpc } from "../lib/rpc";
import { usePluginsKey } from "./usePlugins";

const templateFunctionsAtom = atom<TemplateFunction[]>([]);

export function useTemplateFunctionCompletionOptions(
  onClick: (fn: TemplateFunction, ragTag: string, pos: number) => void,
  enabled: boolean,
) {
  const templateFunctions = useAtomValue(templateFunctionsAtom);
  return useMemo<TwigCompletionOption[]>(() => {
    if (!enabled) {
      return [];
    }
    return templateFunctions.map((fn) => {
      const argsLabel = fn.args.length > 0 ? "…" : "";
      const fn2: TwigCompletionOption = {
        type: "function",
        onClick: (rawTag: string, startPos: number) => onClick(fn, rawTag, startPos),
        label: `${fn.name}(${argsLabel})`,
        invalid: false,
        value: null,
        ...fn,
      };
      return fn2;
    });
  }, [enabled, onClick, templateFunctions]);
}

export function useSubscribeTemplateFunctions() {
  const pluginsKey = usePluginsKey();
  const [numFns, setNumFns] = useState<number>(0);
  const setAtom = useSetAtom(templateFunctionsAtom);

  useQuery({
    queryKey: ["template_functions", pluginsKey],
    // Fetch periodically until functions are returned
    // NOTE: visibilitychange (refetchOnWindowFocus) does not work on Windows, so we'll rely on this logic
    //  to refetch things until that's working again
    // TODO: Update plugin system to wait for plugins to initialize before sending the first event to them
    refetchInterval: numFns > 0 ? Number.POSITIVE_INFINITY : 1000,
    refetchOnMount: true,
    queryFn: async () => {
      const result = await rpc<GetTemplateFunctionSummaryResponse[]>(
        "cmd_template_function_summaries",
      );
      setNumFns(result.length);
      const functions = result.flatMap((r) => r.functions) ?? [];
      setAtom(functions);
      return functions;
    },
  });
}
