import { defineCommand, arg } from "politty";
import { z } from "zod";
import { readErpKitVersion } from "../../../util";
import { executeCommand, success } from "../../lib/command-result";
import { formatMeasureStructureReport, runMeasureStructure } from "./structure";
import { formatMeasureThinReport, runMeasureThin } from "./thin";
import { runMeasureVersions } from "./versions";

const thinCommand = defineCommand({
  name: "thin",
  description: "Measure implementation thinness across resolvers, commands, and frontend pages",
  args: z.object({
    appRoot: arg(z.string().optional(), {
      alias: "a",
      description: "Path to an app directory (measures resolvers + frontend)",
    }),
    modulesRoot: arg(z.string().optional(), {
      alias: "m",
      description: "Path to a modules directory (measures commands + lib)",
    }),
  }),
  run: (args) => {
    return executeCommand(async () => {
      const result = await runMeasureThin(
        { appRoot: args.appRoot, modulesRoot: args.modulesRoot },
        process.cwd(),
      );
      console.log(formatMeasureThinReport(result));
      return success();
    });
  },
});

const structureCommand = defineCommand({
  name: "structure",
  description:
    "Check repository structure: naming/placement against bundled rule tree + required-dir presence",
  args: z.object({
    appRoot: arg(z.string().optional(), {
      alias: "a",
      description: "Path to an app directory (scans resolvers + app shape)",
    }),
    modulesRoot: arg(z.string().optional(), {
      alias: "m",
      description: "Path to a modules directory (checks module structure)",
    }),
  }),
  run: (args) => {
    return executeCommand(async () => {
      const result = await runMeasureStructure(
        { appRoot: args.appRoot, modulesRoot: args.modulesRoot },
        process.cwd(),
      );
      console.log(formatMeasureStructureReport(result));
      return success();
    });
  },
});

const versionsCommand = defineCommand({
  name: "versions",
  description:
    "Check that workspace dependencies and installed skills match the running erp-kit version",
  args: z.object({
    appsRoot: arg(z.string().default("apps"), {
      alias: "a",
      description: "Path to an apps directory (scans each app's backend/frontend package.json)",
    }),
    modulesRoot: arg(z.string().default("modules"), {
      alias: "m",
      description: "Path to a modules directory (scans each module's package.json)",
    }),
  }),
  run: (args) => {
    return executeCommand(async () => {
      const result = await runMeasureVersions({
        appsRoot: args.appsRoot,
        modulesRoot: args.modulesRoot,
        cwd: process.cwd(),
        installedVersion: readErpKitVersion(),
      });
      console.log(JSON.stringify(result, null, 2));
      return success();
    });
  },
});

export const measureCommand = defineCommand({
  name: "measure",
  description: "Measure repository code characteristics",
  subCommands: {
    thin: thinCommand,
    structure: structureCommand,
    versions: versionsCommand,
  },
});
