const mongoose = require('mongoose');
const path = require('path');
const fs = require('fs');

// Colors for console output
const colors = {
  green: '\x1b[32m',
  red: '\x1b[31m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  reset: '\x1b[0m'
};

function log(message, color = 'reset') {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

// Validation results
const validationResults = {
  passed: 0,
  failed: 0,
  warnings: 0,
  errors: []
};

// Helper function to run validation
async function runValidation(name, validationFunction) {
  try {
    const result = await validationFunction();
    if (result === true) {
      log(`✅ ${name}`, 'green');
      validationResults.passed++;
    } else if (result === 'warning') {
      log(`⚠️  ${name}`, 'yellow');
      validationResults.warnings++;
    } else {
      log(`❌ ${name}`, 'red');
      validationResults.failed++;
      validationResults.errors.push(name);
    }
  } catch (error) {
    log(`❌ ${name} - Error: ${error.message}`, 'red');
    validationResults.failed++;
    validationResults.errors.push(`${name}: ${error.message}`);
  }
}

// Validation functions
async function validateEnvironmentVariables() {
  // Check if .env file exists
  const envPath = path.join(__dirname, '.env');
  if (!fs.existsSync(envPath)) {
    throw new Error('.env file not found');
  }
  
  // Load environment variables
  require('dotenv').config();
  
  const requiredVars = ['MONGO_URI'];
  const optionalVars = ['JWT_SECRET', 'PORT', 'NODE_ENV'];
  
  let hasRequired = true;
  let hasOptional = false;
  
  for (const varName of requiredVars) {
    if (!process.env[varName]) {
      hasRequired = false;
      break;
    }
  }
  
  for (const varName of optionalVars) {
    if (process.env[varName]) {
      hasOptional = true;
      break;
    }
  }
  
  if (!hasRequired) return false;
  if (!hasOptional) return 'warning';
  return true;
}

async function validateDatabaseConnection() {
  try {
    const MONGO_URI = process.env.MONGO_URI || 
      "mongodb+srv://ydubey48_db_user:xCHPPhz0d9ObcDmt@therapy.zbtsngk.mongodb.net/?retryWrites=true&w=majority&appName=Therapy";
    
    await mongoose.connect(MONGO_URI, {
      useNewUrlParser: true,
      serverSelectionTimeoutMS: 5000
    });
    
    await mongoose.connection.close();
    return true;
  } catch (error) {
    throw new Error(`Database connection failed: ${error.message}`);
  }
}

async function validateModels() {
  const modelFiles = [
    'models/TherapistProfile.js',
    'models/userModel.js',
    'models/Appointment.js'
  ];
  
  for (const modelFile of modelFiles) {
    const modelPath = path.join(__dirname, modelFile);
    if (!fs.existsSync(modelPath)) {
      throw new Error(`Model file not found: ${modelFile}`);
    }
    
    try {
      require(modelPath);
    } catch (error) {
      throw new Error(`Model import failed for ${modelFile}: ${error.message}`);
    }
  }
  
  return true;
}

async function validateControllers() {
  const controllerFiles = [
    'controller/doctor/therapistProfileController.js',
    'controller/appointment/matchingController.js',
    'controller/admin/therapistApprovalController.js'
  ];
  
  for (const controllerFile of controllerFiles) {
    const controllerPath = path.join(__dirname, controllerFile);
    if (!fs.existsSync(controllerPath)) {
      throw new Error(`Controller file not found: ${controllerFile}`);
    }
    
    try {
      const controller = require(controllerPath);
      if (!controller || typeof controller !== 'object') {
        throw new Error(`Controller exports invalid: ${controllerFile}`);
      }
    } catch (error) {
      throw new Error(`Controller import failed for ${controllerFile}: ${error.message}`);
    }
  }
  
  return true;
}

async function validateRoutes() {
  const routeFiles = [
    'routes/doctor/therapistProfileRoutes.js',
    'routes/appointment/matchingRoutes.js',
    'routes/admin/therapistApprovalRoutes.js'
  ];
  
  for (const routeFile of routeFiles) {
    const routePath = path.join(__dirname, routeFile);
    if (!fs.existsSync(routePath)) {
      throw new Error(`Route file not found: ${routeFile}`);
    }
    
    try {
      const route = require(routePath);
      if (!route || typeof route !== 'function') {
        throw new Error(`Route exports invalid: ${routeFile}`);
      }
    } catch (error) {
      throw new Error(`Route import failed for ${routeFile}: ${error.message}`);
    }
  }
  
  return true;
}

async function validateMiddleware() {
  const middlewareFiles = [
    'middleware/authMiddleware.js'
  ];
  
  for (const middlewareFile of middlewareFiles) {
    const middlewarePath = path.join(__dirname, middlewareFile);
    if (!fs.existsSync(middlewarePath)) {
      throw new Error(`Middleware file not found: ${middlewareFile}`);
    }
    
    try {
      const middleware = require(middlewarePath);
      if (!middleware || typeof middleware !== 'object') {
        throw new Error(`Middleware exports invalid: ${middlewareFile}`);
      }
    } catch (error) {
      throw new Error(`Middleware import failed for ${middlewareFile}: ${error.message}`);
    }
  }
  
  return true;
}

async function validateDirectoryStructure() {
  const requiredDirs = [
    'models',
    'controller',
    'controller/doctor',
    'controller/appointment',
    'controller/admin',
    'routes',
    'routes/doctor',
    'routes/appointment',
    'routes/admin',
    'middleware'
  ];
  
  for (const dir of requiredDirs) {
    const dirPath = path.join(__dirname, dir);
    if (!fs.existsSync(dirPath)) {
      throw new Error(`Required directory not found: ${dir}`);
    }
  }
  
  return true;
}

async function validatePackageDependencies() {
  const packagePath = path.join(__dirname, 'package.json');
  if (!fs.existsSync(packagePath)) {
    throw new Error('package.json not found');
  }
  
  const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
  const requiredDeps = [
    'express',
    'mongoose',
    'jsonwebtoken',
    'bcryptjs',
    'cors',
    'dotenv',
    'moment'
  ];
  
  for (const dep of requiredDeps) {
    if (!packageJson.dependencies || !packageJson.dependencies[dep]) {
      throw new Error(`Required dependency not found: ${dep}`);
    }
  }
  
  return true;
}

// Main validation runner
async function runAllValidations() {
  log('🚀 Starting Backend Integration Validation...', 'blue');
  log('================================================', 'blue');
  
  await runValidation('Environment Variables', validateEnvironmentVariables);
  await runValidation('Package Dependencies', validatePackageDependencies);
  await runValidation('Directory Structure', validateDirectoryStructure);
  await runValidation('Database Models', validateModels);
  await runValidation('Controllers', validateControllers);
  await runValidation('Routes', validateRoutes);
  await runValidation('Middleware', validateMiddleware);
  await runValidation('Database Connection', validateDatabaseConnection);
  
  // Print results
  log('\n📊 Validation Results:', 'blue');
  log('======================', 'blue');
  log(`✅ Passed: ${validationResults.passed}`, 'green');
  log(`⚠️  Warnings: ${validationResults.warnings}`, 'yellow');
  log(`❌ Failed: ${validationResults.failed}`, 'red');
  
  const total = validationResults.passed + validationResults.warnings + validationResults.failed;
  const successRate = ((validationResults.passed / total) * 100).toFixed(1);
  log(`📈 Success Rate: ${successRate}%`, successRate > 80 ? 'green' : 'red');
  
  if (validationResults.errors.length > 0) {
    log('\n🔍 Issues Found:', 'red');
    validationResults.errors.forEach(error => {
      log(`   - ${error}`, 'red');
    });
  }
  
  if (validationResults.warnings > 0) {
    log('\n💡 Recommendations:', 'yellow');
    log('   - Set up environment variables for production', 'yellow');
    log('   - Configure JWT_SECRET for security', 'yellow');
    log('   - Set up email/SMS services for notifications', 'yellow');
  }
  
  log('\n🎯 Next Steps:', 'blue');
  if (validationResults.failed === 0) {
    log('   ✅ All critical validations passed!', 'green');
    log('   🚀 You can start the server with: npm start', 'green');
    log('   📚 Check the API documentation in THERAPIST_SYSTEM_README.md', 'blue');
  } else {
    log('   ❌ Fix the failed validations before starting the server', 'red');
    log('   📖 Check the error messages above for details', 'red');
  }
  
  return validationResults.failed === 0;
}

// Export for use in other files
module.exports = { runAllValidations };

// Run validations if this file is executed directly
if (require.main === module) {
  runAllValidations()
    .then(success => {
      process.exit(success ? 0 : 1);
    })
    .catch(error => {
      log(`💥 Validation runner crashed: ${error.message}`, 'red');
      process.exit(1);
    });
}
