const axios = require('axios');

// Configuration
const BASE_URL = 'http://localhost:5500';
const TEST_CONFIG = {
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json'
  }
};

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

// Logging functions
const log = {
  info: (msg) => console.log(`${colors.blue}[INFO]${colors.reset} ${msg}`),
  success: (msg) => console.log(`${colors.green}[SUCCESS]${colors.reset} ${msg}`),
  error: (msg) => console.log(`${colors.red}[ERROR]${colors.reset} ${msg}`),
  warning: (msg) => console.log(`${colors.yellow}[WARNING]${colors.reset} ${msg}`),
  debug: (msg) => console.log(`${colors.cyan}[DEBUG]${colors.reset} ${msg}`),
  test: (msg) => console.log(`${colors.magenta}[TEST]${colors.reset} ${msg}`)
};

// Test cases
const tests = [
  {
    name: 'Health Check',
    method: 'GET',
    url: '/api/health',
    expectedStatus: 200
  },
  {
    name: 'Get All Exams',
    method: 'GET',
    url: '/api/exams',
    expectedStatus: 200
  },
  {
    name: 'Get Exams by Stage (Class 6-10)',
    method: 'GET',
    url: '/api/exams/stage/class_6_10',
    expectedStatus: 200
  },
  {
    name: 'Get Quiz Questions',
    method: 'GET',
    url: '/api/quiz/questions?stage=class_6_10&limit=5',
    expectedStatus: 200
  },
  {
    name: 'Get Quiz Categories',
    method: 'GET',
    url: '/api/quiz/categories',
    expectedStatus: 200
  },
  {
    name: 'Get Quiz Leaderboard',
    method: 'GET',
    url: '/api/quiz/leaderboard',
    expectedStatus: 200
  },
  {
    name: 'Generate Quiz Questions (Gemini AI)',
    method: 'POST',
    url: '/api/quiz/generate',
    data: {
      stage: 'class_6_10',
      category: 'gk',
      difficulty: 'medium',
      count: 5
    },
    expectedStatus: 200
  },
  {
    name: 'Get Study Groups',
    method: 'GET',
    url: '/api/study-groups',
    expectedStatus: 200
  },
  {
    name: 'Get Free Education Exams',
    method: 'GET',
    url: '/api/free-education',
    expectedStatus: 200
  },
  {
    name: 'Get Career Paths',
    method: 'GET',
    url: '/api/career-paths',
    expectedStatus: 200
  }
];

// Utility function to make API calls
async function makeRequest(test) {
  const startTime = Date.now();
  
  try {
    const config = {
      ...TEST_CONFIG,
      method: test.method.toLowerCase(),
      url: `${BASE_URL}${test.url}`
    };

    if (test.data) {
      config.data = test.data;
    }

    log.test(`Testing: ${test.name}`);
    log.debug(`Request: ${test.method} ${test.url}`);
    
    if (test.data) {
      log.debug(`Data: ${JSON.stringify(test.data, null, 2)}`);
    }

    const response = await axios(config);
    const duration = Date.now() - startTime;

    // Check status code
    if (response.status === test.expectedStatus) {
      log.success(`✅ ${test.name} - Status: ${response.status} (${duration}ms)`);
    } else {
      log.warning(`⚠️ ${test.name} - Expected: ${test.expectedStatus}, Got: ${response.status} (${duration}ms)`);
    }

    // Log response details
    log.debug(`Response size: ${JSON.stringify(response.data).length} bytes`);
    
    if (response.data.success !== undefined) {
      log.debug(`Success: ${response.data.success}`);
    }
    
    if (response.data.data && Array.isArray(response.data.data)) {
      log.debug(`Data count: ${response.data.data.length}`);
    } else if (response.data.data && typeof response.data.data === 'object') {
      log.debug(`Data keys: ${Object.keys(response.data.data).join(', ')}`);
    }

    return {
      success: true,
      status: response.status,
      duration,
      data: response.data
    };

  } catch (error) {
    const duration = Date.now() - startTime;
    
    if (error.response) {
      log.error(`❌ ${test.name} - Status: ${error.response.status} (${duration}ms)`);
      log.error(`Error: ${error.response.data?.message || error.message}`);
      log.debug(`Response: ${JSON.stringify(error.response.data, null, 2)}`);
      
      return {
        success: false,
        status: error.response.status,
        duration,
        error: error.response.data
      };
    } else {
      log.error(`❌ ${test.name} - Network Error (${duration}ms)`);
      log.error(`Error: ${error.message}`);
      
      return {
        success: false,
        status: 0,
        duration,
        error: error.message
      };
    }
  }
}

// Main test runner
async function runTests() {
  log.info('🚀 Starting API Debug Tests');
  log.info(`Base URL: ${BASE_URL}`);
  log.info(`Total Tests: ${tests.length}`);
  log.info('');

  const results = [];
  let passed = 0;
  let failed = 0;

  for (const test of tests) {
    const result = await makeRequest(test);
    results.push({ ...test, result });
    
    if (result.success) {
      passed++;
    } else {
      failed++;
    }
    
    log.info(''); // Add spacing between tests
  }

  // Summary
  log.info('📊 TEST SUMMARY');
  log.info('================');
  log.success(`✅ Passed: ${passed}`);
  log.error(`❌ Failed: ${failed}`);
  log.info(`📈 Total: ${tests.length}`);
  log.info('');

  // Detailed results
  log.info('📋 DETAILED RESULTS');
  log.info('===================');
  
  results.forEach(({ name, result }) => {
    if (result.success) {
      log.success(`✅ ${name} - ${result.status} (${result.duration}ms)`);
    } else {
      log.error(`❌ ${name} - ${result.status} (${result.duration}ms)`);
    }
  });

  log.info('');
  log.info('🏁 Test run completed!');
  
  // Exit with error code if any tests failed
  if (failed > 0) {
    process.exit(1);
  }
}

// Check if server is running first
async function checkServer() {
  try {
    log.info('🔍 Checking if server is running...');
    const response = await axios.get(`${BASE_URL}/api/health`, { timeout: 5000 });
    log.success('✅ Server is running and healthy');
    log.info(`Server info: ${JSON.stringify(response.data.data, null, 2)}`);
    return true;
  } catch (error) {
    log.error('❌ Server is not running or not accessible');
    log.error(`Error: ${error.message}`);
    log.info('Please start the server first with: npm run debug');
    return false;
  }
}

// Main execution
async function main() {
  console.log(`${colors.bright}${colors.cyan}`);
  console.log('╔══════════════════════════════════════════════════════════════╗');
  console.log('║                RECONNECTIFLY API DEBUG TESTER                ║');
  console.log('╚══════════════════════════════════════════════════════════════╝');
  console.log(`${colors.reset}`);
  
  const serverRunning = await checkServer();
  
  if (!serverRunning) {
    process.exit(1);
  }
  
  log.info('');
  await runTests();
}

// Handle unhandled promise rejections
process.on('unhandledRejection', (reason, promise) => {
  log.error('Unhandled Promise Rejection:', reason);
  process.exit(1);
});

// Run the tests
main().catch(error => {
  log.error('Test runner error:', error);
  process.exit(1);
});
