import type { ExtensionAPI } from "@jaeswift/jae-coding-agent";
import { existsSync, readFileSync, mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path";

export default function (pi: ExtensionAPI) {
  pi.on("before_agent_start", async (_event, ctx) => {
    const dnaPath = join(ctx.cwd, ".jae", "project-dna.md");
    if (existsSync(dnaPath)) {
      const dna = readFileSync(dnaPath, "utf-8").trim();
      if (dna.length > 0) {
        return { systemPrompt: `\n\n# Project DNA (auto-generated fingerprint)\n\n${dna}` };
      }
    }
  });

  pi.on("session_start", async (_event, ctx) => {
    const dnaPath = join(ctx.cwd, ".jae", "project-dna.md");
    if (!existsSync(dnaPath)) {
      ctx.ui.notify("\u{1F9EC} No project DNA found. Run /dna to auto-analyze your project.", "info");
    }
  });

  pi.registerCommand("dna", {
    description: "Auto-analyze project and generate .jae/project-dna.md fingerprint",
    handler: async (args, ctx) => {
      const cwd = ctx.cwd;
      const jaeDir = join(cwd, ".jae");
      const dnaPath = join(jaeDir, "project-dna.md");

      if (args.trim() === "show" && existsSync(dnaPath)) {
        const dna = readFileSync(dnaPath, "utf-8");
        ctx.ui.notify(`\u{1F9EC} Project DNA:\n${dna.substring(0, 1500)}`, "info");
        return;
      }

      ctx.ui.notify("\u{1F50D} Analyzing project...", "info");

      const sections: string[] = ["# Project DNA\n"];

      // Tech stack detection
      const checks = [
        { file: "package.json", label: "Node.js" },
        { file: "Cargo.toml", label: "Rust" },
        { file: "go.mod", label: "Go" },
        { file: "pyproject.toml", label: "Python (pyproject)" },
        { file: "requirements.txt", label: "Python (pip)" },
        { file: "Gemfile", label: "Ruby" },
        { file: "pom.xml", label: "Java (Maven)" },
        { file: "build.gradle", label: "Java/Kotlin (Gradle)" },
        { file: "docker-compose.yml", label: "Docker Compose" },
        { file: "Dockerfile", label: "Docker" },
        { file: ".github/workflows", label: "GitHub Actions" },
        { file: "tsconfig.json", label: "TypeScript" },
        { file: ".eslintrc.json", label: "ESLint" },
        { file: "vitest.config.ts", label: "Vitest" },
        { file: "jest.config.js", label: "Jest" },
        { file: "tailwind.config.js", label: "Tailwind CSS" },
        { file: "next.config.js", label: "Next.js" },
        { file: "vite.config.ts", label: "Vite" },
      ];

      const detected: string[] = [];
      for (const c of checks) {
        if (existsSync(join(cwd, c.file))) detected.push(c.label);
      }
      sections.push(`## Tech Stack\n${detected.length > 0 ? detected.map((d) => `- ${d}`).join("\n") : "- Unknown"}\n`);

      // Package.json details
      const pkgPath = join(cwd, "package.json");
      if (existsSync(pkgPath)) {
        try {
          const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
          sections.push(
            `## Package Info\n- Name: ${pkg.name || "unknown"}\n- Version: ${pkg.version || "unknown"}\n- Description: ${pkg.description || "none"}\n`,
          );
          if (pkg.dependencies) {
            const deps = Object.keys(pkg.dependencies).slice(0, 20);
            sections.push(`## Dependencies (top 20)\n${deps.map((d) => `- ${d}`).join("\n")}\n`);
          }
          if (pkg.scripts) {
            const scripts = Object.entries(pkg.scripts).slice(0, 15) as [string, string][];
            sections.push(`## Scripts\n${scripts.map(([k, v]) => `- \`${k}\`: ${v}`).join("\n")}\n`);
          }
        } catch {
          /* ignore parse errors */
        }
      }

      // Git info
      try {
        const gitResult = await pi.exec("git", ["log", "--oneline", "-10"], { cwd });
        if (gitResult.code === 0 && gitResult.stdout.trim()) {
          sections.push(`## Recent Git History\n\`\`\`\n${gitResult.stdout.trim()}\n\`\`\`\n`);
        }
        const branchResult = await pi.exec("git", ["branch", "--show-current"], { cwd });
        if (branchResult.code === 0 && branchResult.stdout.trim()) {
          sections.push(`## Current Branch: ${branchResult.stdout.trim()}\n`);
        }
      } catch {
        /* not a git repo */
      }

      // File stats
      try {
        const findResult = await pi.exec(
          "find",
          [".", "-maxdepth", "3", "-type", "f", "-not", "-path", "*/node_modules/*", "-not", "-path", "*/.git/*", "-not", "-path", "*/dist/*", "-not", "-path", "*/.jae/*"],
          { cwd },
        );
        if (findResult.code === 0) {
          const files = findResult.stdout.trim().split("\n").filter(Boolean);
          sections.push(`## File Count: ${files.length}\n`);
          const extCounts: Record<string, number> = {};
          for (const f of files) {
            const ext = f.includes(".") ? (f.split(".").pop() || "none") : "(no ext)";
            extCounts[ext] = (extCounts[ext] || 0) + 1;
          }
          const sorted = Object.entries(extCounts)
            .sort((a, b) => b[1] - a[1])
            .slice(0, 15);
          sections.push(`## File Types\n${sorted.map(([ext, count]) => `- .${ext}: ${count}`).join("\n")}\n`);
        }
      } catch {
        /* ignore */
      }

      sections.push(`\n---\nGenerated: ${new Date().toISOString()}\n`);

      const dnaContent = sections.join("\n");
      if (!existsSync(jaeDir)) mkdirSync(jaeDir, { recursive: true });
      writeFileSync(dnaPath, dnaContent, "utf-8");

      ctx.ui.notify(
        `\u{1F9EC} Project DNA generated (${dnaContent.length} chars). Saved to .jae/project-dna.md`,
        "info",
      );
    },
  });
}
