/**
 * MORPH-SPEC Sprint Status Manager
 * Updates sprint-status.yaml and shows next story
 */

import fs from 'fs';
import path from 'path';
import yaml from 'yaml';
import ora from 'ora';
import chalk from 'chalk';
import { logger } from '../utils/logger.js';

// ============================================================================
// Helper Functions
// ============================================================================

function loadSprintStatus(featureName) {
  const statusPath = path.join(process.cwd(), `.morph/project/outputs/${featureName}/sprint-status.yaml`);

  if (!fs.existsSync(statusPath)) {
    throw new Error(`Sprint status not found: ${statusPath}\n\n💡 Create a sprint status file first:\n   morph-spec story create ${featureName} STORY-001`);
  }

  const content = fs.readFileSync(statusPath, 'utf-8');
  return { path: statusPath, data: yaml.parse(content) };
}

function saveSprintStatus(statusPath, data) {
  const content = yaml.stringify(data);
  fs.writeFileSync(statusPath, content);
}

function updateMetrics(sprint) {
  const stories = sprint.stories || [];
  const metrics = {
    total_stories: stories.length,
    ready: stories.filter(s => s.status === 'ready').length,
    in_progress: stories.filter(s => s.status === 'in_progress').length,
    ready_for_qa: stories.filter(s => s.status === 'ready_for_qa').length,
    done: stories.filter(s => s.status === 'done').length,
  };

  metrics.completion_percent = stories.length > 0
    ? Math.round((metrics.done / stories.length) * 100)
    : 0;

  sprint.metrics = metrics;
  sprint.updated = new Date().toISOString().split('T')[0];
}

function findStory(sprint, storyId) {
  return sprint.stories.find(s => s.id === storyId);
}

function getNextStory(sprint) {
  // Find first story that is "ready" (not in_progress or done)
  return sprint.stories.find(s => s.status === 'ready' || s.status === 'pending');
}

function displayStatus(sprint) {
  logger.header(`Sprint Status: ${sprint.feature}`);
  logger.blank();
  logger.info(`Epic: ${chalk.cyan(sprint.epic)}`);
  logger.info(`Progress: ${chalk.green(`${sprint.metrics.completion_percent}%`)} (${sprint.metrics.done}/${sprint.metrics.total_stories} stories done)`);
  logger.blank();

  logger.header('Stories:');
  sprint.stories.forEach(story => {
    const statusEmoji = {
      pending: '⏸️ ',
      ready: '✅',
      in_progress: '🔄',
      ready_for_qa: '👀',
      done: '✔️ ',
    }[story.status] || '❓';

    const statusColor = {
      pending: chalk.dim,
      ready: chalk.cyan,
      in_progress: chalk.yellow,
      ready_for_qa: chalk.magenta,
      done: chalk.green,
    }[story.status] || chalk.white;

    logger.dim(`  ${statusEmoji} ${story.id}: ${story.title} ${statusColor(`(${story.status})`)}`);
  });
  logger.blank();

  if (sprint.current && sprint.current.story_id) {
    logger.info(`🎯 Current Focus: ${chalk.cyan(sprint.current.story_id)} (${sprint.current.agent} agent)`);
  }

  if (sprint.next && sprint.next.story_id) {
    logger.info(`📋 Next Story: ${chalk.cyan(sprint.next.story_id)}`);
    logger.dim(`   ${sprint.next.recommendation || 'Ready for development'}`);
  }

  logger.blank();
}

// ============================================================================
// Command Function
// ============================================================================

export async function sprintStatusCommand(feature, action, storyId, options) {
  // Default action is 'show'
  const cmd = action || 'show';

  if (cmd === 'help' || options.help) {
    logger.header('MORPH-SPEC Sprint Status Manager');
    logger.blank();
    logger.info('Usage:');
    logger.dim('  morph-spec story status <feature> [command] [story-id]');
    logger.blank();
    logger.info('Commands:');
    logger.dim('  show                      Display current sprint status (default)');
    logger.dim('  start <story-id>          Mark story as in_progress');
    logger.dim('  qa <story-id>             Mark story as ready_for_qa');
    logger.dim('  done <story-id>           Mark story as done');
    logger.dim('  next                      Show next story to work on');
    logger.blank();
    logger.info('Examples:');
    logger.dim('  morph-spec story status scheduled-reports show');
    logger.dim('  morph-spec story status scheduled-reports start SR-001');
    logger.dim('  morph-spec story status scheduled-reports qa SR-001');
    logger.dim('  morph-spec story status scheduled-reports done SR-001');
    logger.dim('  morph-spec story status scheduled-reports next');
    logger.blank();
    return;
  }

  try {
    // Load sprint status
    const { path: statusPath, data: sprint } = loadSprintStatus(feature);

    // Execute command
    switch (cmd) {
      case 'show':
        displayStatus(sprint);
        break;

      case 'start':
        if (!storyId) {
          throw new Error('Story ID required for "start" command');
        }
        const storyToStart = findStory(sprint, storyId);
        if (!storyToStart) {
          throw new Error(`Story not found: ${storyId}`);
        }

        const spinner = ora('Updating story status...').start();
        storyToStart.status = 'in_progress';
        storyToStart.started = new Date().toISOString().split('T')[0];
        storyToStart.assigned = 'dev';
        sprint.current = { story_id: storyId, agent: 'dev', phase: 'implementation' };
        updateMetrics(sprint);
        saveSprintStatus(statusPath, sprint);
        spinner.succeed(`Story ${chalk.cyan(storyId)} marked as IN PROGRESS`);
        logger.blank();
        logger.info('💡 Recommendation: Run this story in a FRESH Claude session');
        logger.dim('   /dev → Implement story → Add Dev Notes');
        logger.blank();
        break;

      case 'qa':
        if (!storyId) {
          throw new Error('Story ID required for "qa" command');
        }
        const storyForQA = findStory(sprint, storyId);
        if (!storyForQA) {
          throw new Error(`Story not found: ${storyId}`);
        }

        const qaSpinner = ora('Updating story status...').start();
        storyForQA.status = 'ready_for_qa';
        storyForQA.assigned = 'qa';
        sprint.current = { story_id: storyId, agent: 'qa', phase: 'review' };
        updateMetrics(sprint);
        saveSprintStatus(statusPath, sprint);
        qaSpinner.succeed(`Story ${chalk.cyan(storyId)} marked as READY FOR QA`);
        logger.blank();
        logger.info('💡 Recommendation: QA in a FRESH Claude session');
        logger.dim('   /qa → Review code → Add QA Notes');
        logger.blank();
        break;

      case 'done':
        if (!storyId) {
          throw new Error('Story ID required for "done" command');
        }
        const storyDone = findStory(sprint, storyId);
        if (!storyDone) {
          throw new Error(`Story not found: ${storyId}`);
        }

        const doneSpinner = ora('Updating story status...').start();
        storyDone.status = 'done';
        storyDone.completed = new Date().toISOString().split('T')[0];
        updateMetrics(sprint);

        // Update next story
        const nextStory = getNextStory(sprint);
        if (nextStory) {
          sprint.next = {
            story_id: nextStory.id,
            recommendation: `Story ${nextStory.id} is ready for development`,
          };
        } else {
          sprint.next = null;
        }

        saveSprintStatus(statusPath, sprint);
        doneSpinner.succeed(`Story ${chalk.cyan(storyId)} marked as DONE`);
        logger.blank();

        if (nextStory) {
          logger.info(`📋 Next Story: ${chalk.cyan(nextStory.id)}`);
          logger.dim(`   ${nextStory.title}`);
          logger.blank();
        } else {
          logger.success('🎉 All stories completed! Feature ready for final review.');
          logger.blank();
        }
        break;

      case 'next':
        const next = getNextStory(sprint);
        if (next) {
          logger.header('Next Story:');
          logger.blank();
          logger.info(`📋 Story ID: ${chalk.cyan(next.id)}`);
          logger.info(`   Title: ${next.title}`);
          logger.info(`   File: ${chalk.dim(next.file)}`);
          logger.info(`   Status: ${next.status}`);
          logger.blank();
        } else {
          logger.success('🎉 No pending stories! Sprint complete.');
          logger.blank();
        }
        break;

      default:
        throw new Error(`Unknown command: ${cmd}\n   Use --help to see available commands`);
    }

  } catch (error) {
    logger.error(error.message);
    process.exit(1);
  }
}
