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

import fs from 'fs';
import path from 'path';
import chalk from 'chalk';
import { loadState, getFeature } from '../../core/state/state-manager.js';

// Phase definitions with requirements
const PHASES = {
  'proposal': {
    order: 0,
    name: 'FASE 0: PROPOSAL',
    requiredOutputs: [],
    description: 'Initial proposal and agent detection'
  },
  'setup': {
    order: 1,
    name: 'FASE 1: SETUP',
    requiredOutputs: ['proposal.md'],
    description: 'Load context and standards'
  },
  'uiux': {
    order: 2,
    name: 'FASE 1.5: UI/UX DESIGN',
    requiredOutputs: ['proposal.md'],
    optionalOutputs: ['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'],
    description: 'Technical specification and contracts'
  },
  'clarify': {
    order: 4,
    name: 'FASE 3: CLARIFY',
    requiredOutputs: ['proposal.md', 'spec.md'],
    description: 'Clarify ambiguities and edge cases'
  },
  'tasks': {
    order: 5,
    name: 'FASE 4: TASKS',
    requiredOutputs: ['proposal.md', 'spec.md'],
    description: 'Break down into executable tasks'
  },
  'implement': {
    order: 6,
    name: 'FASE 5: IMPLEMENT',
    requiredOutputs: ['proposal.md', 'spec.md'],
    description: 'Execute tasks and implement code'
  },
  'sync': {
    order: 7,
    name: 'FASE 6: SYNC',
    requiredOutputs: ['proposal.md', 'spec.md', 'decisions.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}`,
      suggestion: `Run 'morph-spec state set ${featureName} phase proposal' to start`,
      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);
    }
  }

  // Check state.json for current phase
  let stateWarning = null;
  try {
    const feature = getFeature(featureName);
    if (feature) {
      const currentPhaseOrder = PHASES[feature.phase]?.order ?? -1;
      const targetPhaseOrder = phaseDefinition.order;

      if (targetPhaseOrder > currentPhaseOrder + 1) {
        stateWarning = `Skipping phases: current is '${feature.phase}' (order ${currentPhaseOrder}), target is '${targetPhase}' (order ${targetPhaseOrder})`;
      }
    }
  } catch {
    // State file may not exist, that's OK
  }

  // Special validation: if target is 'implement', check tasks exist in state
  if (targetPhase === 'implement') {
    try {
      const feature = getFeature(featureName);
      if (feature && (!feature.tasks || feature.tasks.total === 0)) {
        missingOutputs.push('tasks in state.json (run morph-spec task to add tasks)');
      }
    } catch {
      // State file may not exist
    }
  }

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

/**
 * Main command handler
 */
export async function validatePhaseCommand(feature, phase, options = {}) {
  console.log(chalk.cyan('\n╔════════════════════════════════════════════════╗'));
  console.log(chalk.cyan('║     MORPH-SPEC PHASE VALIDATOR                 ║'));
  console.log(chalk.cyan('╚════════════════════════════════════════════════╝\n'));

  const result = validatePhase(feature, phase);

  console.log(chalk.gray('Feature:'), feature);
  console.log(chalk.gray('Target Phase:'), result.phase ? result.phase.name : phase);

  if (result.phase) {
    console.log(chalk.gray('Description:'), result.phase.description);
  }

  if (result.stateWarning) {
    console.log(chalk.yellow(`\n⚠️  Warning: ${result.stateWarning}`));
  }

  if (result.valid) {
    console.log(chalk.green('\n✓ VALIDATION PASSED'));
    console.log(chalk.green('  All required outputs are present.'));
    console.log(chalk.green(`  Safe to proceed to ${result.phase.name}\n`));

    if (options.verbose) {
      console.log(chalk.gray('Required outputs found:'));
      result.phase.requiredOutputs.forEach(output => {
        console.log(chalk.gray(`  ✓ ${output}`));
      });
      console.log('');
    }
  } else {
    console.log(chalk.red('\n✗ VALIDATION FAILED'));

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

      if (result.suggestion) {
        console.log(chalk.yellow(`  Suggestion: ${result.suggestion}\n`));
      }

      if (result.validPhases) {
        console.log(chalk.yellow('Valid phases:'));
        result.validPhases.forEach(p => {
          const def = PHASES[p];
          console.log(chalk.gray(`  - ${p}: ${def.name}${def.optional ? ' (optional)' : ''}`));
        });
      }
    } else {
      console.log(chalk.red('  Missing required outputs:'));
      result.missingOutputs.forEach(output => {
        console.log(chalk.gray(`  - ${output}`));
      });

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

export { PHASES, validatePhase };
