#!/usr/bin/env node

/**
 * MORPH-SPEC Phase Validator
 *
 * Validates that required previous phases have been completed before advancing.
 * Prevents skipping phases accidentally.
 *
 * Usage:
 *   node bin/validate-phase.js <feature-name> <target-phase>
 *
 * Example:
 *   node bin/validate-phase.js scheduled-reports implement
 */

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// ANSI colors
const colors = {
  green: '\x1b[32m',
  red: '\x1b[31m',
  yellow: '\x1b[33m',
  cyan: '\x1b[36m',
  gray: '\x1b[90m',
  reset: '\x1b[0m'
};

// Phase definitions with requirements
const PHASES = {
  'proposal': {
    order: 0,
    name: 'FASE 0: PROPOSAL',
    requiredOutputs: ['proposal.md'],
    description: 'Initial proposal and agent detection'
  },
  'setup': {
    order: 1,
    name: 'FASE 1: SETUP',
    requiredOutputs: ['proposal.md'],
    description: 'Load context and standards'
  },
  'uiux-design': {
    order: 2,
    name: 'FASE 1.5: UI/UX DESIGN',
    requiredOutputs: ['proposal.md', 'ui-design-system.md', 'ui-mockups.md', 'ui-components.md', 'ui-flows.md'],
    description: 'UI/UX design (conditional - only if frontend)',
    optional: true
  },
  'design': {
    order: 3,
    name: 'FASE 2: DESIGN',
    requiredOutputs: ['proposal.md', 'spec.md', 'contracts.cs', 'decisions.md'],
    description: 'Technical specification and contracts'
  },
  'clarify': {
    order: 4,
    name: 'FASE 3: CLARIFY',
    requiredOutputs: ['proposal.md', 'spec.md', 'contracts.cs'],
    description: 'Clarify ambiguities and edge cases'
  },
  'tasks': {
    order: 5,
    name: 'FASE 4: TASKS',
    requiredOutputs: ['proposal.md', 'spec.md', 'contracts.cs', 'tasks.json'],
    description: 'Break down into executable tasks'
  },
  'implement': {
    order: 6,
    name: 'FASE 5: IMPLEMENT',
    requiredOutputs: ['proposal.md', 'spec.md', 'contracts.cs', 'tasks.json'],
    description: 'Execute tasks and implement code'
  },
  'sync': {
    order: 7,
    name: 'FASE 6: SYNC',
    requiredOutputs: ['proposal.md', 'spec.md', 'decisions.md', 'recap.md'],
    description: 'Sync decisions to project standards',
    optional: true
  }
};

/**
 * Check if output file exists
 */
function checkOutput(featurePath, outputFile) {
  const filePath = path.join(featurePath, outputFile);
  return fs.existsSync(filePath);
}

/**
 * Validate phase requirements
 */
function validatePhase(featureName, targetPhase) {
  const featurePath = path.join(process.cwd(), '.morph/project/outputs', featureName);

  // Check if feature directory exists
  if (!fs.existsSync(featurePath)) {
    return {
      valid: false,
      error: `Feature directory not found: ${featurePath}`,
      missingOutputs: [],
      phase: null
    };
  }

  // Get target phase definition
  const phaseDefinition = PHASES[targetPhase];
  if (!phaseDefinition) {
    return {
      valid: false,
      error: `Unknown phase: ${targetPhase}`,
      validPhases: Object.keys(PHASES),
      missingOutputs: [],
      phase: null
    };
  }

  // Check required outputs
  const missingOutputs = [];
  for (const output of phaseDefinition.requiredOutputs) {
    if (!checkOutput(featurePath, output)) {
      missingOutputs.push(output);
    }
  }

  // Special validation: if target is 'implement', check tasks.json structure
  if (targetPhase === 'implement' && checkOutput(featurePath, 'tasks.json')) {
    try {
      const tasksPath = path.join(featurePath, 'tasks.json');
      const tasks = JSON.parse(fs.readFileSync(tasksPath, 'utf-8'));

      if (!tasks.tasks || !Array.isArray(tasks.tasks) || tasks.tasks.length === 0) {
        missingOutputs.push('tasks.json (must contain tasks array)');
      }
    } catch (error) {
      missingOutputs.push('tasks.json (invalid JSON)');
    }
  }

  return {
    valid: missingOutputs.length === 0,
    error: null,
    missingOutputs,
    phase: phaseDefinition,
    featurePath
  };
}

/**
 * Print validation result
 */
function printResult(result, featureName, targetPhase) {
  console.log(`\n${colors.cyan}╔════════════════════════════════════════════════╗${colors.reset}`);
  console.log(`${colors.cyan}║     MORPH-SPEC PHASE VALIDATOR                 ║${colors.reset}`);
  console.log(`${colors.cyan}╚════════════════════════════════════════════════╝${colors.reset}\n`);

  console.log(`${colors.gray}Feature:${colors.reset} ${featureName}`);
  console.log(`${colors.gray}Target Phase:${colors.reset} ${result.phase ? result.phase.name : targetPhase}`);

  if (result.phase) {
    console.log(`${colors.gray}Description:${colors.reset} ${result.phase.description}`);
  }

  if (result.valid) {
    console.log(`\n${colors.green}✓ VALIDATION PASSED${colors.reset}`);
    console.log(`${colors.green}  All required outputs are present.${colors.reset}`);
    console.log(`${colors.green}  Safe to proceed to ${result.phase.name}${colors.reset}\n`);
  } else {
    console.log(`\n${colors.red}✗ VALIDATION FAILED${colors.reset}`);

    if (result.error) {
      console.log(`${colors.red}  Error: ${result.error}${colors.reset}\n`);

      if (result.validPhases) {
        console.log(`${colors.yellow}Valid phases:${colors.reset}`);
        result.validPhases.forEach(phase => {
          console.log(`  - ${phase}`);
        });
      }
    } else {
      console.log(`${colors.red}  Missing required outputs:${colors.reset}`);
      result.missingOutputs.forEach(output => {
        console.log(`  ${colors.gray}-${colors.reset} ${output}`);
      });

      console.log(`\n${colors.yellow}Action required:${colors.reset}`);
      console.log(`  Complete the missing outputs before advancing to ${result.phase.name}`);
    }
    console.log('');
  }
}

/**
 * Print help
 */
function printHelp() {
  console.log(`
${colors.cyan}MORPH-SPEC Phase Validator${colors.reset}

Validates that required previous phases have been completed before advancing.

${colors.green}Usage:${colors.reset}
  node bin/validate-phase.js <feature-name> <target-phase>

${colors.green}Arguments:${colors.reset}
  feature-name    Name of the feature (kebab-case)
  target-phase    Phase you want to advance to

${colors.green}Valid Phases:${colors.reset}
  proposal        FASE 0: Initial proposal
  setup           FASE 1: Load context and standards
  uiux-design     FASE 1.5: UI/UX design (optional)
  design          FASE 2: Technical specification
  clarify         FASE 3: Clarify ambiguities
  tasks           FASE 4: Break down into tasks
  implement       FASE 5: Execute implementation
  sync            FASE 6: Sync to project standards (optional)

${colors.green}Examples:${colors.reset}
  # Check if ready to implement
  node bin/validate-phase.js scheduled-reports implement

  # Check if ready for design phase
  node bin/validate-phase.js user-auth design

  # Use in slash command
  node bin/validate-phase.js my-feature implement || exit 1

${colors.green}Exit Codes:${colors.reset}
  0 - Validation passed (safe to proceed)
  1 - Validation failed (missing requirements)

${colors.green}Integration:${colors.reset}
  This validator is designed to be called from slash commands like
  /morph-apply to ensure phase gates are respected.
  `);
}

/**
 * Main function
 */
function main() {
  const args = process.argv.slice(2);

  if (args.includes('--help') || args.includes('-h') || args.length < 2) {
    printHelp();
    process.exit(args.length < 2 ? 1 : 0);
  }

  const [featureName, targetPhase] = args;

  const result = validatePhase(featureName, targetPhase);
  printResult(result, featureName, targetPhase);

  process.exit(result.valid ? 0 : 1);
}

main();
