/**
 * MORPH-SPEC Rollback Phase Command
 *
 * Rolls back a feature to a previous phase, marking outputs as draft.
 *
 * Usage:
 *   morph-spec rollback <feature-name> <target-phase>
 *
 * Example:
 *   morph-spec rollback scheduled-reports design
 */

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

// Phase order
const PHASE_ORDER = ['proposal', 'setup', 'uiux', 'design', 'clarify', 'tasks', 'implement', 'sync'];

/**
 * Get phase index
 */
function getPhaseIndex(phase) {
  return PHASE_ORDER.indexOf(phase);
}

/**
 * Get outputs that should be marked as draft when rolling back
 */
function getOutputsToReset(fromPhase, toPhase) {
  const fromIndex = getPhaseIndex(fromPhase);
  const toIndex = getPhaseIndex(toPhase);

  // Map phases to their outputs
  const phaseOutputs = {
    'proposal': ['proposal'],
    'setup': [],
    'uiux': ['uiDesignSystem', 'uiMockups', 'uiComponents', 'uiFlows'],
    'design': ['spec', 'contracts', 'decisions'],
    'clarify': [],
    'tasks': ['tasks'],
    'implement': ['recap'],
    'sync': []
  };

  const outputsToReset = [];

  // Collect all outputs from phases after target
  for (let i = toIndex + 1; i <= fromIndex; i++) {
    const phase = PHASE_ORDER[i];
    if (phaseOutputs[phase]) {
      outputsToReset.push(...phaseOutputs[phase]);
    }
  }

  return outputsToReset;
}

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

  // Validate target phase
  if (!PHASE_ORDER.includes(targetPhase)) {
    console.log(chalk.red(`❌ Invalid phase: ${targetPhase}`));
    console.log(chalk.gray('\nValid phases:'));
    PHASE_ORDER.forEach(p => console.log(chalk.gray(`  - ${p}`)));
    process.exit(1);
  }

  // Get current feature state
  let featureState;
  try {
    featureState = getFeature(feature);
  } catch (error) {
    console.log(chalk.red(`❌ Feature not found: ${feature}`));
    console.log(chalk.gray('  Run: morph-spec state list'));
    process.exit(1);
  }

  if (!featureState) {
    console.log(chalk.red(`❌ Feature not found: ${feature}`));
    process.exit(1);
  }

  const currentPhase = featureState.phase || 'proposal';
  const currentIndex = getPhaseIndex(currentPhase);
  const targetIndex = getPhaseIndex(targetPhase);

  // Check if rollback makes sense
  if (targetIndex >= currentIndex) {
    console.log(chalk.yellow(`⚠️  Cannot rollback: target phase '${targetPhase}' is not before current phase '${currentPhase}'`));
    process.exit(1);
  }

  // Get outputs to reset
  const outputsToReset = getOutputsToReset(currentPhase, targetPhase);

  // Show what will happen
  console.log(chalk.gray('Feature:'), feature);
  console.log(chalk.gray('Current Phase:'), currentPhase);
  console.log(chalk.gray('Target Phase:'), targetPhase);
  console.log('');

  if (outputsToReset.length > 0) {
    console.log(chalk.yellow('Outputs that will be marked as draft:'));
    outputsToReset.forEach(o => {
      console.log(chalk.gray(`  - ${o}`));
    });
    console.log('');
  }

  // Confirm unless --force
  if (!options.force) {
    console.log(chalk.yellow('⚠️  This will:'));
    console.log(chalk.gray('  1. Set phase back to: ' + targetPhase));
    console.log(chalk.gray('  2. Reset task progress'));
    console.log(chalk.gray('  3. Mark outputs as not created (files remain on disk)'));
    console.log('');
    console.log(chalk.gray('Run with --force to confirm.'));
    process.exit(1);
  }

  // Perform rollback
  try {
    const state = loadState();

    // Update phase
    state.features[feature].phase = targetPhase;
    state.features[feature].status = 'in_progress';
    state.features[feature].updatedAt = new Date().toISOString();

    // Reset outputs
    for (const output of outputsToReset) {
      if (state.features[feature].outputs[output]) {
        state.features[feature].outputs[output].created = false;
      }
    }

    // Reset tasks if rolling back before tasks phase
    if (targetIndex < getPhaseIndex('tasks')) {
      state.features[feature].tasks = {
        total: 0,
        completed: 0,
        inProgress: 0,
        pending: 0
      };
    }

    // Add checkpoint for rollback
    state.features[feature].checkpoints = state.features[feature].checkpoints || [];
    state.features[feature].checkpoints.push({
      timestamp: new Date().toISOString(),
      phase: targetPhase,
      completedTasks: 0,
      note: `Rollback from ${currentPhase} to ${targetPhase}`
    });

    // Track skipped phases (if any were skipped)
    if (!state.features[feature].skippedPhases) {
      state.features[feature].skippedPhases = [];
    }

    saveState(state);

    console.log(chalk.green('✅ Rollback completed!'));
    console.log('');
    console.log(chalk.gray('Current state:'));
    console.log(chalk.gray(`  Phase: ${targetPhase}`));
    console.log(chalk.gray(`  Status: in_progress`));
    console.log('');
    console.log(chalk.cyan('Next steps:'));
    console.log(chalk.gray(`  1. Review and update outputs for phase: ${targetPhase}`));
    console.log(chalk.gray(`  2. Run: morph-spec session-summary ${feature}`));

  } catch (error) {
    console.log(chalk.red(`❌ Rollback failed: ${error.message}`));
    process.exit(1);
  }
}
