/**
 * Recap Generator
 *
 * Auto-generates recap.md from real project data: state.json, contract compliance,
 * validation results, and decisions. Replaces manual template filling.
 *
 * MORPH-SPEC 3.0 - Phase B: Spec-Driven Pipeline
 */

import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
import { join, dirname } from 'path';
import chalk from 'chalk';
import { loadState } from '../../core/state/state-manager.js';
import { runValidation } from '../validators/validation-runner.js';

/**
 * Generate recap.md for a feature
 *
 * @param {string} projectPath - Project root path
 * @param {string} featureName - Feature name
 * @param {Object} options - Options
 * @returns {string} Generated recap content
 */
export async function generateRecap(projectPath, featureName, options = {}) {
  const state = loadState(false);
  if (!state || !state.features[featureName]) {
    throw new Error(`Feature '${featureName}' not found in state.json`);
  }

  const feature = state.features[featureName];
  const outputsPath = join(projectPath, '.morph/project/outputs', featureName);

  // Gather data
  const tasksSummary = getTasksSummary(feature);
  const agentsSummary = getAgentsSummary(feature);
  const checkpointsSummary = getCheckpointsSummary(feature);
  // Decision constraints support (stub - decision-constraint-loader removed as orphaned code)
  const decisions = { decisions: [] };
  const validationResult = await runValidation(projectPath, featureName, { verbose: false });

  // Contract coverage
  let contractCoverage = null;
  if (validationResult.issues) {
    const contractIssues = validationResult.issues.filter(i => i.message?.includes('Interface') || i.message?.includes('contracts'));
    if (contractIssues.length > 0 || existsSync(join(outputsPath, 'contracts.cs'))) {
      // Extract coverage from validation result
      contractCoverage = extractContractCoverage(validationResult);
    }
  }

  // Generate markdown
  const recap = buildRecapMarkdown({
    featureName,
    feature,
    tasksSummary,
    agentsSummary,
    checkpointsSummary,
    decisions: decisions.decisions,
    validationResult,
    contractCoverage
  });

  // Write to file
  const recapPath = join(outputsPath, 'recap.md');
  if (!existsSync(dirname(recapPath))) {
    mkdirSync(dirname(recapPath), { recursive: true });
  }
  writeFileSync(recapPath, recap, 'utf-8');

  if (!options.quiet) {
    console.log(chalk.green(`\n✅ Recap generated: ${recapPath}`));
  }

  return recap;
}

function getTasksSummary(feature) {
  // v2: feature.tasks is an array of task objects
  if (Array.isArray(feature.tasks)) {
    const tasks = feature.tasks;
    const completed = tasks.filter(t => t.status === 'completed');
    const pending = tasks.filter(t => t.status === 'pending');
    const inProgress = tasks.filter(t => t.status === 'in_progress');
    return {
      total: tasks.length,
      completed: completed.length,
      pending: pending.length,
      inProgress: inProgress.length,
      percentage: tasks.length > 0 ? Math.round((completed.length / tasks.length) * 100) : 0,
      items: tasks
    };
  }

  // v3: feature.tasks is a counter object {total, completed, inProgress, pending}
  // Use feature.taskList for individual items if available
  const counters = feature.tasks || {};
  const items = feature.taskList || [];
  const total = counters.total || items.length || 0;
  const completedCount = counters.completed ?? items.filter(t => t.status === 'completed').length;
  const pendingCount = counters.pending ?? items.filter(t => t.status === 'pending').length;
  const inProgressCount = counters.inProgress ?? items.filter(t => t.status === 'in_progress').length;

  return {
    total,
    completed: completedCount,
    pending: pendingCount,
    inProgress: inProgressCount,
    percentage: total > 0 ? Math.round((completedCount / total) * 100) : 0,
    items
  };
}

function getAgentsSummary(feature) {
  return feature.activeAgents || [];
}

function getCheckpointsSummary(feature) {
  return (feature.checkpoints || []).map(cp => ({
    timestamp: cp.timestamp,
    note: cp.note,
    tasks: cp.tasksCompleted || []
  }));
}

function extractContractCoverage(validationResult) {
  // Look for contract compliance data in validation issues
  const interfaceErrors = validationResult.issues.filter(i =>
    i.message?.includes('Interface') && i.level === 'error'
  );
  const methodErrors = validationResult.issues.filter(i =>
    i.message?.includes('Method') && i.message?.includes('missing') && i.level === 'error'
  );

  return {
    missingInterfaces: interfaceErrors.length,
    missingMethods: methodErrors.length,
    hasIssues: interfaceErrors.length > 0 || methodErrors.length > 0
  };
}

function buildRecapMarkdown(data) {
  const { featureName, feature, tasksSummary, agentsSummary, checkpointsSummary, decisions, validationResult, contractCoverage } = data;
  const now = new Date().toISOString().split('T')[0];

  let md = `# Recap: ${featureName}\n\n`;
  md += `> Generated: ${now} | Phase: ${feature.phase} | Status: ${feature.status}\n\n`;
  md += `---\n\n`;

  // Progress
  md += `## Progress\n\n`;
  md += `| Metric | Value |\n|--------|-------|\n`;
  md += `| Tasks completed | ${tasksSummary.completed}/${tasksSummary.total} (${tasksSummary.percentage}%) |\n`;
  md += `| Tasks pending | ${tasksSummary.pending} |\n`;
  md += `| Tasks in progress | ${tasksSummary.inProgress} |\n`;
  md += `| Active agents | ${agentsSummary.length} |\n`;
  md += `| Checkpoints | ${checkpointsSummary.length} |\n\n`;

  // Validation Results
  md += `## Validation Results\n\n`;
  if (validationResult.passed) {
    md += `**Status: PASSED** (${validationResult.warnings} warnings)\n\n`;
  } else {
    md += `**Status: FAILED** (${validationResult.errors} errors, ${validationResult.warnings} warnings)\n\n`;
    if (validationResult.issues.length > 0) {
      md += `| Level | Issue |\n|-------|-------|\n`;
      for (const issue of validationResult.issues.slice(0, 15)) {
        md += `| ${issue.level} | ${issue.message} |\n`;
      }
      md += `\n`;
    }
  }

  // Contract Coverage
  if (contractCoverage) {
    md += `## Contract Compliance\n\n`;
    if (contractCoverage.hasIssues) {
      md += `- Missing interfaces: ${contractCoverage.missingInterfaces}\n`;
      md += `- Missing methods: ${contractCoverage.missingMethods}\n\n`;
    } else {
      md += `All contracts implemented.\n\n`;
    }
  }

  // Decisions
  if (decisions.length > 0) {
    md += `## Decisions Applied\n\n`;
    for (const d of decisions) {
      if (d.title) {
        md += `- **${d.title}**: ${d.decision.slice(0, 100)}${d.decision.length > 100 ? '...' : ''}\n`;
      }
    }
    md += `\n`;
  }

  // Agents
  if (agentsSummary.length > 0) {
    md += `## Active Agents\n\n`;
    md += agentsSummary.map(a => `- ${a}`).join('\n');
    md += `\n\n`;
  }

  // Checkpoints
  if (checkpointsSummary.length > 0) {
    md += `## Checkpoints\n\n`;
    for (const cp of checkpointsSummary) {
      md += `- ${cp.timestamp}: ${cp.note}\n`;
    }
    md += `\n`;
  }

  // Tasks Detail
  if (tasksSummary.items.length > 0) {
    md += `## Tasks\n\n`;
    md += `| ID | Title | Status |\n|----|-------|--------|\n`;
    for (const task of tasksSummary.items) {
      const statusIcon = task.status === 'completed' ? '✅' : task.status === 'in_progress' ? '🔄' : '⏳';
      md += `| ${task.id} | ${task.title || '-'} | ${statusIcon} ${task.status} |\n`;
    }
    md += `\n`;
  }

  md += `---\n\n*Generated by MORPH-SPEC Recap Generator*\n`;

  return md;
}
