import { readdirSync, readFileSync, existsSync } from "node:fs";
import { join } from "node:path";
import { PACKAGE_ROOT } from "../../../util";
import { type CommandResult, success } from "../../lib/command-result";
import { MODULE_PATHS } from "../../lib/paths";

const MODULES_DIR = join(PACKAGE_ROOT, "src", "modules");

interface ModuleOverview {
  name: string;
  commandCount: number;
  queryCount: number;
  modelCount: number;
  overview: string;
  dependencies: string[];
}

function countDocs(dir: string): number {
  if (!existsSync(dir)) return 0;
  return readdirSync(dir).filter((f) => f.endsWith(".md")).length;
}

function extractOverview(readmePath: string): string {
  if (!existsSync(readmePath)) return "";
  const content = readFileSync(readmePath, "utf-8");
  const overviewMatch = /## Overview\n\n([\s\S]*?)(?=\n##\s|\n$)/.exec(content);
  if (!overviewMatch) return "";
  const firstParagraph = overviewMatch[1].trim().split("\n\n")[0];
  return firstParagraph;
}

function extractDependencies(readmePath: string): string[] {
  if (!existsSync(readmePath)) return [];
  const content = readFileSync(readmePath, "utf-8");
  const depsMatch = /## Module Dependencies\n\n([\s\S]*?)(?=\n##\s|$)/.exec(content);
  if (!depsMatch) return [];
  const deps: string[] = [];
  const linePattern = /^- \[([^\]]+)\]/;
  for (const line of depsMatch[1].trim().split("\n")) {
    const match = linePattern.exec(line);
    if (match) deps.push(match[1]);
  }
  return deps;
}

export function getModuleOverviews(): ModuleOverview[] {
  if (!existsSync(MODULES_DIR)) return [];
  return readdirSync(MODULES_DIR, { withFileTypes: true })
    .filter((d) => d.isDirectory())
    .map((d) => {
      const modDir = join(MODULES_DIR, d.name);
      const readmePath = join(modDir, "README.md");
      return {
        name: d.name,
        commandCount: countDocs(join(modDir, MODULE_PATHS.docs.command)),
        queryCount: countDocs(join(modDir, MODULE_PATHS.docs.query)),
        modelCount: countDocs(join(modDir, MODULE_PATHS.docs.model)),
        overview: extractOverview(readmePath),
        dependencies: extractDependencies(readmePath),
      };
    })
    .sort((a, b) => a.name.localeCompare(b.name));
}

export function formatModuleOverviews(modules: ModuleOverview[]): string {
  if (modules.length === 0) return "No modules found.";

  const lines: string[] = [];
  for (const mod of modules) {
    const counts = [
      `${mod.commandCount} commands`,
      `${mod.queryCount} queries`,
      `${mod.modelCount} models`,
    ].join(", ");
    lines.push(`# ${mod.name} (${counts})`);
    if (mod.overview) {
      lines.push(mod.overview);
    }
    if (mod.dependencies.length > 0) {
      lines.push(`Dependencies: ${mod.dependencies.join(", ")}`);
    } else {
      lines.push("Dependencies: none");
    }
    lines.push("");
  }
  lines.push(`${modules.length} modules`);
  return lines.join("\n");
}

export function runDocModules(format = "text"): CommandResult {
  const modules = getModuleOverviews();
  if (format === "json") {
    console.log(JSON.stringify(modules, null, 2));
  } else {
    console.log(formatModuleOverviews(modules));
  }
  return success();
}
