import { defineCommand } from '@kb-labs/sdk';
import { CACHE_KEYS } from '@kb-labs/quality-contracts';
import fs from 'fs';
import path from 'path';

// src/cli/commands/stats.ts
var stats_default = defineCommand({
  id: "quality:stats",
  description: "Show monorepo statistics and health score",
  handler: {
    async execute(ctx, input) {
      const { ui, platform } = ctx;
      const flags = input.flags ?? input;
      if (!flags.refresh) {
        const cached = await platform.cache.get(CACHE_KEYS.STATS);
        if (cached) {
          outputStats(cached, flags, ui);
          return { exitCode: 0 };
        }
      }
      const stats = await collectStats(ctx.cwd);
      if (flags.health) {
        stats.health = calculateHealthScore(stats);
      }
      await platform.cache.set(CACHE_KEYS.STATS, stats, 5 * 60 * 1e3);
      await platform.analytics.track("quality:stats", {
        packages: stats.overview.totalPackages,
        repositories: stats.overview.totalRepositories,
        withHealth: flags.health ?? false
      });
      outputStats(stats, flags, ui);
      return { exitCode: 0 };
    }
  }
});
function findPackages(rootDir) {
  const packages = [];
  if (!fs.existsSync(rootDir)) {
    return packages;
  }
  const entries = fs.readdirSync(rootDir, { withFileTypes: true });
  for (const entry of entries) {
    if (!entry.isDirectory() || !entry.name.startsWith("kb-labs-")) {
      continue;
    }
    const repoPath = path.join(rootDir, entry.name);
    const packagesDir = path.join(repoPath, "packages");
    if (!fs.existsSync(packagesDir)) {
      continue;
    }
    const packageDirs = fs.readdirSync(packagesDir, { withFileTypes: true });
    for (const pkgDir of packageDirs) {
      if (!pkgDir.isDirectory()) {
        continue;
      }
      const packageJsonPath = path.join(packagesDir, pkgDir.name, "package.json");
      if (fs.existsSync(packageJsonPath)) {
        packages.push(packageJsonPath);
      }
    }
  }
  return packages;
}
function calculateSize(packageDir) {
  const srcDir = path.join(packageDir, "src");
  if (!fs.existsSync(srcDir)) {
    return { files: 0, lines: 0, bytes: 0 };
  }
  let files = 0;
  let lines = 0;
  let bytes = 0;
  function walk(dir) {
    const entries = fs.readdirSync(dir, { withFileTypes: true });
    for (const entry of entries) {
      const fullPath = path.join(dir, entry.name);
      if (entry.isDirectory()) {
        walk(fullPath);
      } else if (entry.isFile() && /\.(ts|tsx|js|jsx)$/.test(entry.name)) {
        files++;
        const content = fs.readFileSync(fullPath, "utf-8");
        lines += content.split("\n").length;
        bytes += Buffer.byteLength(content, "utf-8");
      }
    }
  }
  walk(srcDir);
  return { files, lines, bytes };
}
async function collectStats(rootDir) {
  const packages = findPackages(rootDir);
  const stats = {
    overview: {
      totalPackages: 0,
      totalRepositories: 0,
      totalFiles: 0,
      totalLines: 0,
      totalBytes: 0
    },
    byRepository: {},
    dependencies: {
      total: 0,
      workspace: 0,
      external: 0,
      duplicates: 0,
      topUsed: []
    },
    health: {
      score: 0,
      grade: "F",
      issues: []
    },
    largestPackages: []
  };
  const repos = /* @__PURE__ */ new Set();
  const allDeps = /* @__PURE__ */ new Map();
  for (const packagePath of packages) {
    const packageJson = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
    const packageName = packageJson.name;
    if (!packageName || !packageName.startsWith("@kb-labs/")) {
      continue;
    }
    stats.overview.totalPackages++;
    const packageDir = path.dirname(packagePath);
    const repoName = path.basename(path.dirname(path.dirname(packageDir)));
    repos.add(repoName);
    const size = calculateSize(packageDir);
    stats.overview.totalFiles += size.files;
    stats.overview.totalLines += size.lines;
    stats.overview.totalBytes += size.bytes;
    if (!stats.byRepository[repoName]) {
      stats.byRepository[repoName] = {
        name: repoName,
        packages: 0,
        files: 0,
        lines: 0,
        bytes: 0
      };
    }
    stats.byRepository[repoName].packages++;
    stats.byRepository[repoName].files += size.files;
    stats.byRepository[repoName].lines += size.lines;
    stats.byRepository[repoName].bytes += size.bytes;
    const deps = {
      ...packageJson.dependencies,
      ...packageJson.devDependencies
    };
    for (const dep of Object.keys(deps)) {
      stats.dependencies.total++;
      if (dep.startsWith("@kb-labs/")) {
        stats.dependencies.workspace++;
      } else {
        stats.dependencies.external++;
      }
      allDeps.set(dep, (allDeps.get(dep) || 0) + 1);
    }
    stats.largestPackages.push({
      name: packageName,
      repository: repoName,
      files: size.files,
      lines: size.lines,
      bytes: size.bytes
    });
  }
  stats.overview.totalRepositories = repos.size;
  stats.dependencies.duplicates = Array.from(allDeps.values()).filter((count) => count > 1).length;
  stats.dependencies.topUsed = Array.from(allDeps.entries()).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([name, count]) => ({ name, count }));
  stats.largestPackages.sort((a, b) => b.lines - a.lines);
  stats.largestPackages = stats.largestPackages.slice(0, 10);
  return stats;
}
function calculateHealthScore(stats) {
  let score = 100;
  const issues = [];
  if (stats.dependencies.duplicates > 0) {
    const penalty = Math.min(20, stats.dependencies.duplicates * 2);
    score -= penalty;
    issues.push({
      type: "duplicates",
      severity: "warning",
      message: `${stats.dependencies.duplicates} duplicate dependencies (-${penalty})`
    });
  }
  let grade;
  if (score >= 90) {
    grade = "A";
  } else if (score >= 80) {
    grade = "B";
  } else if (score >= 70) {
    grade = "C";
  } else if (score >= 60) {
    grade = "D";
  } else {
    grade = "F";
  }
  return {
    score,
    grade,
    issues
  };
}
function outputStats(stats, flags, ui) {
  if (flags.json) {
    ui?.json?.(stats);
    return;
  }
  if (flags.md) {
    outputMarkdown(stats);
    return;
  }
  const overviewItems = [
    `Packages: ${stats.overview.totalPackages}`,
    `Repositories: ${stats.overview.totalRepositories}`,
    `Lines of Code: ${stats.overview.totalLines.toLocaleString()}`,
    `Total Size: ${formatBytes(stats.overview.totalBytes)}`
  ];
  const sections = [
    { header: "Overview", items: overviewItems }
  ];
  if (flags.health && stats.health) {
    const healthItems = [
      `Score: ${stats.health.score}/100 (Grade ${stats.health.grade})`
    ];
    if (stats.health.issues.length > 0) {
      healthItems.push("");
      healthItems.push("Issues:");
      stats.health.issues.forEach((issue) => {
        healthItems.push(`  ${issue.message}`);
      });
    }
    sections.push({ header: "Health Score", items: healthItems });
  }
  const topRepos = Object.values(stats.byRepository).sort((a, b) => b.lines - a.lines).slice(0, 5).map((repo) => `${repo.name}: ${repo.lines.toLocaleString()} lines, ${repo.packages} pkg(s)`);
  if (topRepos.length > 0) {
    sections.push({ header: "Top Repositories", items: topRepos });
  }
  ui?.success?.("Statistics collected successfully", {
    title: "\u{1F4CA} KB Labs Monorepo Statistics",
    sections
  });
}
function outputMarkdown(stats) {
  console.log("# KB Labs Monorepo Statistics\n");
  console.log("## Overview\n");
  console.log("| Metric | Value |");
  console.log("|--------|-------|");
  console.log(`| Packages | ${stats.overview.totalPackages} |`);
  console.log(`| Repositories | ${stats.overview.totalRepositories} |`);
  console.log(`| Lines of Code | ${stats.overview.totalLines.toLocaleString()} |`);
  console.log(`| Total Size | ${formatBytes(stats.overview.totalBytes)} |
`);
  if (stats.health) {
    console.log("## Health Score\n");
    console.log(`**${stats.health.score}/100** (Grade ${stats.health.grade})
`);
    if (stats.health.issues.length > 0) {
      console.log("### Issues\n");
      for (const issue of stats.health.issues) {
        console.log(`- ${issue.message}`);
      }
      console.log("");
    }
  }
  console.log("## By Repository\n");
  console.log("| Repository | Packages | Lines | Size |");
  console.log("|------------|----------|-------|------|");
  for (const [name, repo] of Object.entries(stats.byRepository)) {
    console.log(`| ${name} | ${repo.packages} | ${repo.lines.toLocaleString()} | ${formatBytes(repo.bytes)} |`);
  }
}
function formatBytes(bytes) {
  if (bytes === 0) {
    return "0 B";
  }
  const k = 1024;
  const sizes = ["B", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`;
}

export { stats_default as default };
//# sourceMappingURL=stats.js.map
//# sourceMappingURL=stats.js.map