/**
 * @fileoverview OrdoJS CLI - Init command
 */

import { Command } from 'commander';
import fs from 'fs/promises';
import path from 'path';
import { logger } from '../utils/index.js';

/**
 * Register the init command
 */
export function registerInitCommand(program: Command): void {
  program
    .command('init')
    .description('Initialize a new OrdoJS project')
    .option('-n, --name <name>', 'Project name', 'my-ordojs-app')
    .option('-t, --template <template>', 'Project template (basic, fullstack)', 'basic')
    .option('--css-framework <framework>', 'CSS framework to integrate (tailwind, bootstrap, bulma, foundation, none)', 'none')
    .option('--typescript', 'Use TypeScript', false)
    .option('--git', 'Initialize git repository', true)
    .option('--install', 'Install dependencies after creation', true)
    .action(async (options) => {
      await initProject(options);
    });
}

async function initProject(options: {
  name: string;
  template: string;
  cssFramework: string;
  typescript: boolean;
  git: boolean;
  install: boolean;
}): Promise<void> {
  logger.info(`🚀 Initializing new OrdoJS project: ${options.name}`);

  try {
    // Create project directory
    const projectDir = path.resolve(options.name);
    await fs.mkdir(projectDir, { recursive: true });

    // Copy template files
    await copyTemplateFiles(options.template, projectDir, options);

    // Initialize git if requested
    if (options.git) {
      await initializeGit(projectDir);
    }

    // Install dependencies if requested
    if (options.install) {
      await installDependencies(projectDir);
    }

    // Integrate CSS framework if specified
    if (options.cssFramework !== 'none') {
      await integrateCSSFramework(projectDir, options.cssFramework);
    }

    logger.success(`✅ Project '${options.name}' created successfully!`);
    logger.info(`📁 Project directory: ${projectDir}`);

    if (options.install) {
      logger.info(`📦 Dependencies installed`);
    }

    if (options.cssFramework !== 'none') {
      logger.info(`🎨 ${options.cssFramework} CSS framework integrated`);
    }

    // Display next steps
    displayNextSteps(options.name, options.cssFramework);

  } catch (error) {
    logger.error(`Failed to initialize project: ${error instanceof Error ? error.message : String(error)}`);
    process.exit(1);
  }
}

async function copyTemplateFiles(template: string, projectDir: string, options: {
  name: string;
  template: string;
  cssFramework: string;
  typescript: boolean;
  git: boolean;
  install: boolean;
}): Promise<void> {
  logger.info(`📦 Copying template files for template: ${template}`);

  try {
    const templatePath = path.join(__dirname, '..', 'templates', template);
    await fs.cp(templatePath, projectDir, { recursive: true });
    logger.success(`✅ Template files copied successfully from ${templatePath} to ${projectDir}`);
  } catch (error) {
    logger.error(`Failed to copy template files: ${error instanceof Error ? error.message : String(error)}`);
    process.exit(1);
  }
}

async function initializeGit(projectDir: string): Promise<void> {
  logger.info(`🔗 Initializing git repository...`);
  try {
    const { execSync } = await import('child_process');
    execSync('git init', { stdio: 'inherit', cwd: projectDir });
    execSync('git add .', { stdio: 'inherit', cwd: projectDir });
    execSync('git commit -m "Initial commit"', { stdio: 'inherit', cwd: projectDir });
    logger.success(`✅ Git repository initialized and committed.`);
  } catch (error) {
    logger.warn(`⚠️ Git initialization failed: ${error instanceof Error ? error.message : String(error)}`);
    logger.info(`💡 You can manually initialize git with: git init && git add . && git commit -m "Initial commit"`);
  }
}

async function installDependencies(projectDir: string): Promise<void> {
  logger.info(`📦 Installing dependencies...`);
  try {
    const { execSync } = await import('child_process');
    execSync('npm install', { stdio: 'inherit', cwd: projectDir });
    logger.success(`✅ Dependencies installed.`);
  } catch (error) {
    logger.error(`Failed to install dependencies: ${error instanceof Error ? error.message : String(error)}`);
    process.exit(1);
  }
}

async function integrateCSSFramework(projectDir: string, framework: string): Promise<void> {
  logger.info(`🎨 Integrating ${framework} CSS framework...`);

  try {
    // Change to project directory
    process.chdir(projectDir);

    // Run CSS framework integration
    const { execSync } = await import('child_process');
    execSync(`ordojs css-framework ${framework} --output ./styles`, {
      stdio: 'inherit',
      cwd: projectDir
    });

    logger.success(`✅ ${framework} CSS framework integrated successfully!`);
  } catch (error) {
    logger.warn(`⚠️ CSS framework integration failed: ${error instanceof Error ? error.message : String(error)}`);
    logger.info(`💡 You can manually integrate ${framework} later with: ordojs css-framework ${framework}`);
  }
}

function displayNextSteps(projectName: string, cssFramework: string): void {
  logger.info('\n🎉 Next steps:');
  logger.info(`  cd ${projectName}`);

  if (cssFramework !== 'none') {
    logger.info(`  # ${cssFramework} CSS framework is ready to use!`);
    logger.info(`  # Check out the generated styles/${cssFramework}.css file`);
  }

  logger.info('  ordojs dev          # Start development server');
  logger.info('  ordojs build        # Build for production');
  logger.info('  ordojs deploy       # Deploy your application');

  if (cssFramework === 'tailwind') {
    logger.info('\n📚 Tailwind CSS Resources:');
    logger.info('  - https://tailwindcss.com/docs');
    logger.info('  - https://tailwindcss.com/components');
    logger.info('  - Check out the demo at http://localhost:3000');
  }
}
