const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const axios = require('axios');
const _ = require('lodash');
require('dotenv').config();

const UnifiedTechStackService = require('./services/unified-tech-stack-service');
const TemplateManagerClient = require('./clients/template-manager-client');
const TechStackSelectorClient = require('./clients/tech-stack-selector-client');

const app = express();
const PORT = process.env.PORT || 8013;

// Initialize service clients
const templateManagerClient = new TemplateManagerClient();
const techStackSelectorClient = new TechStackSelectorClient();
const unifiedService = new UnifiedTechStackService(templateManagerClient, techStackSelectorClient);

// Middleware
app.use(helmet());
app.use(cors({
  origin: "*",
  credentials: true,
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization', 'X-User-ID', 'X-User-Role']
}));
app.use(morgan('combined'));
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));

// Middleware to extract and validate user authentication
const authenticateUser = async (req, res, next) => {
  try {
    const authHeader = req.headers.authorization;
    
    if (!authHeader || !authHeader.startsWith('Bearer ')) {
      // No authentication provided - allow anonymous access
      req.user = null;
      req.userId = null;
      return next();
    }

    const token = authHeader.substring(7); // Remove 'Bearer ' prefix
    
    // Validate token with user-auth service
    const validationResult = await unifiedService.validateUserToken(token);
    
    if (validationResult.success) {
      req.user = validationResult.user;
      req.userId = validationResult.user.id;
      console.log(`✅ Authenticated user: ${req.user.username} (${req.userId})`);
    } else {
      console.log(`❌ Token validation failed: ${validationResult.error}`);
      req.user = null;
      req.userId = null;
    }
    
    next();
  } catch (error) {
    console.error('❌ Authentication middleware error:', error.message);
    req.user = null;
    req.userId = null;
    next();
  }
};

// Apply authentication middleware to all routes
app.use(authenticateUser);
app.get('/health', (req, res) => {
  res.json({
    status: 'healthy',
    service: 'unified-tech-stack-service',
    version: '1.0.0',
    timestamp: new Date().toISOString()
  });
});

// Comprehensive tech stack recommendations endpoint (includes Claude AI)
app.post('/api/unified/comprehensive-recommendations', async (req, res) => {
  try {
    const { 
      template,
      features = [],
      businessContext,
      projectName,
      projectType,
      templateId,
      budget,
      domain,
      preferences = {},
      includeClaude = true,
      includeTemplateBased = true,
      includeDomainBased = true,
      sessionId = null,
      saveToDatabase = true,
      useCache = true
    } = req.body;

    // Use authenticated user ID or fallback to request body
    const userId = req.userId || req.body.userId || null;

    console.log('🚀 Processing comprehensive tech stack recommendation request...');
    console.log(`📊 Template: ${template?.title}`);
    console.log(`🔧 Features provided: ${features.length}`);
    console.log(`🤖 Include Claude: ${includeClaude}`);
    console.log(`📊 Include Template-based: ${includeTemplateBased}`);
    console.log(`🏢 Include Domain-based: ${includeDomainBased}`);
    console.log(`👤 User ID: ${userId || 'anonymous'}`);
    console.log(`💾 Save to database: ${saveToDatabase}`);
    console.log(`🗄️ Use cache: ${useCache}`);

    // Validate required fields for Claude recommendations
    if (includeClaude && (!template || !features || !businessContext)) {
      return res.status(400).json({
        success: false,
        error: 'Missing required fields for Claude recommendations: template, features, or businessContext',
      });
    }

    // Validate template structure
    if (includeClaude && (!template.title || !template.category)) {
      return res.status(400).json({
        success: false,
        error: 'Template must have title and category',
      });
    }

    // Validate features array
    if (includeClaude && (!Array.isArray(features) || features.length === 0)) {
      return res.status(400).json({
        success: false,
        error: 'Features must be a non-empty array',
      });
    }

    // Validate business context
    if (includeClaude && (!businessContext.questions || !Array.isArray(businessContext.questions))) {
      return res.status(400).json({
        success: false,
        error: 'Business context must have questions array',
      });
    }

    const comprehensiveRecommendations = await unifiedService.getComprehensiveRecommendations({
      template,
      features,
      businessContext,
      projectName,
      projectType,
      templateId,
      budget,
      domain,
      preferences,
      includeClaude,
      includeTemplateBased,
      includeDomainBased,
      userId,
      sessionId,
      saveToDatabase,
      useCache
    });

    // Add template information to response
    const response = {
      success: true,
      data: {
        ...comprehensiveRecommendations.data,
        templateInfo: {
          id: templateId,
          title: template?.title || 'Unknown',
          type: template?.type || template?.category || 'unknown',
          featuresCount: features.length,
          features: features.map(f => ({
            id: f.id,
            name: f.name,
            description: f.description,
            type: f.feature_type,
            complexity: f.complexity
          }))
        },
        requestFeatures: features,
        finalFeatures: features.map(f => f.name)
      },
      message: 'Comprehensive tech stack recommendations generated successfully'
    };

    res.json(response);

  } catch (error) {
    console.error('❌ Comprehensive recommendation error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Internal server error',
      message: error.message
    });
  }
});

// Unified recommendation endpoint
app.post('/api/unified/recommendations', async (req, res) => {
  try {
    const { 
      templateId, 
      budget, 
      domain, 
      features = [], 
      preferences = {},
      includePermutations = true,
      includeCombinations = true,
      includeDomainRecommendations = true
    } = req.body;

    console.log('🚀 Processing unified tech stack recommendation request...');
    console.log(`📊 Template ID: ${templateId}`);
    console.log(`💰 Budget: ${budget}`);
    console.log(`🏢 Domain: ${domain}`);
    console.log(`🔧 Features provided: ${features.length}`);

    // Fetch template features from database if templateId is provided
    let templateFeatures = [];
    let templateInfo = null;
    
    if (templateId) {
      console.log('🔍 Fetching template features from database...');
      const featuresResponse = await templateManagerClient.getTemplateFeatures(templateId);
      
      if (featuresResponse.success) {
        templateFeatures = featuresResponse.data.data || [];
        templateInfo = featuresResponse.data.templateInfo;
        console.log(`✅ Found ${templateFeatures.length} template features`);
        
        // Log feature names for debugging
        const featureNames = templateFeatures.map(f => f.name).slice(0, 5);
        console.log(`📋 Sample features: ${featureNames.join(', ')}${templateFeatures.length > 5 ? '...' : ''}`);
      } else {
        console.log(`⚠️ Failed to fetch template features: ${featuresResponse.error}`);
      }
    }

    // Use template features if no features provided in request
    const finalFeatures = features.length > 0 ? features : templateFeatures.map(f => f.name);

    console.log(`🎯 Using ${finalFeatures.length} features for recommendations`);

    const unifiedRecommendations = await unifiedService.getUnifiedRecommendations({
      templateId,
      budget,
      domain,
      features: finalFeatures,
      preferences: {
        ...preferences,
        // Use only user-requested features for filtering when provided
        featureFilter: Array.isArray(features) && features.length > 0 ? features : []
      },
      includePermutations,
      includeCombinations,
      includeDomainRecommendations
    });

    // Add template information to response
    const response = {
      success: true,
      data: {
        ...unifiedRecommendations.data,
        templateInfo: {
          id: templateId,
          title: templateInfo?.title || 'Unknown',
          type: templateInfo?.template_type || 'unknown',
          featuresCount: templateFeatures.length,
          // Show requested features only if provided, else show all template features
          features: (features.length > 0 ? templateFeatures.filter(f => features.includes(f.name)) : templateFeatures).map(f => ({
            id: f.id,
            name: f.name,
            description: f.description,
            type: f.feature_type,
            complexity: f.complexity
          }))
        },
        requestFeatures: features,
        finalFeatures: finalFeatures
      },
      message: 'Unified tech stack recommendations generated successfully'
    };

    res.json(response);

  } catch (error) {
    console.error('❌ Unified recommendation error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Internal server error',
      message: error.message
    });
  }
});

// Get user's recommendation statistics
app.get('/api/unified/user/stats', async (req, res) => {
  try {
    const userId = req.userId;
    
    if (!userId) {
      return res.status(401).json({
        success: false,
        error: 'Authentication required',
        message: 'Please provide a valid authentication token'
      });
    }

    console.log(`📊 Getting recommendation statistics for user: ${userId}`);

    const stats = await unifiedService.getUserRecommendationStats(userId);

    res.json({
      success: stats.success,
      data: stats.data,
      message: stats.success ? 'User recommendation statistics retrieved successfully' : 'Failed to retrieve statistics'
    });

  } catch (error) {
    console.error('❌ User recommendation stats error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Internal server error',
      message: error.message
    });
  }
});

// Get user's recommendation history
app.get('/api/unified/user/recommendations', async (req, res) => {
  try {
    const userId = req.userId;
    const { limit = 10 } = req.query;
    
    if (!userId) {
      return res.status(401).json({
        success: false,
        error: 'Authentication required',
        message: 'Please provide a valid authentication token'
      });
    }

    console.log(`📚 Getting recommendation history for user: ${userId}`);

    const history = await unifiedService.getUserRecommendationHistory(userId, parseInt(limit));

    res.json({
      success: history.success,
      data: history.data,
      message: history.success ? 'User recommendation history retrieved successfully' : 'Failed to retrieve history'
    });

  } catch (error) {
    console.error('❌ User recommendation history error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Internal server error',
      message: error.message
    });
  }
});

// Get user's recommendation history
app.get('/api/unified/user/:userId/recommendations', async (req, res) => {
  try {
    const { userId } = req.params;
    const { limit = 10 } = req.query;

    console.log(`📚 Getting recommendation history for user: ${userId}`);

    const history = await unifiedService.getUserRecommendationHistory(userId, parseInt(limit));

    res.json({
      success: history.success,
      data: history.data,
      message: history.success ? 'User recommendation history retrieved successfully' : 'Failed to retrieve history'
    });

  } catch (error) {
    console.error('❌ User recommendation history error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Internal server error',
      message: error.message
    });
  }
});

// Get cached recommendations for user
app.get('/api/unified/cached-recommendations/:templateId', async (req, res) => {
  try {
    const { templateId } = req.params;
    const { userId, sessionId } = req.query;

    console.log(`🔍 Getting cached recommendations for template: ${templateId}`);

    const cachedResult = await unifiedService.database.getRecommendations(templateId, userId, sessionId);

    res.json({
      success: cachedResult.success,
      data: cachedResult.data,
      message: cachedResult.success ? 'Cached recommendations retrieved successfully' : 'No cached recommendations found'
    });

  } catch (error) {
    console.error('❌ Cached recommendations error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Internal server error',
      message: error.message
    });
  }
});

// Clean up expired recommendations (admin endpoint)
app.post('/api/unified/admin/cleanup-expired', async (req, res) => {
  try {
    console.log('🧹 Cleaning up expired recommendations...');

    const cleanupResult = await unifiedService.cleanupExpiredRecommendations();

    res.json({
      success: cleanupResult.success,
      data: {
        deletedCount: cleanupResult.deletedCount || 0
      },
      message: cleanupResult.success ? 
        `Cleaned up ${cleanupResult.deletedCount} expired recommendations` : 
        'Failed to cleanup expired recommendations'
    });

  } catch (error) {
    console.error('❌ Cleanup expired recommendations error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Internal server error',
      message: error.message
    });
  }
});

// Service status endpoint (enhanced with database info)
app.get('/api/unified/status', async (req, res) => {
  try {
    const status = await unifiedService.getServiceStatus();
    res.json({
      success: true,
      data: status,
      message: 'Service status retrieved successfully'
    });
  } catch (error) {
    console.error('❌ Service status error:', error.message);
    res.status(500).json({
      success: false,
      error: 'Internal server error',
      message: error.message
    });
  }
});

// Error handling middleware
app.use((error, req, res, next) => {
  console.error('❌ Unhandled error:', error);
  res.status(500).json({
    success: false,
    error: 'Internal server error',
    message: 'An unexpected error occurred'
  });
});

// 404 handler
app.use('*', (req, res) => {
  res.status(404).json({
    success: false,
    error: 'Not Found',
    message: 'Endpoint not found'
  });
});

// Validate environment variables
const claudeApiKey = process.env.CLAUDE_API_KEY || process.env.ANTHROPIC_API_KEY;
if (!claudeApiKey) {
  console.warn('⚠️  WARNING: Claude API key not found in environment variables');
  console.warn('   Set CLAUDE_API_KEY or ANTHROPIC_API_KEY in your .env file');
  console.warn('   Claude AI recommendations will not work without this key');
} else {
  console.log('✅ Claude API key found - AI recommendations enabled');
}

// Start server
app.listen(PORT, () => {
  console.log(`🚀 Unified Tech Stack Service running on port ${PORT}`);
  console.log(`📊 Health check: http://localhost:${PORT}/health`);
  console.log(`🔗 API endpoints:`);
  console.log(`   POST /api/unified/comprehensive-recommendations - Get comprehensive recommendations (Claude AI + Template + Domain)`);
  console.log(`   POST /api/unified/recommendations - Get unified recommendations (Template + Domain only)`);
});

module.exports = app;
