const express = require('express');
const router = express.Router();
const TechStackRecommendation = require('../models/tech_stack_recommendation');
const IntelligentTechStackAnalyzer = require('../services/intelligent-tech-stack-analyzer');
const autoTechStackAnalyzer = require('../services/auto_tech_stack_analyzer');
const Template = require('../models/template');
const CustomTemplate = require('../models/custom_template');
const Feature = require('../models/feature');
const CustomFeature = require('../models/custom_feature');
const database = require('../config/database');

// Initialize analyzer
    const analyzer = new IntelligentTechStackAnalyzer();

// GET /api/tech-stack/recommendations - Get all tech stack recommendations
router.get('/recommendations', async (req, res) => {
  try {
    const limit = parseInt(req.query.limit) || 50;
    const offset = parseInt(req.query.offset) || 0;
    const status = req.query.status || null;
    
    console.log(`📊 [TechStack] Fetching recommendations (status: ${status || 'all'}, limit: ${limit}, offset: ${offset})`);
    
    let recommendations;
    if (status) {
      recommendations = await TechStackRecommendation.getByStatus(status, limit, offset);
    } else {
      recommendations = await TechStackRecommendation.getAll(limit, offset);
    }
    
    res.json({
      success: true,
      data: recommendations,
      count: recommendations.length,
      message: `Found ${recommendations.length} tech stack recommendations`
    });
  } catch (error) {
    console.error('❌ Error fetching tech stack recommendations:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to fetch recommendations',
      message: error.message
    });
  }
});

// GET /api/tech-stack/recommendations/with-details - Get recommendations with template details
router.get('/recommendations/with-details', async (req, res) => {
  try {
    const limit = parseInt(req.query.limit) || 50;
    const offset = parseInt(req.query.offset) || 0;
    
    console.log(`📊 [TechStack] Fetching recommendations with template details (limit: ${limit}, offset: ${offset})`);
    
    const recommendations = await TechStackRecommendation.getWithTemplateDetails(limit, offset);
    
    res.json({
      success: true,
      data: recommendations,
      count: recommendations.length,
      message: `Found ${recommendations.length} recommendations with template details`
    });
  } catch (error) {
    console.error('❌ Error fetching recommendations with details:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to fetch recommendations with details',
      message: error.message
    });
  }
});

// GET /api/tech-stack/recommendations/:templateId - Get recommendation for specific template
router.get('/recommendations/:templateId', async (req, res) => {
  try {
    const { templateId } = req.params;
    const templateType = req.query.templateType || null;
    
    console.log(`🔍 [TechStack] Fetching recommendation for template: ${templateId} (type: ${templateType || 'any'})`);
    
    const recommendation = await TechStackRecommendation.getByTemplateId(templateId, templateType);
    
    if (!recommendation) {
      return res.status(404).json({
        success: false,
        error: 'Recommendation not found',
        message: `No tech stack recommendation found for template ${templateId}`
      });
    }
    
    res.json({
      success: true,
      data: recommendation,
      message: `Tech stack recommendation found for template ${templateId}`
    });
  } catch (error) {
    console.error('❌ Error fetching recommendation:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to fetch recommendation',
      message: error.message
    });
  }
});

// POST /api/tech-stack/analyze/:templateId - Analyze specific template
router.post('/analyze/:templateId', async (req, res) => {
  try {
    const { templateId } = req.params;
    const forceUpdate = req.query.force === 'true';
    
    console.log(`🤖 [TechStack] Starting analysis for template: ${templateId} (force: ${forceUpdate})`);
    
    // Check if recommendation already exists
    if (!forceUpdate) {
      const existing = await TechStackRecommendation.getByTemplateId(templateId);
      if (existing) {
        return res.json({
          success: true,
          data: existing,
          message: `Recommendation already exists for template ${templateId}. Use ?force=true to update.`,
          cached: true
        });
      }
    }
    
    // Fetch template with features and business rules
    const templateData = await fetchTemplateWithFeatures(templateId);
    if (!templateData) {
      return res.status(404).json({
        success: false,
        error: 'Template not found',
        message: `Template with ID ${templateId} does not exist`
      });
    }
    
    // Analyze template
    const analysisResult = await analyzer.analyzeTemplate(templateData);
    
    // Save recommendation
    const recommendation = await TechStackRecommendation.upsert(
      templateId,
      templateData.is_custom ? 'custom' : 'default',
      analysisResult
    );
    
    res.json({
      success: true,
      data: recommendation,
      message: `Tech stack analysis completed for template ${templateData.title}`,
      cached: false
    });
    
  } catch (error) {
    console.error('❌ Error analyzing template:', error.message);
    res.status(500).json({
      success: false,
      error: 'Analysis failed',
      message: error.message
    });
  }
});

// POST /api/tech-stack/analyze/batch - Batch analyze all templates
router.post('/analyze/batch', async (req, res) => {
  try {
    const { 
      forceUpdate = false, 
      templateIds = null, 
      includeCustom = true,
      includeDefault = true 
    } = req.body;
    
    console.log(`🚀 [TechStack] Starting batch analysis (force: ${forceUpdate}, custom: ${includeCustom}, default: ${includeDefault})`);
    
    // Fetch all templates with features
    const templates = await fetchAllTemplatesWithFeatures(includeCustom, includeDefault, templateIds);
    
    if (templates.length === 0) {
      return res.json({
        success: true,
        data: [],
        message: 'No templates found for analysis',
        summary: { total: 0, processed: 0, failed: 0 }
      });
    }
    
    console.log(`📊 [TechStack] Found ${templates.length} templates for analysis`);
    
    // Filter out templates that already have recommendations (unless force update)
    let templatesToAnalyze = templates;
    if (!forceUpdate) {
      const existingRecommendations = await Promise.all(
        templates.map(t => TechStackRecommendation.getByTemplateId(t.id))
      );
      
      templatesToAnalyze = templates.filter((template, index) => !existingRecommendations[index]);
      console.log(`📊 [TechStack] ${templates.length - templatesToAnalyze.length} templates already have recommendations`);
    }
    
    if (templatesToAnalyze.length === 0) {
      return res.json({
        success: true,
        data: [],
        message: 'All templates already have recommendations. Use forceUpdate=true to re-analyze.',
        summary: { total: templates.length, processed: 0, failed: 0, skipped: templates.length }
      });
    }
    
    // Start batch analysis
    const results = await analyzer.batchAnalyze(templatesToAnalyze, (current, total, title, status) => {
      console.log(`📈 [TechStack] Progress: ${current}/${total} - ${title} (${status})`);
    });
    
    // Save all results
    const savedRecommendations = [];
    const failedRecommendations = [];
    
    for (const result of results) {
      try {
        const recommendation = await TechStackRecommendation.upsert(
          result.template_id,
          result.template_type,
          result
        );
        savedRecommendations.push(recommendation);
      } catch (saveError) {
        console.error(`❌ Failed to save recommendation for ${result.template_id}:`, saveError.message);
        failedRecommendations.push({
          template_id: result.template_id,
          error: saveError.message
        });
      }
    }
    
    const summary = {
      total: templates.length,
      processed: templatesToAnalyze.length,
      successful: savedRecommendations.length,
      failed: failedRecommendations.length,
      skipped: templates.length - templatesToAnalyze.length
    };
    
    res.json({
      success: true,
      data: savedRecommendations,
      failed: failedRecommendations,
      summary,
      message: `Batch analysis completed: ${summary.successful} successful, ${summary.failed} failed, ${summary.skipped} skipped`
    });
    
  } catch (error) {
    console.error('❌ Error in batch analysis:', error.message);
    res.status(500).json({
      success: false,
      error: 'Batch analysis failed',
      message: error.message
    });
  }
});

// GET /api/tech-stack/stats - Get statistics
router.get('/stats', async (req, res) => {
  try {
    console.log('📊 [TechStack] Fetching statistics...');
    
    const stats = await TechStackRecommendation.getStats();
    
    res.json({
      success: true,
      data: stats,
      message: 'Tech stack statistics retrieved successfully'
    });
  } catch (error) {
    console.error('❌ Error fetching stats:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to fetch statistics',
      message: error.message
    });
  }
});

// GET /api/tech-stack/stale - Get recommendations that need updating
router.get('/stale', async (req, res) => {
  try {
    const daysOld = parseInt(req.query.days) || 30;
    const limit = parseInt(req.query.limit) || 100;
    
    console.log(`📊 [TechStack] Fetching stale recommendations (older than ${daysOld} days, limit: ${limit})`);
    
    const staleRecommendations = await TechStackRecommendation.getStaleRecommendations(daysOld, limit);
    
    res.json({
      success: true,
      data: staleRecommendations,
      count: staleRecommendations.length,
      message: `Found ${staleRecommendations.length} recommendations older than ${daysOld} days`
    });
  } catch (error) {
    console.error('❌ Error fetching stale recommendations:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to fetch stale recommendations',
      message: error.message
    });
  }
});

// DELETE /api/tech-stack/recommendations/:id - Delete recommendation
router.delete('/recommendations/:id', async (req, res) => {
  try {
    const { id } = req.params;
    
    console.log(`🗑️ [TechStack] Deleting recommendation: ${id}`);
    
    const deleted = await TechStackRecommendation.delete(id);
    
    if (!deleted) {
      return res.status(404).json({
        success: false,
        error: 'Recommendation not found',
        message: `Recommendation with ID ${id} does not exist`
      });
    }
    
    res.json({
      success: true,
      message: `Recommendation ${id} deleted successfully`
    });
  } catch (error) {
    console.error('❌ Error deleting recommendation:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to delete recommendation',
      message: error.message
    });
  }
});

// POST /api/tech-stack/auto-analyze/all - Automatically analyze all templates without recommendations
router.post('/auto-analyze/all', async (req, res) => {
  try {
    console.log('🤖 [TechStack] 🚀 Starting auto-analysis for all templates without recommendations...');
    
    const result = await autoTechStackAnalyzer.analyzeAllPendingTemplates();
    
    res.json({
      success: true,
      data: result,
      message: result.message
    });
  } catch (error) {
    console.error('❌ Error in auto-analysis:', error.message);
    res.status(500).json({
      success: false,
      error: 'Auto-analysis failed',
      message: error.message
    });
  }
});

// POST /api/tech-stack/auto-analyze/force-all - Force analyze ALL templates regardless of existing recommendations
router.post('/auto-analyze/force-all', async (req, res) => {
  try {
    console.log('🤖 [TechStack] 🚀 Starting FORCE analysis for ALL templates...');
    
    const result = await autoTechStackAnalyzer.analyzeAllTemplates(true);
    
    res.json({
      success: true,
      data: result,
      message: result.message
    });
  } catch (error) {
    console.error('❌ Error in force auto-analysis:', error.message);
    res.status(500).json({
      success: false,
      error: 'Force auto-analysis failed',
      message: error.message
    });
  }
});

// POST /api/tech-stack/analyze-existing - Analyze all existing templates in database (including those with old recommendations)
router.post('/analyze-existing', async (req, res) => {
  try {
    const { forceUpdate = false, daysOld = 30 } = req.body;
    
    console.log(`🤖 [TechStack] 🔍 Starting analysis of existing templates (force: ${forceUpdate}, daysOld: ${daysOld})...`);
    
    // Get all templates from database
    const allTemplates = await fetchAllTemplatesWithFeatures(true, true);
    console.log(`📊 [TechStack] 📊 Found ${allTemplates.length} total templates in database`);
    
    if (allTemplates.length === 0) {
      return res.json({
        success: true,
        data: { total: 0, queued: 0, skipped: 0 },
        message: 'No templates found in database'
      });
    }
    
    let queuedCount = 0;
    let skippedCount = 0;
    
    // Process each template
    for (const template of allTemplates) {
      const templateType = template.is_custom ? 'custom' : 'default';
      
      if (!forceUpdate) {
        // Check if recommendation exists and is recent
        const existing = await TechStackRecommendation.getByTemplateId(template.id, templateType);
        if (existing && autoTechStackAnalyzer.isRecentRecommendation(existing, daysOld)) {
          console.log(`⏭️ [TechStack] ⏸️ Skipping ${template.title} - recent recommendation exists`);
          skippedCount++;
          continue;
        }
      }
      
      // Queue for analysis
      console.log(`📝 [TechStack] 📝 Queuing existing template: ${template.title} (${templateType})`);
      autoTechStackAnalyzer.queueForAnalysis(template.id, templateType, 2); // Normal priority
      queuedCount++;
    }
    
    const result = {
      total: allTemplates.length,
      queued: queuedCount,
      skipped: skippedCount,
      forceUpdate
    };
    
    console.log(`✅ [TechStack] ✅ Existing templates analysis queued: ${queuedCount} queued, ${skippedCount} skipped`);
    
    res.json({
      success: true,
      data: result,
      message: `Queued ${queuedCount} existing templates for analysis (${skippedCount} skipped)`
    });
    
  } catch (error) {
    console.error('❌ Error analyzing existing templates:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to analyze existing templates',
      message: error.message
    });
  }
});

// GET /api/tech-stack/auto-analyze/queue - Get automation queue status
router.get('/auto-analyze/queue', async (req, res) => {
  try {
    const queueStatus = autoTechStackAnalyzer.getQueueStatus();
    
    res.json({
      success: true,
      data: queueStatus,
      message: `Queue status: ${queueStatus.isProcessing ? 'processing' : 'idle'}, ${queueStatus.queueLength} items queued`
    });
  } catch (error) {
    console.error('❌ Error getting queue status:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to get queue status',
      message: error.message
    });
  }
});

// POST /api/tech-stack/auto-analyze/queue/clear - Clear the processing queue
router.post('/auto-analyze/queue/clear', async (req, res) => {
  try {
    const clearedCount = autoTechStackAnalyzer.clearQueue();
    
    res.json({
      success: true,
      data: { clearedCount },
      message: `Cleared ${clearedCount} items from processing queue`
    });
  } catch (error) {
    console.error('❌ Error clearing queue:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to clear queue',
      message: error.message
    });
  }
});

// POST /api/tech-stack/auto-analyze/trigger/:templateId - Manually trigger auto-analysis for specific template
router.post('/auto-analyze/trigger/:templateId', async (req, res) => {
  try {
    const { templateId } = req.params;
    const { templateType = null, priority = 1 } = req.body;
    
    console.log(`🤖 [TechStack] Manually triggering auto-analysis for template: ${templateId}`);
    
    // Queue for analysis
    autoTechStackAnalyzer.queueForAnalysis(templateId, templateType, priority);
    
    res.json({
      success: true,
      data: { templateId, templateType, priority },
      message: `Template ${templateId} queued for auto-analysis with priority ${priority}`
    });
  } catch (error) {
    console.error('❌ Error triggering auto-analysis:', error.message);
    res.status(500).json({
      success: false,
      error: 'Failed to trigger auto-analysis',
      message: error.message
    });
  }
});

// Helper function to fetch template with features and business rules
async function fetchTemplateWithFeatures(templateId) {
  try {
    // Check if template exists in default templates
    let template = await Template.getByIdWithFeatures(templateId);
    let isCustom = false;
    
    if (!template) {
      // Check custom templates
      template = await CustomTemplate.getByIdWithFeatures(templateId);
      isCustom = true;
    }
    
    if (!template) {
      return null;
    }
    
    // Get features and business rules
    const features = await Feature.getByTemplateId(templateId);
    
    // Extract business rules
    const businessRules = {};
    features.forEach(feature => {
      if (feature.additional_business_rules) {
        businessRules[feature.id] = feature.additional_business_rules;
      }
    });
    
    return {
      ...template,
      features,
      business_rules: businessRules,
      feature_count: features.length,
      is_custom: isCustom
    };
    
  } catch (error) {
    console.error('❌ Error fetching template with features:', error.message);
    throw error;
  }
}

// Helper function to fetch all templates with features
async function fetchAllTemplatesWithFeatures(includeCustom = true, includeDefault = true, templateIds = null) {
  try {
    const templates = [];
    
    if (includeDefault) {
      const defaultTemplates = await Template.getAllByCategory();
      const defaultTemplatesFlat = Object.values(defaultTemplates).flat();
      templates.push(...defaultTemplatesFlat);
    }
    
    if (includeCustom) {
      const customTemplates = await CustomTemplate.getAll(1000, 0);
      templates.push(...customTemplates);
    }
    
    // Filter by template IDs if provided
    let filteredTemplates = templates;
    if (templateIds && Array.isArray(templateIds)) {
      filteredTemplates = templates.filter(t => templateIds.includes(t.id));
    }
    
    // Fetch features for each template
    const templatesWithFeatures = await Promise.all(
      filteredTemplates.map(async (template) => {
        try {
          const features = await Feature.getByTemplateId(template.id);
          
          // Extract business rules
          const businessRules = {};
          features.forEach(feature => {
            if (feature.additional_business_rules) {
              businessRules[feature.id] = feature.additional_business_rules;
            }
          });
          
          return {
            ...template,
            features,
            business_rules: businessRules,
            feature_count: features.length,
            is_custom: !template.is_active
          };
        } catch (error) {
          console.error(`⚠️ Error fetching features for template ${template.id}:`, error.message);
          return {
            ...template,
            features: [],
            business_rules: {},
            feature_count: 0,
            is_custom: !template.is_active,
            error: error.message
          };
        }
      })
    );
    
    return templatesWithFeatures;
    
  } catch (error) {
    console.error('❌ Error fetching all templates with features:', error.message);
    throw error;
  }
}

module.exports = router;
