import { readable } from "svelte/store";

export const wasmReady = readable(false, (set) => {
  if (typeof window === "undefined") {
    return;
  }

  const loadWasm = async () => {
    const go = new globalThis.Go();
    try {
      const result = await WebAssembly.instantiateStreaming(
        fetch("/_playground/main.wasm"),
        go.importObject,
      );
      go.run(result.instance);
      set(true);
    } catch (error) {
      console.error("Error loading wasm module:", error);
    }
  };

  if (document.readyState === "complete") {
    loadWasm();
  } else {
    globalThis.addEventListener("load", loadWasm);
  }
});

export type ParseResultSuccess = {
  data: unknown;
  timings: { [key: string]: number };
};

export type ParseResultError = {
  error: string;
};

export type ParseResult = ParseResultSuccess | ParseResultError;

export function parseMarkdown(markdown: string): ParseResult {
  if (typeof globalThis.marka?.parseFile !== "function") {
    throw new Error("Wasm module not ready");
  }
  const resultString = globalThis.marka.parseFile(markdown);
  return JSON.parse(resultString);
}

export function compileTemplate(templateSource: string) {
  if (typeof globalThis.marka?.compileTemplate !== "function") {
    throw new Error("Wasm module not ready");
  }
  const resultString = globalThis.marka.compileTemplate(templateSource);
  const result = JSON.parse(resultString);
  console.log({ result });
  return result;
}

export function matchBlocks(markdown: string, template: string): ParseResult {
  if (typeof globalThis.marka?.matchBlocks !== "function") {
    throw new Error("Wasm module not ready");
  }
  const resultString = globalThis.marka.matchBlocks(markdown, template);
  return JSON.parse(resultString);
}

export function parseMarkdownWithTemplate(
  markdown: string,
  template: string,
): ParseResult {
  if (typeof globalThis.marka?.parseFileWithTemplate !== "function") {
    throw new Error("Wasm module not ready");
  }
  const resultString = globalThis.marka.parseFileWithTemplate(
    markdown,
    template,
  );
  return JSON.parse(resultString);
}

export function listTemplates(): string[] {
  if (typeof globalThis.marka?.listTemplates !== "function") {
    throw new Error("Wasm module not ready");
  }
  const resultString = globalThis.marka.listTemplates();
  return JSON.parse(resultString);
}

export function getTemplate(name: string): string {
  if (typeof globalThis.marka?.getTemplate !== "function") {
    throw new Error("Wasm module not ready");
  }
  return globalThis.marka.getTemplate(name);
}

export function detectType(markdown: string): string | ParseResultError {
  if (typeof globalThis.marka?.detectType !== "function") {
    throw new Error("Wasm module not ready");
  }
  const result = globalThis.marka.detectType(markdown);
  try {
    // If the result is a JSON string with an error, parse and return it
    const parsed = JSON.parse(result);
    if (parsed.error) {
      return parsed;
    }
  } catch (e) {
    // Otherwise, it's a plain string for success
    return result;
  }
  return result;
}
