/**
 * AutoLlama Dev Command
 * 🦙 Start development environment with hot reload and auto-migration
 */

const chalk = require('chalk');
const ora = require('ora');
const { startDevelopment } = require('../services/manager');
const { execSync } = require('child_process');
const fs = require('fs-extra');
const path = require('path');

class DevCommand {
  constructor(options = {}) {
    this.options = {
      port: options.port || process.env.PORT || '8080',
      apiPort: options.apiPort || process.env.API_PORT || '3001',
      open: options.open !== false,
      mode: options.mode || process.env.DEPLOYMENT_MODE || 'local',
      ...options
    };
    
    this.serviceManager = null;
    this.startTime = Date.now();
  }

  async run() {
    console.log(chalk.cyan.bold('\n🦙 AutoLlama Development Server'));
    console.log(chalk.gray('Starting your RAG development environment...\n'));

    try {
      // 1. Pre-flight checks
      await this.preFlightChecks();
      
      // 2. Initialize service manager
      await this.initializeServices();
      
      // 3. Start development environment
      await this.startDevelopment();
      
      // 4. Show status and instructions
      this.showStatus();
      
      // 5. Setup watchers and keep alive
      this.setupWatchers();
      
    } catch (error) {
      console.error(chalk.red.bold('\n❌ Failed to start development server:'), error.message);
      
      if (this.serviceManager) {
        await this.serviceManager.stop();
      }
      
      process.exit(1);
    }
  }

  async preFlightChecks() {
    const spinner = ora('Running pre-flight checks...').start();
    
    const checks = {
      envFile: await fs.pathExists('.env'),
      nodeModules: await fs.pathExists('node_modules'),
      dataDir: await fs.pathExists('data'),
      packageJson: await fs.pathExists('package.json')
    };
    
    const failed = Object.entries(checks)
      .filter(([, status]) => !status)
      .map(([name]) => name);
    
    if (failed.includes('packageJson')) {
      spinner.fail('Not in an AutoLlama project directory');
      console.log(chalk.yellow('🦙 Run this command from your AutoLlama project root'));
      process.exit(1);
    }
    
    if (failed.includes('nodeModules')) {
      spinner.text = 'Installing dependencies...';
      execSync('npm install', { stdio: 'pipe' });
      spinner.text = 'Dependencies installed, continuing...';
    }
    
    if (failed.includes('envFile')) {
      spinner.warn('.env file not found');
      console.log(chalk.yellow('🦙 Creating default .env file...'));
      await this.createDefaultEnv();
    } else {
      spinner.succeed('Pre-flight checks passed');
    }
    
    if (failed.includes('dataDir')) {
      await fs.ensureDir('data');
    }
  }

  async createDefaultEnv() {
    const envContent = `# AutoLlama Development Configuration
# Generated by 'autollama dev'

# Deployment Mode
DEPLOYMENT_MODE=${this.options.mode}

# AI Provider (add your API key)
OPENAI_API_KEY=your_openai_api_key_here
AI_PROVIDER=openai

# Database (SQLite for development)
DATABASE_TYPE=sqlite
DATABASE_PATH=./data/autollama.db

# Vector Database
QDRANT_URL=http://localhost:6333

# Server Ports
PORT=${this.options.apiPort}
FRONTEND_PORT=${this.options.port}

# Development Settings
NODE_ENV=development
DEBUG=false
LLAMA_PERSONALITY=friendly

# RAG Configuration
ENABLE_CONTEXTUAL_EMBEDDINGS=true
CONTEXT_GENERATION_BATCH_SIZE=5
`;
    
    await fs.writeFile('.env', envContent);
    console.log(chalk.green('✅ Created .env file'));
    console.log(chalk.yellow('🔑 Remember to add your OpenAI API key!'));
  }

  async initializeServices() {
    const spinner = ora('Initializing AutoLlama...').start();
    
    try {
      this.serviceManager = await startDevelopment({
        deploymentMode: this.options.mode,
        projectRoot: process.cwd(),
        ports: {
          api: this.options.apiPort,
          frontend: this.options.port
        }
      });
      
      spinner.succeed('AutoLlama services initialized');
    } catch (error) {
      spinner.fail('Service initialization failed');
      throw error;
    }
  }

  async startDevelopment() {
    console.log(chalk.cyan('🚀 Starting development services...\n'));
    
    // Services are started by the service manager
    // Just wait a moment for everything to stabilize
    await new Promise(resolve => setTimeout(resolve, 3000));
  }

  showStatus() {
    const duration = Math.round((Date.now() - this.startTime) / 1000);
    
    console.log(chalk.green.bold('\n✅ Development server ready!'));
    console.log(chalk.gray(`Started in ${duration} seconds\n`));
    
    console.log(chalk.cyan('🌐 URLs:'));
    console.log(chalk.white(`  • Application:  http://localhost:${this.options.port}`));
    console.log(chalk.white(`  • API Server:   http://localhost:${this.options.apiPort}`));
    console.log(chalk.white(`  • API Docs:     http://localhost:${this.options.port}/api/docs`));
    console.log(chalk.white(`  • Health Check: http://localhost:${this.options.apiPort}/health`));
    
    console.log(chalk.cyan('\n📊 Mode:'));
    console.log(chalk.white(`  • Deployment:   ${this.options.mode}`));
    console.log(chalk.white(`  • Database:     ${this.options.mode === 'local' ? 'SQLite (embedded)' : 'PostgreSQL'}`));
    console.log(chalk.white(`  • Vector DB:    ${this.options.mode === 'local' ? 'Embedded Qdrant' : 'External Qdrant'}`));
    
    // Check API key
    if (!process.env.OPENAI_API_KEY || process.env.OPENAI_API_KEY === 'your_openai_api_key_here') {
      console.log(chalk.yellow('\n⚠️  No AI API key configured'));
      console.log(chalk.gray('   Add OPENAI_API_KEY to your .env file'));
    }
    
    // Open browser
    if (this.options.open) {
      this.openBrowser();
    }
    
    // Show friendly message
    const personality = process.env.LLAMA_PERSONALITY || 'friendly';
    const messages = {
      professional: '\n🦙 Development server is running.',
      friendly: '\n🦙 Your development environment is ready! Happy coding!',
      party: '\n🦙🎉 DEVELOPMENT SERVER IS LIVE! Let\'s build something AMAZING! 🚀'
    };
    
    console.log(chalk.cyan.bold(messages[personality] || messages.friendly));
    console.log(chalk.gray('\n📝 Logs will appear below. Press Ctrl+C to stop.\n'));
  }

  openBrowser() {
    const url = `http://localhost:${this.options.port}`;
    const platform = process.platform;
    
    try {
      if (platform === 'darwin') {
        execSync(`open ${url}`, { stdio: 'ignore' });
      } else if (platform === 'linux') {
        execSync(`xdg-open ${url}`, { stdio: 'ignore' });
      } else if (platform === 'win32') {
        execSync(`start ${url}`, { stdio: 'ignore' });
      }
      console.log(chalk.green('🌐 Browser opened'));
    } catch {
      console.log(chalk.gray(`🌐 Open your browser to: ${chalk.cyan(url)}`));
    }
  }

  setupWatchers() {
    // File watching for hot reload (would be implemented here)
    // For now, just keep the process alive
    
    const shutdown = async () => {
      console.log(chalk.yellow('\n\n🦙 Shutting down development server...'));
      
      if (this.serviceManager) {
        await this.serviceManager.stop();
      }
      
      console.log(chalk.green('✅ Development server stopped'));
      console.log(chalk.gray('Thanks for using AutoLlama! 🦙💙'));
      process.exit(0);
    };
    
    process.on('SIGINT', shutdown);
    process.on('SIGTERM', shutdown);
    
    // Keep process alive
    setInterval(() => {
      // Could implement health checks here
    }, 30000);
  }
}

module.exports = DevCommand;