#!/usr/bin/env node
/**
 * cli:gitflow-status
 * Queries GitFlow status without modifying anything.
 * Reports current branch, branches with tracking, tags, worktrees, and actions.
 *
 * Exit codes: 0 = OK, 1 = warnings, 2 = blockers
 *
 * Usage:
 *   npx ts-node index.ts --spec '<json>' [--workdir <path>] [--json]
 */
import { parseArgs } from 'node:util';
import { readFileSync, existsSync } from 'node:fs';
import { validate } from './validate.js';
import { execute } from './execute.js';
import type { StatusResult } from './types.js';

const { values, positionals } = parseArgs({
  options: {
    spec: { type: 'string' },
    workdir: { type: 'string' },
    help: { type: 'boolean', short: 'h' },
    json: { type: 'boolean' },
  },
  allowPositionals: true,
});

if (values.help) {
  console.log(`
cli:gitflow-status — SmartStack Studio

Queries GitFlow status without modifying anything.
Reports current branch, branches with tracking, tags, worktrees, and suggested actions.

Usage:
  npx ts-node index.ts --spec '<json>' [--workdir <path>] [--json]

Options:
  --spec        JSON string or path to a JSON file with status spec
  --workdir     Working directory for git operations (defaults to cwd)
  --json        Output result as JSON
  --help, -h    Show this help
  `);
  process.exit(0);
}

// ── Validate args ─────────────────────────────────────────
const specArg = values.spec;
const workdir = values.workdir || process.cwd();

if (!specArg) {
  const result = { success: false, blockers: ['Missing required arg: --spec'], warnings: [] };
  if (values.json) console.log(JSON.stringify(result, null, 2));
  else console.error('[BLOCKER] Missing required arg: --spec');
  process.exit(2);
}

// ── Parse spec (JSON string or file path) ──────────────────
let rawSpec: unknown;
try {
  if (existsSync(specArg)) {
    rawSpec = JSON.parse(readFileSync(specArg, 'utf-8'));
  } else {
    rawSpec = JSON.parse(specArg);
  }
} catch (err) {
  const result = { success: false, blockers: [`Invalid JSON spec: ${(err as Error).message}`], warnings: [] };
  if (values.json) console.log(JSON.stringify(result, null, 2));
  else console.error(`[BLOCKER] Invalid JSON spec: ${(err as Error).message}`);
  process.exit(2);
}

// ── Validate ──────────────────────────────────────────────
const validation = validate(rawSpec);

if (!validation.valid || !validation.data) {
  const result = { success: false, blockers: validation.blockers, warnings: validation.warnings };
  if (values.json) {
    console.log(JSON.stringify(result, null, 2));
  } else {
    for (const b of validation.blockers) console.error(`[BLOCKER] ${b}`);
    for (const w of validation.warnings) console.warn(`[WARNING] ${w}`);
  }
  process.exit(2);
}

// Log warnings
if (!values.json) {
  for (const w of validation.warnings) console.warn(`[WARNING] ${w}`);
}

// ── Execute ───────────────────────────────────────────────
let result: StatusResult;
try {
  result = await execute(validation.data, workdir);
} catch (err) {
  const errResult = {
    success: false,
    currentBranch: 'unknown',
    branches: [],
    tags: [],
    workingTree: {
      isDirty: false,
      isRebasing: false,
      isMerging: false,
      isCherryPicking: false,
      unstagedCount: 0,
      stagedCount: 0,
    },
    blockers: [(err as Error).message],
    warnings: validation.warnings,
  };
  if (values.json) console.log(JSON.stringify(errResult, null, 2));
  else console.error(`[BLOCKER] ${(err as Error).message}`);
  process.exit(2);
}

// ── Output ────────────────────────────────────────────────
if (values.json) {
  console.log(JSON.stringify(result, null, 2));
} else {
  if (result.success) {
    console.log(`Current branch: ${result.currentBranch}`);
    console.log(`Total branches: ${result.branches.length}`);
    console.log(`Total tags: ${result.tags.length}`);

    if (result.workingTree.isDirty) {
      console.log(`⚠ Working tree is dirty (${result.workingTree.stagedCount} staged, ${result.workingTree.unstagedCount} unstaged)`);
    }

    if (result.workingTree.isRebasing) {
      console.log('⚠ Rebase in progress');
    }

    if (result.workingTree.isMerging) {
      console.log('⚠ Merge in progress');
    }

    if (result.workingTree.isCherryPicking) {
      console.log('⚠ Cherry-pick in progress');
    }

    if (result.actions && result.actions.length > 0) {
      console.log(`\nSuggested actions (${result.actions.length}):`);
      for (const action of result.actions.slice(0, 5)) {
        console.log(`  [${action.priority.toUpperCase()}] ${action.action}`);
      }
    }
  } else {
    console.error(`Error: ${result.error}`);
  }
}

process.exit(result.success ? 0 : 2);
