import { z } from "zod";
import { defineCommand, arg } from "politty";
import { runCheck } from "../check";
import { runInitModuleWithReadme } from "../init-module";
import { executeCommand, success, silentFailure } from "../lib/command-result";
import { runSyncCheck, formatSyncCheckReport } from "../sync-check";
import { generateCommand } from "./generate";

const cwd = process.cwd();

const pathArgs = z.object({
  path: arg(z.string(), {
    alias: "p",
    description: "Path to modules directory",
  }),
});

const checkCommand = defineCommand({
  name: "check",
  description: "Validate module docs against schemas",
  args: pathArgs,
  run: (args) => {
    return executeCommand(async () => {
      const exitCode = await runCheck({ modulesRoot: args.path }, cwd);
      return exitCode === 0 ? success() : silentFailure(exitCode);
    });
  },
});

const syncCheckCommand = defineCommand({
  name: "sync-check",
  description: "Validate source <-> doc correspondence",
  args: pathArgs,
  run: (args) => {
    return executeCommand(async () => {
      const result = await runSyncCheck({ modulesRoot: args.path }, cwd);
      console.log(formatSyncCheckReport(result));
      return result.exitCode === 0 ? success() : silentFailure(result.exitCode);
    });
  },
});

const initCommand = defineCommand({
  name: "init",
  description: "Bootstrap a new module with directory structure and README",
  args: z.object({
    name: arg(z.string(), {
      positional: true,
      description: "Module name",
    }),
    dir: arg(z.string(), {
      positional: true,
      description: "Parent directory where the module will be created",
    }),
  }),
  run: (args) => {
    return executeCommand(async () => {
      const exitCode = await runInitModuleWithReadme(args.name, args.dir, cwd);
      return exitCode === 0 ? success() : silentFailure(exitCode);
    });
  },
});

export const moduleCommand = defineCommand({
  name: "module",
  description: "Module management",
  subCommands: {
    check: checkCommand,
    "sync-check": syncCheckCommand,
    init: initCommand,
    generate: generateCommand,
  },
});
