import { join } from 'path';
import { readdirSync, existsSync } from 'fs';
import ora from 'ora';
import chalk from 'chalk';
import { logger } from '../utils/logger.js';
import { readFile, writeFile, ensureDir } from '../utils/file-copier.js';
import { analyzeConversation } from '../../detectors/conversation-analyzer.js';

export async function syncCommand(options) {
  const targetPath = options.path || process.cwd();

  logger.header('MORPH-SPEC Standards Sync');
  logger.dim(`Project: ${targetPath}`);
  logger.blank();

  const spinner = ora('Analyzing feature decisions...').start();

  try {
    // 1. Find all decisions.md files
    const outputsPath = join(targetPath, '.morph', 'project', 'outputs');

    if (!existsSync(outputsPath)) {
      spinner.warn('No features found');
      logger.dim('Create features first using MORPH workflow.');
      return;
    }

    const features = readdirSync(outputsPath, { withFileTypes: true })
      .filter(dirent => dirent.isDirectory())
      .map(dirent => dirent.name);

    if (features.length === 0) {
      spinner.warn('No features found');
      return;
    }

    spinner.text = `Found ${features.length} features, analyzing decisions...`;

    // 2. Analyze all decisions
    const conversation = await analyzeConversation(targetPath);

    if (conversation.decisions.length === 0) {
      spinner.warn('No decisions found to sync');
      logger.dim('Features may not have decisions.md files yet.');
      return;
    }

    spinner.succeed(`Found ${conversation.decisions.length} decisions`);
    logger.blank();

    // 3. Group by category
    const byCategory = groupByCategory(conversation.decisions);

    // 4. Display candidates
    logger.header('Decisions by Category:');
    logger.blank();

    let totalCandidates = 0;

    for (const [category, decisions] of Object.entries(byCategory)) {
      if (decisions.length > 0) {
        logger.info(chalk.cyan(`${formatCategory(category)} (${decisions.length})`));
        decisions.slice(0, 3).forEach(d => {
          const preview = d.text.split('\n')[0].substring(0, 70);
          logger.dim(`  - ${preview}...`);
        });
        if (decisions.length > 3) {
          logger.dim(`  ... and ${decisions.length - 3} more`);
        }
        logger.blank();
        totalCandidates += decisions.length;
      }
    }

    // 5. Sync (for now, just report - interactive approval would be added later)
    if (options.dryRun) {
      logger.warn('Dry run mode - no files updated');
      logger.dim(`Would update ${Object.keys(byCategory).length} standard files`);
      return;
    }

    spinner.start('Updating standards...');

    const standardsDir = join(targetPath, '.morph', 'project', 'standards');
    await ensureDir(standardsDir);

    let updatedFiles = [];

    for (const [category, decisions] of Object.entries(byCategory)) {
      if (decisions.length === 0) continue;

      const fileName = `${category}.md`;
      const filePath = join(standardsDir, fileName);

      // Read existing or create new
      let content = '';
      if (existsSync(filePath)) {
        content = await readFile(filePath);
      } else {
        content = `# ${formatCategory(category)} Standards\n\n> Project-specific standards for ${category}\n\n`;
      }

      // Append new decisions
      content += `\n## Decisions from Features (${new Date().toISOString().split('T')[0]})\n\n`;

      decisions.forEach((d, idx) => {
        const preview = d.text.split('\n').slice(0, 5).join('\n');
        content += `### Decision ${idx + 1}\n\n${preview}\n\n`;
      });

      await writeFile(filePath, content);
      updatedFiles.push(fileName);
    }

    spinner.succeed(`Updated ${updatedFiles.length} standard files`);

    updatedFiles.forEach(file => {
      logger.dim(`  - ${file}`);
    });

    logger.blank();
    logger.success('Standards sync complete!');
    logger.dim('Commit these changes with a sync: message.');

  } catch (error) {
    spinner.fail('Sync failed');
    logger.error(error.message);
    process.exit(1);
  }
}

/**
 * Group decisions by category
 */
function groupByCategory(decisions) {
  const categories = {
    'coding': [],
    'architecture': [],
    'azure': [],
    'integrations': [],
    'ui-ux': []
  };

  decisions.forEach(decision => {
    const category = decision.category || 'coding';
    if (categories[category]) {
      categories[category].push(decision);
    }
  });

  return categories;
}

/**
 * Format category name
 */
function formatCategory(category) {
  const names = {
    'coding': 'Coding Standards',
    'architecture': 'Architecture Patterns',
    'azure': 'Azure & Infrastructure',
    'integrations': 'Integration Patterns',
    'ui-ux': 'UI/UX Standards'
  };

  return names[category] || category;
}
