#!/usr/bin/env node
/* eslint-disable @typescript-eslint/no-require-imports */
/**
 * generate-dependency-graph.js
 *
 * Generates two files in docs/ on every commit:
 *
 *   docs/dependency-graph.json   — full import graph for src/lib/game/
 *   docs/circular-deps.txt       — list of circular dependency chains (empty = clean)
 *
 * Run manually:  node .husky/scripts/generate-dependency-graph.js
 * Requires:      bun add -d madge
 */

const path = require('path');
const fs = require('fs');
const { execSync } = require('child_process');

const ROOT = path.resolve(__dirname, '../../');
const DOCS_DIR = path.join(ROOT, 'docs');
const GRAPH_OUT = path.join(DOCS_DIR, 'dependency-graph.json');
const CIRCULAR_OUT = path.join(DOCS_DIR, 'circular-deps.txt');

// Check madge is available
function madgeAvailable() {
  try {
    execSync('bunx madge --version', { stdio: 'ignore', cwd: ROOT });
    return true;
  } catch {
    return false;
  }
}

function run(cmd) {
  return execSync(cmd, { cwd: ROOT, encoding: 'utf8' });
}

if (!madgeAvailable()) {
  console.error('madge not found. Install with: bun add -d madge');
  process.exit(1);
}

if (!fs.existsSync(DOCS_DIR)) {
  fs.mkdirSync(DOCS_DIR, { recursive: true });
}

// ── 1. Full dependency graph for the game library ─────────────────────────
try {
  const graphJson = run(
    'bunx madge --json --extensions ts,tsx --exclude "\\.test\\.|__tests__" src/lib/game'
  );
  // Parse and re-serialize with readable formatting
  const graph = JSON.parse(graphJson);

  // Annotate with metadata for AI agents
  const output = {
    _meta: {
      generated: new Date().toISOString(),
      description:
        'Import dependency graph for src/lib/game. Keys are files, values are arrays of files they import.',
      usage:
        'To find what a file affects, search for its path in the VALUES. To find what a file depends on, look at its KEY entry.',
    },
    graph,
  };

  fs.writeFileSync(GRAPH_OUT, JSON.stringify(output, null, 2));
  const nodeCount = Object.keys(graph).length;
  console.log(`✅ Dependency graph: ${nodeCount} modules → docs/dependency-graph.json`);
} catch (err) {
  console.error('Failed to generate dependency graph:', err.message);
  process.exit(1);
}

// ── 2. Circular dependency report ─────────────────────────────────────────
try {
  let circularOutput = '';
  try {
    // madge exits with code 1 when circulars are found; capture stdout anyway
    circularOutput = run(
      'bunx madge --circular --extensions ts,tsx --exclude "\\.test\\.|__tests__" src/lib/game'
    );
  } catch (e) {
    // exitCode 1 = circulars found; stdout contains the list
    circularOutput = e.stdout || '';
  }

  const lines = circularOutput.trim().split('\n').filter(Boolean);
  // madge circular output format:
  //   "Found N circular dependencies!"  (summary)
  //   "1) fileA > fileB > fileC"       (chain lines start with number + ')')
  //   "Processed N files ..."           (info line to ignore)
  //   "✔ No circular dependency found!"  (clean result)
  const circularLines = lines.filter(
    (l) => /^\d+\)/.test(l.trim())
  );

  let content;
  if (circularLines.length === 0) {
    content = `# Circular Dependencies\nGenerated: ${new Date().toISOString()}\n\nNo circular dependencies found. ✅\n`;
    console.log('✅ No circular dependencies found');
  } else {
    content = [
      `# Circular Dependencies`,
      `Generated: ${new Date().toISOString()}`,
      `Found: ${circularLines.length} circular chain(s) — these MUST be fixed before modifying involved files.`,
      '',
      ...circularLines.map((l, i) => `${i + 1}. ${l.trim()}`),
      '',
      '## How to fix',
      '1. Identify which import in the chain can be extracted to a shared types/utils file.',
      '2. Move the shared type or function there.',
      '3. Both files import from the new shared module instead of each other.',
      '4. Run: bunx madge --circular src/lib/game  (should return clean)',
    ].join('\n');
    console.warn(`⚠️  Found ${circularLines.length} circular dependency chain(s) — see docs/circular-deps.txt`);
  }

  fs.writeFileSync(CIRCULAR_OUT, content);
} catch (err) {
  console.error('Failed to check circular dependencies:', err.message);
  // Non-fatal: write a note to the file and continue
  fs.writeFileSync(CIRCULAR_OUT, `# Circular Dependencies\nError running check: ${err.message}\n`);
}