import { useCallback, useEffect, useRef } from "react";
import { useEditorStore } from "@/stores/editorStore";
import { compile } from "@/api/client";

const DEBOUNCE_MS = 400;

/**
 * Debounced hook that compiles µFrame source via the API.
 * Automatically triggers on ufSource changes.
 */
export function useCompile() {
  const ufSource = useEditorStore((s) => s.ufSource);
  const setCompileResult = useEditorStore((s) => s.setCompileResult);
  const setCompiling = useEditorStore((s) => s.setCompiling);
  const setCompileError = useEditorStore((s) => s.setCompileError);

  const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const abortRef = useRef<AbortController | null>(null);

  const doCompile = useCallback(
    async (source: string) => {
      if (!source.trim()) {
        setCompileResult("", "", "", false, []);
        return;
      }

      abortRef.current?.abort();
      const controller = new AbortController();
      abortRef.current = controller;

      setCompiling(true);

      try {
        const data = await compile(source, controller.signal);
        setCompileResult(
          data.ascii,
          data.micron,
          data.script || "",
          data.is_dynamic || false,
          data.warnings || [],
        );
      } catch (e: unknown) {
        if (e instanceof DOMException && e.name === "AbortError") return;
        setCompileError(e instanceof Error ? e.message : "Compile failed");
      }
    },
    [setCompileResult, setCompiling, setCompileError],
  );

  useEffect(() => {
    if (timerRef.current) clearTimeout(timerRef.current);
    timerRef.current = setTimeout(() => doCompile(ufSource), DEBOUNCE_MS);
    return () => {
      if (timerRef.current) clearTimeout(timerRef.current);
    };
  }, [ufSource, doCompile]);

  useEffect(() => {
    return () => {
      abortRef.current?.abort();
    };
  }, []);
}
