import { existsSync } from 'fs';
import { resolve } from 'path';
import { spawnSync } from 'child_process';

// src/vite-plugin-knowledge/index.ts
function detectLayout(viteRoot) {
  let dir = viteRoot;
  for (; ; ) {
    if (existsSync(resolve(dir, ".elevasis"))) {
      const projectRoot = dir;
      return {
        mode: "external",
        projectRoot,
        omSourcePath: resolve(projectRoot, "core/config/organization-model.ts"),
        mdxNodesDir: resolve(projectRoot, "core/config/knowledge/nodes"),
        generatedDir: resolve(projectRoot, "core/config/knowledge/_generated"),
        watchPaths: [
          resolve(projectRoot, "core/config/knowledge/nodes"),
          resolve(projectRoot, "core/config/organization-model.ts")
        ]
      };
    }
    if (existsSync(resolve(dir, "pnpm-workspace.yaml"))) {
      const projectRoot = dir;
      return {
        mode: "monorepo",
        projectRoot,
        omSourcePath: resolve(projectRoot, "packages/elevasis-core/src/organization-model/index.ts"),
        // monorepo mode does not consume mdxNodesDir; field kept for type uniformity
        mdxNodesDir: resolve(projectRoot, "packages/elevasis-core/knowledge-nodes-unused"),
        generatedDir: resolve(projectRoot, "packages/ui/src/knowledge/_generated"),
        watchPaths: [resolve(projectRoot, "packages/elevasis-core/src/organization-model")]
      };
    }
    const parent = resolve(dir, "..");
    if (parent === dir) {
      throw new Error("knowledgePlugin: no '.elevasis' or 'pnpm-workspace.yaml' found above the Vite root");
    }
    dir = parent;
  }
}
function knowledgePlugin() {
  let layout;
  async function runCodegen() {
    if (layout.mode === "monorepo") {
      const result = spawnSync(
        "pnpm",
        ["-C", "packages/ui", "exec", "tsx", "scripts/run-knowledge-bodies-codegen.ts"],
        {
          cwd: layout.projectRoot,
          encoding: "utf8",
          shell: process.platform === "win32"
        }
      );
      if (result.status !== 0) {
        throw new Error(result.error?.message || result.stderr || result.stdout || "knowledge codegen failed");
      }
      return;
    }
    const sdkNodeSpecifier = "@elevasis/sdk/node";
    const { runKnowledgeCodegen } = await import(
      /* @vite-ignore */
      sdkNodeSpecifier
    );
    await runKnowledgeCodegen(layout);
  }
  return {
    name: "elevasis:knowledge",
    configResolved(config) {
      layout = detectLayout(config.root);
    },
    async buildStart() {
      await runCodegen();
      if (this.meta.watchMode) {
        for (const p of layout.watchPaths) this.addWatchFile(p);
      }
    },
    async handleHotUpdate({ file, server }) {
      const watched = layout.watchPaths.some((p) => file === p || file.startsWith(p + "/") || file.startsWith(p + "\\"));
      if (!watched) return;
      try {
        await runCodegen();
      } catch (err) {
        server.config.logger.error(`[knowledge-plugin] codegen failed: ${String(err)}`);
        return;
      }
      const bodies = server.moduleGraph.getModuleById(resolve(layout.generatedDir, "knowledge-bodies.tsx"));
      if (bodies) {
        server.moduleGraph.invalidateModule(bodies);
        server.hot.send({ type: "full-reload" });
      }
    }
  };
}

export { knowledgePlugin };
