import { defineCommand } from '@kb-labs/sdk';
import { buildDependencyGraph, getReverseDependencies, getImpactAnalysis } from '@kb-labs/quality-core/graph';

// src/cli/commands/visualize.ts
var visualize_default = defineCommand({
  id: "quality:visualize",
  description: "Visualize dependency graph",
  handler: {
    async execute(ctx, input) {
      const { ui } = ctx;
      const flags = input.flags ?? input;
      const graph = buildDependencyGraph(ctx.cwd);
      if (flags.dot) {
        outputDot(graph, flags, ui);
      } else if (flags.tree && flags.package) {
        outputTree(graph, flags.package, flags, ui);
      } else if (flags.reverse && flags.package) {
        outputReverse(graph, flags.package, flags, ui);
      } else if (flags.impact && flags.package) {
        outputImpact(graph, flags.package, flags, ui);
      } else if (flags.stats) {
        outputStats(graph, flags, ui);
      } else {
        outputStats(graph, flags, ui);
      }
      return { exitCode: 0 };
    }
  }
});
function outputTree(graph, packageName, flags, ui) {
  const { nodes } = graph;
  const node = nodes.get(packageName);
  if (!node) {
    ui?.fatal?.(`Package not found: ${packageName}`);
    return;
  }
  const sections = [];
  const visited = /* @__PURE__ */ new Set();
  const treeItems = [];
  function buildTree(pkg, depth, prefix) {
    if (visited.has(pkg)) {
      treeItems.push(`${prefix}${pkg} (circular)`);
      return;
    }
    visited.add(pkg);
    const pkgNode = nodes.get(pkg);
    if (!pkgNode) {
      return;
    }
    treeItems.push(`${prefix}${pkg}`);
    const deps = Array.from(pkgNode.deps);
    for (let i = 0; i < deps.length; i++) {
      const dep = deps[i];
      if (!dep) {
        continue;
      }
      const isLast = i === deps.length - 1;
      const newPrefix = prefix + (isLast ? "  \u2514\u2500 " : "  \u251C\u2500 ");
      buildTree(dep, depth + 1, newPrefix);
    }
  }
  buildTree(packageName, 0, "");
  sections.push({
    header: "Dependency Tree",
    items: treeItems
  });
  ui?.success?.("Dependency tree generated", {
    title: `\u{1F4E6} Dependency Tree for ${packageName}`,
    sections
  });
}
function outputReverse(graph, packageName, flags, ui) {
  const reverseDeps = getReverseDependencies(graph, packageName);
  if (flags.json) {
    ui?.json?.({ package: packageName, reverseDependencies: Array.from(reverseDeps) });
    return;
  }
  const sections = [];
  if (reverseDeps.size === 0) {
    sections.push({
      header: "Result",
      items: ["No packages depend on this package"]
    });
  } else {
    sections.push({
      header: `Packages that depend on ${packageName}`,
      items: Array.from(reverseDeps).map((dep) => `\u2022 ${dep}`)
    });
  }
  ui?.success?.("Reverse dependencies found", {
    title: `\u2B05\uFE0F Reverse Dependencies for ${packageName}`,
    sections
  });
}
function outputImpact(graph, packageName, flags, ui) {
  const affected = getImpactAnalysis(graph, packageName);
  if (flags.json) {
    ui?.json?.({ package: packageName, affectedPackages: Array.from(affected) });
    return;
  }
  const sections = [];
  if (affected.size === 0) {
    sections.push({
      header: "Result",
      items: ["No other packages affected by changes to this package"]
    });
  } else {
    sections.push({
      header: `Impact Analysis for ${packageName}`,
      items: [
        `Changes to this package will affect ${affected.size} other packages:`,
        "",
        ...Array.from(affected).map((dep) => `\u2022 ${dep}`)
      ]
    });
    sections.push({
      header: "Recommendations",
      items: [
        "\u{1F9EA} Run tests in affected packages",
        "\u{1F528} Rebuild affected packages",
        "\u{1F4DD} Update documentation if API changed"
      ]
    });
  }
  ui?.success?.("Impact analysis completed", {
    title: `\u{1F4A5} Impact Analysis for ${packageName}`,
    sections
  });
}
function outputStats(graph, flags, ui) {
  const { nodes } = graph;
  let totalDeps = 0;
  let maxDeps = 0;
  let maxDepsPackage = "";
  const depCounts = /* @__PURE__ */ new Map();
  for (const [name, node] of nodes) {
    const depCount = node.deps.size;
    totalDeps += depCount;
    if (depCount > maxDeps) {
      maxDeps = depCount;
      maxDepsPackage = name;
    }
    depCounts.set(depCount, (depCounts.get(depCount) ?? 0) + 1);
  }
  const avgDeps = nodes.size > 0 ? (totalDeps / nodes.size).toFixed(2) : "0";
  if (flags.json) {
    ui?.json?.({
      totalPackages: nodes.size,
      totalDependencies: totalDeps,
      averageDependencies: Number.parseFloat(avgDeps),
      maxDependencies: maxDeps,
      maxDependenciesPackage: maxDepsPackage
    });
    return;
  }
  const sections = [];
  sections.push({
    header: "Graph Statistics",
    items: [
      `Total packages: ${nodes.size}`,
      `Total dependencies: ${totalDeps}`,
      `Average dependencies per package: ${avgDeps}`,
      `Max dependencies: ${maxDeps} (${maxDepsPackage})`
    ]
  });
  const distributionItems = [];
  const sortedCounts = Array.from(depCounts.entries()).sort((a, b) => a[0] - b[0]);
  for (const [count, packages] of sortedCounts) {
    const bar = "\u2588".repeat(Math.min(packages, 20));
    distributionItems.push(`${count} deps: ${bar} ${packages} packages`);
  }
  sections.push({
    header: "Dependency Distribution",
    items: distributionItems
  });
  ui?.success?.("Graph statistics calculated", {
    title: "\u{1F4CA} Dependency Graph Statistics",
    sections
  });
}
function outputDot(graph, flags, ui) {
  const { nodes } = graph;
  const lines = [];
  lines.push("digraph dependencies {");
  lines.push("  rankdir=LR;");
  lines.push("  node [shape=box];");
  lines.push("");
  for (const [name, node] of nodes) {
    for (const dep of node.deps) {
      const safeName = name.replace(/[@\/]/g, "_");
      const safeDep = dep.replace(/[@\/]/g, "_");
      lines.push(`  "${safeName}" -> "${safeDep}";`);
    }
  }
  lines.push("}");
  if (flags.json) {
    ui?.json?.({ dot: lines.join("\n") });
  } else {
    for (const line of lines) {
      ui?.write?.(line);
    }
    ui?.write?.("");
    ui?.write?.("# Save to file and visualize with:");
    ui?.write?.("# dot -Tpng dependencies.dot -o dependencies.png");
  }
}

export { visualize_default as default };
//# sourceMappingURL=visualize.js.map
//# sourceMappingURL=visualize.js.map