const _ = require('lodash');
const Anthropic = require('@anthropic-ai/sdk');
const database = require('../config/database');
const UserAuthClient = require('../clients/user-auth-client');

/**
 * Unified Tech Stack Service
 * Combines recommendations from template-manager, tech-stack-selector services, and Claude AI
 * Now includes database persistence for user-specific recommendations and user authentication
 */
class UnifiedTechStackService {
  constructor(templateManagerClient, techStackSelectorClient) {
    this.templateManagerClient = templateManagerClient;
    this.techStackSelectorClient = techStackSelectorClient;
    this.userAuthClient = new UserAuthClient();
    this.database = database;
    
    // Initialize Claude AI client
    const claudeApiKey = process.env.CLAUDE_API_KEY || process.env.ANTHROPIC_API_KEY;
    this.claudeApiKey = claudeApiKey;
    
    if (claudeApiKey) {
      this.claudeClient = new Anthropic({
        apiKey: claudeApiKey,
      });
      console.log('✅ Claude AI client initialized successfully');
    } else {
      this.claudeClient = null;
      console.warn('⚠️  Claude AI client not initialized - API key missing');
    }
  }

  /**
   * Get Claude AI recommendations based on template, features, and business context
   */
  async getClaudeRecommendations(request) {
    try {
      console.log('🤖 Generating Claude AI recommendations...');
      console.log('📊 Request data:', {
        template: request.template?.title,
        featuresCount: request.features?.length,
        businessQuestionsCount: request.businessContext?.questions?.length,
      });

      // Check if Claude client is available
      if (!this.claudeClient) {
        console.warn('⚠️  Claude AI client not available - using fallback recommendations');
        return {
          success: false,
          error: 'Claude API key not configured',
          source: 'claude-ai',
          type: 'ai-powered',
          data: {
            claude_recommendations: this.getFallbackRecommendations(),
            functional_requirements: this.getFallbackFunctionalRequirements(request),
          }
        };
      }

      // Build comprehensive prompt for Claude
      const prompt = this.buildTechRecommendationPrompt(request);

      // Call Claude API
      const response = await this.claudeClient.messages.create({
        model: 'claude-3-5-sonnet-20241022',
        max_tokens: 4000,
        temperature: 0.7,
        messages: [
          {
            role: 'user',
            content: prompt,
          },
        ],
      });

      // Parse Claude's response
      const claudeResponse = response.content[0];
      if (claudeResponse.type !== 'text') {
        throw new Error('Unexpected response type from Claude');
      }

      const recommendations = this.parseClaudeResponse(claudeResponse.text, request);

      console.log('✅ Claude recommendations generated successfully');
      return {
        success: true,
        data: recommendations,
        source: 'claude-ai',
        type: 'ai-powered'
      };

    } catch (error) {
      console.error('❌ Error generating Claude recommendations:', error);
      return {
        success: false,
        error: error.message,
        source: 'claude-ai',
        type: 'ai-powered',
        data: {
          claude_recommendations: this.getFallbackRecommendations(),
          functional_requirements: this.getFallbackFunctionalRequirements(request),
        }
      };
    }
  }

  /**
   * Build comprehensive prompt for Claude AI
   */
  buildTechRecommendationPrompt(request) {
    const { template, features, businessContext, projectName, projectType } = request;

    // Extract feature information
    const featureNames = features.map(f => f.name).join(', ');
    const featureDescriptions = features.map(f => `- ${f.name}: ${f.description}`).join('\n');
    const complexityLevels = features.map(f => f.complexity);
    const hasHighComplexity = complexityLevels.includes('high');
    const hasMediumComplexity = complexityLevels.includes('medium');

    // Extract business context
    const businessAnswers = businessContext.questions
      .map(qa => `Q: ${qa.question}\nA: ${qa.answer}`)
      .join('\n\n');

    return `You are an expert technology architect and consultant. Analyze the following project requirements and provide comprehensive technology recommendations.

PROJECT OVERVIEW:
- Project Name: ${projectName || template.title}
- Project Type: ${projectType || template.category}
- Template: ${template.title} - ${template.description}

SELECTED FEATURES (${features.length} total):
${featureDescriptions}

COMPLEXITY ANALYSIS:
- High complexity features: ${hasHighComplexity ? 'Yes' : 'No'}
- Medium complexity features: ${hasMediumComplexity ? 'Yes' : 'No'}
- Overall complexity: ${hasHighComplexity ? 'High' : hasMediumComplexity ? 'Medium' : 'Low'}

BUSINESS CONTEXT:
${businessAnswers}

Please provide a comprehensive technology recommendation in the following JSON format:

{
  "technology_recommendations": {
    "frontend": {
      "framework": "Recommended frontend framework",
      "libraries": ["library1", "library2"],
      "reasoning": "Detailed explanation for frontend choice"
    },
    "backend": {
      "language": "Recommended backend language",
      "framework": "Recommended backend framework", 
      "libraries": ["library1", "library2"],
      "reasoning": "Detailed explanation for backend choice"
    },
    "database": {
      "primary": "Primary database recommendation",
      "secondary": ["secondary1", "secondary2"],
      "reasoning": "Detailed explanation for database choice"
    },
    "mobile": {
      "framework": "Recommended mobile framework (if applicable)",
      "libraries": ["library1", "library2"],
      "reasoning": "Detailed explanation for mobile choice"
    },
    "devops": {
      "tools": ["tool1", "tool2"],
      "platforms": ["platform1", "platform2"],
      "reasoning": "Detailed explanation for DevOps choices"
    },
    "tools": {
      "development": ["dev_tool1", "dev_tool2"],
      "monitoring": ["monitoring_tool1", "monitoring_tool2"],
      "reasoning": "Detailed explanation for tool choices"
    },
    "ai_ml": {
      "frameworks": ["framework1", "framework2"],
      "libraries": ["library1", "library2"],
      "reasoning": "Detailed explanation for AI/ML choices"
    }
  },
  "implementation_strategy": {
    "architecture_pattern": "Recommended architecture pattern (e.g., MVC, Microservices, etc.)",
    "deployment_strategy": "Recommended deployment approach",
    "scalability_approach": "How to handle scaling"
  },
  "business_alignment": {
    "scalability": "How the tech stack supports scalability",
    "maintainability": "How the tech stack supports maintainability", 
    "cost_effectiveness": "Cost considerations and optimization",
    "time_to_market": "How the tech stack affects development speed"
  },
  "risk_assessment": {
    "technical_risks": ["risk1", "risk2"],
    "mitigation_strategies": ["strategy1", "strategy2"]
  }
}

CONSIDERATIONS:
1. Choose technologies that work well together
2. Consider the complexity level of features
3. Factor in business requirements from the context
4. Prioritize scalability and maintainability
5. Consider developer experience and community support
6. Balance performance with development speed
7. Include modern, actively maintained technologies

Provide only the JSON response, no additional text.`;
  }

  /**
   * Parse Claude's response and structure it properly
   */
  parseClaudeResponse(responseText, request) {
    try {
      // Extract JSON from response (handle cases where Claude adds extra text)
      const jsonMatch = responseText.match(/\{[\s\S]*\}/);
      if (!jsonMatch) {
        throw new Error('No JSON found in Claude response');
      }

      const parsed = JSON.parse(jsonMatch[0]);
      
      // Validate required fields
      if (!parsed.technology_recommendations) {
        throw new Error('Missing technology_recommendations in response');
      }

      // Build functional requirements from the request
      const functionalRequirements = {
        feature_name: `${request.template.title} - Integrated System`,
        description: `Complete ${request.template.category} system with ${request.features.length} integrated features`,
        complexity_level: request.features.some(f => f.complexity === 'high') ? 'high' :
          request.features.some(f => f.complexity === 'medium') ? 'medium' : 'low',
        technical_requirements: request.features.flatMap(f => f.technical_requirements || []),
        business_logic_rules: request.features.flatMap(f => f.business_rules || []),
        all_features: request.features.map(f => f.name),
      };

      return {
        claude_recommendations: parsed,
        functional_requirements: functionalRequirements,
      };
    } catch (error) {
      console.error('Error parsing Claude response:', error);
      throw new Error('Failed to parse Claude response');
    }
  }

  /**
   * Fallback recommendations when Claude API fails
   */
  getFallbackRecommendations() {
    return {
      technology_recommendations: {
        frontend: {
          framework: 'React',
          libraries: ['TypeScript', 'Tailwind CSS', 'React Router'],
          reasoning: 'React provides excellent component reusability and ecosystem support for modern web applications.',
        },
        backend: {
          language: 'Node.js',
          framework: 'Express.js',
          libraries: ['TypeScript', 'Prisma', 'JWT'],
          reasoning: 'Node.js offers great performance and JavaScript ecosystem consistency between frontend and backend.',
        },
        database: {
          primary: 'PostgreSQL',
          secondary: ['Redis'],
          reasoning: 'PostgreSQL provides robust ACID compliance and excellent performance for complex applications.',
        },
        mobile: {
          framework: 'React Native',
          libraries: ['Expo', 'React Navigation', 'AsyncStorage'],
          reasoning: 'React Native enables cross-platform mobile development with shared codebase and native performance.',
        },
        devops: {
          tools: ['Docker', 'GitHub Actions', 'Kubernetes'],
          platforms: ['AWS', 'Vercel'],
          reasoning: 'Modern DevOps stack for containerization, CI/CD, and cloud deployment with excellent scalability.',
        },
        tools: {
          development: ['VS Code', 'Git', 'ESLint', 'Prettier'],
          monitoring: ['Sentry', 'LogRocket', 'New Relic'],
          reasoning: 'Essential development tools for code quality and comprehensive monitoring for production applications.',
        },
        ai_ml: {
          frameworks: ['TensorFlow.js', 'OpenAI API'],
          libraries: ['NumPy', 'Pandas', 'Scikit-learn'],
          reasoning: 'AI/ML capabilities for data analysis, machine learning, and integration with modern AI services.',
        },
      },
      implementation_strategy: {
        architecture_pattern: 'MVC (Model-View-Controller)',
        deployment_strategy: 'Containerized deployment with Docker',
        scalability_approach: 'Horizontal scaling with load balancing',
      },
      business_alignment: {
        scalability: 'Designed for horizontal scaling with microservices architecture',
        maintainability: 'Modular architecture with clear separation of concerns',
        cost_effectiveness: 'Open-source technologies reduce licensing costs',
        time_to_market: 'Rapid development with modern frameworks and tools',
      },
      risk_assessment: {
        technical_risks: ['Learning curve for new technologies', 'Integration complexity'],
        mitigation_strategies: ['Comprehensive documentation', 'Phased implementation approach'],
      },
    };
  }

  /**
   * Fallback functional requirements when Claude API fails
   */
  getFallbackFunctionalRequirements(request) {
    return {
      feature_name: `${request.template.title} - Integrated System`,
      description: `Complete ${request.template.category} system with ${request.features.length} integrated features`,
      complexity_level: request.features.some(f => f.complexity === 'high') ? 'high' :
        request.features.some(f => f.complexity === 'medium') ? 'medium' : 'low',
      technical_requirements: request.features.flatMap(f => f.technical_requirements || []),
      business_logic_rules: request.features.flatMap(f => f.business_rules || []),
      all_features: request.features.map(f => f.name),
    };
  }

  /**
   * Get comprehensive recommendations including Claude AI, template-based, and domain-based
   */
  async getComprehensiveRecommendations(request) {
    const {
      template,
      features,
      businessContext,
      projectName,
      projectType,
      templateId,
      budget,
      domain,
      preferences = {},
      includeClaude = true,
      includeTemplateBased = true,
      includeDomainBased = true,
      userId = null,
      sessionId = null,
      saveToDatabase = true,
      useCache = true
    } = request;

    console.log('🔄 Generating comprehensive recommendations...');
    console.log(`👤 User ID: ${userId || 'anonymous'}`);
    console.log(`💾 Save to database: ${saveToDatabase}`);
    console.log(`🗄️ Use cache: ${useCache}`);

    // Try to get cached recommendations first
    if (useCache && templateId) {
      console.log('🔍 Checking for cached recommendations...');
      const cachedResult = await this.database.getRecommendations(templateId, userId, sessionId);
      if (cachedResult.success) {
        console.log('✅ Found cached recommendations, returning cached data');
        
        // Reconstruct the full response structure from cached data
        const cachedData = cachedResult.data;
        const responseData = {
          // Include the extracted tech stack categories
          frontend: cachedData.frontend,
          backend: cachedData.backend,
          mobile: cachedData.mobile,
          testing: cachedData.testing,
          ai_ml: cachedData.ai_ml,
          devops: cachedData.devops,
          cloud: cachedData.cloud,
          tools: cachedData.tools,
          
          // Include metadata
          id: cachedData.id,
          templateId: cachedData.templateId,
          userId: cachedData.userId,
          sessionId: cachedData.sessionId,
          recommendationType: cachedData.recommendationType,
          createdAt: cachedData.createdAt,
          lastAnalyzedAt: cachedData.lastAnalyzedAt,
          
          // Include the full unified data structure
          unifiedData: cachedData.unifiedData,
          
          // Reconstruct the claude data structure for frontend compatibility
          claude: cachedData.unifiedData?.claudeRecommendations ? {
            success: true,
            data: cachedData.unifiedData.claudeRecommendations
          } : null,
          
          // Reconstruct template-based data
          templateBased: cachedData.unifiedData?.templateRecommendations ? {
            success: true,
            data: cachedData.unifiedData.templateRecommendations
          } : null,
          
          // Reconstruct domain-based data
          domainBased: cachedData.unifiedData?.domainRecommendations ? {
            success: true,
            data: cachedData.unifiedData.domainRecommendations
          } : null,
          
          // Include confidence scores and reasoning
          confidenceScores: cachedData.confidenceScores,
          reasoning: cachedData.reasoning,
          
          // Cache metadata
          cached: true,
          cacheSource: cachedData.recommendationType
        };
        
        return {
          success: true,
          data: responseData,
          metadata: {
            templateId,
            budget,
            domain,
            featuresCount: features.length,
            timestamp: new Date().toISOString(),
            cached: true
          }
        };
      }
    }

    const results = {
      claude: null,
      templateBased: null,
      domainBased: null,
      unified: null,
      analysis: null
    };

    // Get Claude AI recommendations
    if (includeClaude) {
      console.log('🤖 Getting Claude AI recommendations...');
      results.claude = await this.getClaudeRecommendations({
        template,
        features,
        businessContext,
        projectName,
        projectType
      });
    }

    // Get template-based recommendations
    if (includeTemplateBased && templateId) {
      console.log('📊 Getting template-based recommendations...');
      results.templateBased = await this.getTemplateBasedRecommendations({
        templateId,
        recommendationType: 'both'
      });
    }

    // Get domain-based recommendations
    if (includeDomainBased && budget && domain) {
      console.log('🏢 Getting domain-based recommendations...');
      results.domainBased = await this.getDomainBasedRecommendations({
        budget,
        domain,
        features: features.map(f => f.name)
      });
    }

    // Generate unified recommendations
    console.log('🔗 Generating unified recommendations...');
    results.unified = this.generateComprehensiveRecommendations(results, preferences);

    // Perform analysis
    console.log('📈 Analyzing recommendations...');
    results.analysis = this.analyzeComprehensiveRecommendations(results);

    // Save to database if requested
    if (saveToDatabase && templateId) {
      console.log('💾 Saving recommendations to database...');
      const saveResult = await this.saveRecommendationsToDatabase({
        templateId,
        userId,
        sessionId,
        template,
        features,
        businessContext,
        unifiedData: results.unified,
        claudeData: results.claude,
        templateBasedData: results.templateBased,
        domainBasedData: results.domainBased,
        analysisData: results.analysis,
        expiresAt: userId ? null : new Date(Date.now() + 24 * 60 * 60 * 1000) // 24 hours for session-based
      });

      if (saveResult.success) {
        console.log('✅ Recommendations saved to database:', saveResult.data.id);
      } else {
        console.log('⚠️ Failed to save recommendations to database:', saveResult.error);
      }
    }

    return {
      success: true,
      data: results,
      metadata: {
        templateId,
        budget,
        domain,
        featuresCount: features.length,
        timestamp: new Date().toISOString(),
        cached: false
      }
    };
  }

  /**
   * Generate comprehensive recommendations by combining all sources
   */
  generateComprehensiveRecommendations(results, preferences = {}) {
    console.log('🔥 generateComprehensiveRecommendations CALLED');
    const unified = {
      techStacks: [],
      technologies: [],
      recommendations: [],
      confidence: 0,
      approach: 'comprehensive',
      claudeRecommendations: null,
      templateRecommendations: null,
      domainRecommendations: null
    };

    // Extract Claude recommendations
    if (results.claude?.success) {
      console.log('🔥 Extracting Claude recommendations');
      unified.claudeRecommendations = results.claude.data;
      // Also extract tech stacks from Claude recommendations
      const claudeTechStacks = this.extractTechStacksFromClaude(results.claude.data);
      console.log('🔥 Claude techStacks extracted:', claudeTechStacks.length);
      unified.techStacks.push(...claudeTechStacks);
    }

    // Extract tech stacks from template-based recommendations
    if (results.templateBased?.success) {
      console.log('🔥 Extracting template recommendations');
      const templateTechStacks = this.extractTechStacksFromTemplate(results.templateBased.data);
      console.log('🔥 Template techStacks extracted:', templateTechStacks.length);
      unified.techStacks.push(...templateTechStacks);
      unified.templateRecommendations = results.templateBased.data;
    }

    // Extract tech stacks from domain-based recommendations
    if (results.domainBased?.success) {
      console.log('🔥 Extracting domain recommendations');
      const domainTechStacks = this.extractTechStacksFromDomain(results.domainBased.data);
      console.log('🔥 Domain techStacks extracted:', domainTechStacks.length);
      unified.techStacks.push(...domainTechStacks);
      unified.domainRecommendations = results.domainBased.data;
    }

    console.log('🔥 Total techStacks:', unified.techStacks.length);

    // Merge and deduplicate technologies
    console.log('🔥 Merging technologies');
    unified.technologies = this.mergeTechnologies(unified.techStacks);
    console.log('🔥 Technologies merged:', unified.technologies.length);

    // Generate unified recommendations
    console.log('🔥 Generating recommendations list');
    unified.recommendations = this.generateUnifiedRecommendationList(unified.techStacks, preferences);
    console.log('🔥 Recommendations generated:', unified.recommendations.length);

    // Calculate overall confidence
    console.log('🔥 Calculating confidence');
    unified.confidence = this.calculateComprehensiveConfidence(results);
    console.log('🔥 Confidence calculated:', unified.confidence);

    // Determine best approach
    console.log('🔥 Determining approach');
    unified.approach = this.determineComprehensiveApproach(results);
    console.log('🔥 Approach determined:', unified.approach);

    console.log('🔥 generateComprehensiveRecommendations RETURNING');
    return unified;
  }

  /**
   * Calculate comprehensive confidence score
   */
  calculateComprehensiveConfidence(results) {
    let confidence = 0;
    let sources = 0;

    if (results.claude?.success) {
      confidence += 0.5; // Claude gets highest weight
      sources++;
    }

    if (results.templateBased?.success) {
      confidence += 0.3; // Template-based gets medium weight
      sources++;
    }

    if (results.domainBased?.success) {
      confidence += 0.2; // Domain-based gets lower weight
      sources++;
    }

    return sources > 0 ? confidence / sources : 0;
  }

  /**
   * Determine best approach based on available data
   */
  determineComprehensiveApproach(results) {
    const approaches = [];
    
    if (results.claude?.success) approaches.push('claude-ai');
    if (results.templateBased?.success) approaches.push('template-based');
    if (results.domainBased?.success) approaches.push('domain-based');

    if (approaches.length === 3) return 'comprehensive';
    if (approaches.length === 2) return approaches.join('-');
    if (approaches.length === 1) return approaches[0];
    return 'none';
  }

  /**
   * Analyze comprehensive recommendations from all services
   */
  analyzeComprehensiveRecommendations(results) {
    const analysis = {
      claude: {
        status: results.claude?.success ? 'success' : 'failed',
        dataAvailable: results.claude?.success,
        hasRecommendations: !!results.claude?.data?.claude_recommendations,
        hasFunctionalRequirements: !!results.claude?.data?.functional_requirements
      },
      templateManager: {
        status: results.templateBased?.success ? 'success' : 'failed',
        dataAvailable: results.templateBased?.success,
        permutationsCount: 0,
        combinationsCount: 0,
        techStacksCount: 0
      },
      techStackSelector: {
        status: results.domainBased?.success ? 'success' : 'failed',
        dataAvailable: results.domainBased?.success,
        recommendationsCount: 0,
        avgConfidence: 0
      },
      comparison: {
        overlap: 0,
        uniqueTechnologies: 0,
        recommendationQuality: 'unknown',
        comprehensiveScore: 0
      }
    };

    // Analyze Claude data
    if (results.claude?.success) {
      analysis.claude.hasRecommendations = !!results.claude.data?.claude_recommendations;
      analysis.claude.hasFunctionalRequirements = !!results.claude.data?.functional_requirements;
    }

    // Analyze template manager data
    if (results.templateBased?.success) {
      const data = results.templateBased.data;
      if (data.permutations?.success) {
        analysis.templateManager.permutationsCount = data.permutations.data?.data?.total_permutations || 0;
      }
      if (data.combinations?.success) {
        analysis.templateManager.combinationsCount = data.combinations.data?.data?.total_combinations || 0;
      }
      analysis.templateManager.techStacksCount = analysis.templateManager.permutationsCount + analysis.templateManager.combinationsCount;
    }

    // Analyze tech stack selector data
    if (results.domainBased?.success) {
      const data = results.domainBased.data;
      analysis.techStackSelector.recommendationsCount = data.data?.recommendations?.length || 0;
      analysis.techStackSelector.avgConfidence = _.meanBy(data.data?.recommendations || [], 'confidence') || 0;
    }

    // Calculate comprehensive score
    const claudeScore = analysis.claude.dataAvailable ? 1 : 0;
    const templateScore = analysis.templateManager.dataAvailable ? 1 : 0;
    const domainScore = analysis.techStackSelector.dataAvailable ? 1 : 0;
    analysis.comparison.comprehensiveScore = (claudeScore + templateScore + domainScore) / 3;

    // Assess recommendation quality
    if (analysis.comparison.comprehensiveScore >= 0.8) {
      analysis.comparison.recommendationQuality = 'excellent';
    } else if (analysis.comparison.comprehensiveScore >= 0.6) {
      analysis.comparison.recommendationQuality = 'good';
    } else if (analysis.comparison.comprehensiveScore >= 0.3) {
      analysis.comparison.recommendationQuality = 'fair';
    } else {
      analysis.comparison.recommendationQuality = 'poor';
    }

    return analysis;
  }

  /**
   * Get unified recommendations combining both services
   */
  async getUnifiedRecommendations(options) {
    const {
      templateId,
      budget,
      domain,
      features = [],
      preferences = {},
      includePermutations = true,
      includeCombinations = true,
      includeDomainRecommendations = true
    } = options;

    console.log('🔄 Generating unified recommendations...');

    const results = {
      templateBased: null,
      domainBased: null,
      unified: null,
      analysis: null
    };

    // Get template-based recommendations
    if (templateId && (includePermutations || includeCombinations)) {
      console.log('📊 Getting template-based recommendations...');
      results.templateBased = await this.getTemplateBasedRecommendations({
        templateId,
        recommendationType: 'both'
      });
    }

    // Get domain-based recommendations
    if (budget && domain && includeDomainRecommendations) {
      console.log('🏢 Getting domain-based recommendations...');
      results.domainBased = await this.getDomainBasedRecommendations({
        budget,
        domain,
        features
      });
    }

    // Generate unified recommendations
    console.log('🔗 Generating unified recommendations...');
    results.unified = this.generateUnifiedRecommendations(results.templateBased, results.domainBased, preferences);

    // Perform analysis
    console.log('📈 Analyzing recommendations...');
    results.analysis = this.analyzeRecommendations(results.templateBased, results.domainBased);

    return {
      success: true,
      data: results,
      metadata: {
        templateId,
        budget,
        domain,
        featuresCount: features.length,
        timestamp: new Date().toISOString()
      }
    };
  }

  /**
   * Get template-based recommendations
   */
  async getTemplateBasedRecommendations(options) {
    const { templateId, recommendationType = 'both' } = options;

    const results = {
      permutations: null,
      combinations: null,
      template: null
    };

    try {
      // Get template info
      const templateInfo = await this.templateManagerClient.getTemplateInfo(templateId);
      if (templateInfo.success) {
        results.template = templateInfo.data;
      }

      // Get permutations
      if (recommendationType === 'both' || recommendationType === 'permutations') {
        const permutations = await this.templateManagerClient.getPermutationRecommendations(templateId);
        results.permutations = permutations;
      }

      // Get combinations
      if (recommendationType === 'both' || recommendationType === 'combinations') {
        const combinations = await this.templateManagerClient.getCombinationRecommendations(templateId);
        results.combinations = combinations;
      }

      return {
        success: true,
        data: results,
        source: 'template-manager'
      };

    } catch (error) {
      console.error('❌ Template-based recommendations error:', error.message);
      return {
        success: false,
        error: error.message,
        source: 'template-manager'
      };
    }
  }

  /**
   * Get domain-based recommendations
   */
  async getDomainBasedRecommendations(options) {
    const { budget, domain, features = [] } = options;

    try {
      const recommendations = await this.techStackSelectorClient.getTechStackRecommendations(
        budget,
        domain,
        features
      );

      return {
        success: true,
        data: recommendations,
        source: 'tech-stack-selector'
      };

    } catch (error) {
      console.error('❌ Domain-based recommendations error:', error.message);
      return {
        success: false,
        error: error.message,
        source: 'tech-stack-selector'
      };
    }
  }

  /**
   * Generate unified recommendations by combining both sources
   */
  generateUnifiedRecommendations(templateBased, domainBased, preferences = {}) {
    const unified = {
      techStacks: [],
      technologies: [],
      recommendations: [],
      confidence: 0,
      approach: 'hybrid'
    };

    // Extract tech stacks from template-based recommendations
    if (templateBased?.success) {
      const templateTechStacks = this.extractTechStacksFromTemplate(templateBased.data);
      unified.techStacks.push(...templateTechStacks);
    }

    // Extract tech stacks from domain-based recommendations
    if (domainBased?.success) {
      const domainTechStacks = this.extractTechStacksFromDomain(domainBased.data);
      unified.techStacks.push(...domainTechStacks);
    }

    // Optional feature-based filtering if preferences carries feature list
    const featureFilter = Array.isArray(preferences?.featureFilter)
      ? preferences.featureFilter.map(f => (typeof f === 'string' ? f.toLowerCase().trim() : f))
      : [];

    if (featureFilter.length > 0) {
      unified.techStacks = this.filterTechStacksByFeatures(unified.techStacks, featureFilter);
    }

    // Merge and deduplicate technologies
    unified.technologies = this.mergeTechnologies(unified.techStacks);

    // Generate unified recommendations
    unified.recommendations = this.generateUnifiedRecommendationList(unified.techStacks, preferences);

    // Calculate overall confidence
    unified.confidence = this.calculateUnifiedConfidence(templateBased, domainBased);

    // Determine best approach
    unified.approach = this.determineBestApproach(templateBased, domainBased);

    return unified;
  }

  /**
   * Extract tech stacks from template-based data
   */
  extractTechStacksFromTemplate(templateData) {
    const techStacks = [];

    // Extract from permutations
    if (templateData.permutations?.success && templateData.permutations.data?.data?.permutation_recommendations) {
      templateData.permutations.data.data.permutation_recommendations.forEach(perm => {
        if (perm.tech_stack) {
          techStacks.push({
            ...perm.tech_stack,
            source: 'template-permutation',
            type: 'permutation',
            sequenceLength: perm.sequence_length,
            performanceScore: perm.performance_score,
            // Capture feature context when present (various possible keys)
            features: (perm.features || perm.feature_names || perm.sequence || [])
          });
        }
      });
    }

    // Extract from combinations
    if (templateData.combinations?.success && templateData.combinations.data?.data?.combination_recommendations) {
      templateData.combinations.data.data.combination_recommendations.forEach(comb => {
        if (comb.tech_stack) {
          techStacks.push({
            ...comb.tech_stack,
            source: 'template-combination',
            type: 'combination',
            setSize: comb.set_size,
            synergyScore: comb.synergy_score,
            // Capture feature context when present (various possible keys)
            features: (comb.features || comb.feature_names || comb.set || [])
          });
        }
      });
    }

    return techStacks;
  }

  /**
   * Filter tech stacks to only those that include all requested features
   */
  filterTechStacksByFeatures(techStacks, featureNames) {
    if (!Array.isArray(techStacks) || techStacks.length === 0) return [];
    const required = new Set(featureNames.map(f => (typeof f === 'string' ? f.toLowerCase().trim() : f)));

    return techStacks.filter(stack => {
      const stackFeaturesRaw = stack.features || [];
      const stackFeatures = stackFeaturesRaw.map(f => (typeof f === 'string' ? f.toLowerCase().trim() : (f?.name || '').toLowerCase().trim()))
        .filter(Boolean);
      // Keep only stacks that have all requested features present
      for (const req of required) {
        if (!stackFeatures.includes(req)) {
          return false;
        }
      }
      return true;
    });
  }

  /**
   * Extract tech stacks from Claude AI recommendations
   */
  extractTechStacksFromClaude(claudeData) {
    console.log('🎯 extractTechStacksFromClaude called');
    const techStacks = [];

    if (claudeData?.claude_recommendations?.technology_recommendations) {
      console.log('✅ Claude tech recommendations found, extracting...');
      const techRecs = claudeData.claude_recommendations.technology_recommendations;
      
      const claudeStack = {
        name: 'Claude AI Recommended Stack',
        source: 'claude-ai',
        type: 'ai-powered',
        confidence: 0.9,
        frontend: {
          framework: techRecs.frontend?.framework,
          libraries: techRecs.frontend?.libraries || [],
          reasoning: techRecs.frontend?.reasoning
        },
        backend: {
          language: techRecs.backend?.language,
          framework: techRecs.backend?.framework,
          libraries: techRecs.backend?.libraries || [],
          reasoning: techRecs.backend?.reasoning
        },
        database: {
          primary: techRecs.database?.primary,
          secondary: techRecs.database?.secondary || [],
          reasoning: techRecs.database?.reasoning
        },
        mobile: {
          framework: techRecs.mobile?.framework,
          libraries: techRecs.mobile?.libraries || [],
          reasoning: techRecs.mobile?.reasoning
        },
        devops: {
          tools: techRecs.devops?.tools || [],
          platforms: techRecs.devops?.platforms || [],
          reasoning: techRecs.devops?.reasoning
        },
        tools: {
          development: techRecs.tools?.development || [],
          monitoring: techRecs.tools?.monitoring || [],
          reasoning: techRecs.tools?.reasoning
        },
        ai_ml: {
          frameworks: techRecs.ai_ml?.frameworks || [],
          libraries: techRecs.ai_ml?.libraries || [],
          reasoning: techRecs.ai_ml?.reasoning
        },
        implementation_strategy: claudeData.claude_recommendations.implementation_strategy,
        business_alignment: claudeData.claude_recommendations.business_alignment,
        risk_assessment: claudeData.claude_recommendations.risk_assessment
      };
      
      techStacks.push(claudeStack);
      console.log('✅ Claude tech stack extracted successfully');
    } else {
      console.log('⚠️ No Claude tech recommendations found');
    }

    console.log('🎯 extractTechStacksFromClaude returning', techStacks.length, 'stacks');
    return techStacks;
  }

  /**
   * Extract tech stacks from domain-based data
   */
  extractTechStacksFromDomain(domainData) {
    console.log('🎯 extractTechStacksFromDomain called');
    const techStacks = [];

    // Case 1: Array of recommendations (older shape)
    if (domainData?.success && domainData.data?.recommendations) {
      console.log('✅ Found domain recommendations array');
      domainData.data.recommendations.forEach(rec => {
        techStacks.push({
          ...rec,
          source: 'domain-based',
          type: 'domain',
          confidence: rec.confidence || 0.8
        });
      });
    }

    // Case 2: Direct data object (current shape)
    // Example: { success: true, data: { price_tier, monthly_cost, ... }, source, type }
    if (!techStacks.length && domainData?.data && (domainData.data.price_tier || domainData.data.monthly_cost || domainData.data.backend)) {
      console.log('✅ Found domain recommendation object');
      const rec = domainData.data;
      const domainStack = {
        name: rec.stack_name || `${rec.price_tier || 'Recommended'} Stack`,
        price_tier: rec.price_tier,
        monthly_cost: rec.monthly_cost,
        setup_cost: rec.setup_cost,
        frontend: rec.frontend,
        backend: rec.backend,
        database: rec.database,
        cloud: rec.cloud,
        testing: rec.testing,
        mobile: rec.mobile,
        devops: rec.devops,
        ai_ml: rec.ai_ml,
        tool: rec.tool,
        recommendation_score: rec.recommendation_score,
        description: rec.description,
        source: 'domain-based',
        type: 'domain',
        confidence: 0.85
      };
      techStacks.push(domainStack);
    } else if (!techStacks.length) {
      console.log('⚠️ No domain recommendations found');
    }

    console.log('🎯 extractTechStacksFromDomain returning', techStacks.length, 'stacks');
    return techStacks;
  }

  /**
   * Merge technologies from different sources
   */
  mergeTechnologies(techStacks) {
    const technologyMap = new Map();

    techStacks.forEach(techStack => {
      if (techStack.technologies) {
        techStack.technologies.forEach(tech => {
          const key = tech.name || tech;
          if (!technologyMap.has(key)) {
            technologyMap.set(key, {
              name: tech.name || tech,
              category: tech.category || 'unknown',
              confidence: tech.confidence || 0.5,
              sources: [],
              frequency: 0
            });
          }
          
          const existing = technologyMap.get(key);
          existing.sources.push(techStack.source);
          existing.frequency++;
          existing.confidence = Math.max(existing.confidence, tech.confidence || 0.5);
        });
      }
    });

    return Array.from(technologyMap.values()).sort((a, b) => b.frequency - a.frequency);
  }

  /**
   * Generate unified recommendation list
   */
  generateUnifiedRecommendationList(techStacks, preferences = {}) {
    const recommendations = [];

    // Group by technology categories
    const categoryGroups = _.groupBy(techStacks, 'category');

    Object.entries(categoryGroups).forEach(([category, stacks]) => {
      const recommendation = {
        category,
        techStacks: stacks,
        confidence: _.meanBy(stacks, 'confidence') || 0.5,
        recommendation: this.generateCategoryRecommendation(category, stacks, preferences)
      };
      recommendations.push(recommendation);
    });

    return recommendations.sort((a, b) => b.confidence - a.confidence);
  }

  /**
   * Generate recommendation for a specific category
   */
  generateCategoryRecommendation(category, stacks, preferences) {
    const topTech = _.maxBy(stacks, 'confidence');
    
    return {
      primary: topTech?.name || 'Unknown',
      alternatives: stacks.slice(1, 4).map(s => s.name),
      confidence: topTech?.confidence || 0.5,
      reasoning: `Based on ${stacks.length} recommendations from ${_.uniq(stacks.map(s => s.source)).join(', ')}`
    };
  }

  /**
   * Calculate unified confidence score
   */
  calculateUnifiedConfidence(templateBased, domainBased) {
    let confidence = 0;
    let sources = 0;

    if (templateBased?.success) {
      confidence += 0.6; // Template-based gets higher weight
      sources++;
    }

    if (domainBased?.success) {
      confidence += 0.4; // Domain-based gets lower weight
      sources++;
    }

    return sources > 0 ? confidence / sources : 0;
  }

  /**
   * Determine best approach based on available data
   */
  determineBestApproach(templateBased, domainBased) {
    if (templateBased?.success && domainBased?.success) {
      return 'hybrid';
    } else if (templateBased?.success) {
      return 'template-based';
    } else if (domainBased?.success) {
      return 'domain-based';
    } else {
      return 'none';
    }
  }

  /**
   * Analyze recommendations from both services
   */
  analyzeRecommendations(templateBased, domainBased) {
    const analysis = {
      templateManager: {
        status: templateBased?.success ? 'success' : 'failed',
        dataAvailable: templateBased?.success,
        permutationsCount: 0,
        combinationsCount: 0,
        techStacksCount: 0
      },
      techStackSelector: {
        status: domainBased?.success ? 'success' : 'failed',
        dataAvailable: domainBased?.success,
        recommendationsCount: 0,
        avgConfidence: 0
      },
      comparison: {
        overlap: 0,
        uniqueTechnologies: 0,
        recommendationQuality: 'unknown'
      }
    };

    // Analyze template manager data
    if (templateBased?.success) {
      const data = templateBased.data;
      if (data.permutations?.success) {
        analysis.templateManager.permutationsCount = data.permutations.data?.data?.total_permutations || 0;
      }
      if (data.combinations?.success) {
        analysis.templateManager.combinationsCount = data.combinations.data?.data?.total_combinations || 0;
      }
      analysis.templateManager.techStacksCount = analysis.templateManager.permutationsCount + analysis.templateManager.combinationsCount;
    }

    // Analyze tech stack selector data
    if (domainBased?.success) {
      const data = domainBased.data;
      analysis.techStackSelector.recommendationsCount = data.data?.recommendations?.length || 0;
      analysis.techStackSelector.avgConfidence = _.meanBy(data.data?.recommendations || [], 'confidence') || 0;
    }

    // Compare recommendations
    if (templateBased?.success && domainBased?.success) {
      analysis.comparison.recommendationQuality = this.assessRecommendationQuality(templateBased, domainBased);
    }

    return analysis;
  }

  /**
   * Assess the quality of recommendations
   */
  assessRecommendationQuality(templateBased, domainBased) {
    const templateCount = (templateBased.data.permutations?.data?.data?.total_permutations || 0) + 
                         (templateBased.data.combinations?.data?.data?.total_combinations || 0);
    const domainCount = domainBased.data.data?.recommendations?.length || 0;

    if (templateCount > 5 && domainCount > 3) {
      return 'excellent';
    } else if (templateCount > 2 && domainCount > 1) {
      return 'good';
    } else if (templateCount > 0 || domainCount > 0) {
      return 'fair';
    } else {
      return 'poor';
    }
  }

  /**
   * Save recommendations to database
   */
  async saveRecommendationsToDatabase(recommendationData) {
    try {
      return await this.database.saveRecommendations(recommendationData);
    } catch (error) {
      console.error('❌ Error saving recommendations to database:', error.message);
      return {
        success: false,
        error: error.message
      };
    }
  }

  /**
   * Get user's recommendation history
   */
  async getUserRecommendationHistory(userId, limit = 10) {
    try {
      return await this.database.getUserRecommendationHistory(userId, limit);
    } catch (error) {
      console.error('❌ Error getting user recommendation history:', error.message);
      return {
        success: false,
        error: error.message
      };
    }
  }

  /**
   * Clean up expired recommendations
   */
  async cleanupExpiredRecommendations() {
    try {
      return await this.database.cleanupExpiredRecommendations();
    } catch (error) {
      console.error('❌ Error cleaning up expired recommendations:', error.message);
      return {
        success: false,
        error: error.message
      };
    }
  }

  /**
   * Validate user authentication token
   */
  async validateUserToken(token) {
    try {
      return await this.userAuthClient.validateUserToken(token);
    } catch (error) {
      console.error('❌ Error validating user token:', error.message);
      return {
        success: false,
        error: error.message
      };
    }
  }

  /**
   * Check if user exists and is active
   */
  async checkUserExists(userId) {
    try {
      return await this.userAuthClient.checkUserExists(userId);
    } catch (error) {
      console.error('❌ Error checking user existence:', error.message);
      return {
        success: false,
        exists: false,
        error: error.message
      };
    }
  }

  /**
   * Get user recommendation statistics
   */
  async getUserRecommendationStats(userId) {
    try {
      const query = `SELECT * FROM get_user_recommendation_stats($1)`;
      const result = await this.database.query(query, [userId]);
      
      if (result.rows.length > 0) {
        return {
          success: true,
          data: result.rows[0]
        };
      } else {
        return {
          success: false,
          error: 'No statistics found for user'
        };
      }
    } catch (error) {
      console.error('❌ Error getting user recommendation stats:', error.message);
      return {
        success: false,
        error: error.message
      };
    }
  }

  /**
   * Get service status
   */
  async getServiceStatus() {
    const templateManagerHealth = await this.templateManagerClient.checkHealth();
    const techStackSelectorHealth = await this.techStackSelectorClient.checkHealth();
    const userAuthHealth = await this.userAuthClient.checkHealth();

    return {
      unifiedService: {
        status: 'healthy',
        version: '1.0.0',
        uptime: process.uptime()
      },
      templateManager: templateManagerHealth,
      techStackSelector: techStackSelectorHealth,
      userAuth: userAuthHealth,
      database: {
        status: 'connected', // Could add actual database health check here
        available: true
      },
      overallStatus: templateManagerHealth.success && techStackSelectorHealth.success && userAuthHealth.success ? 'healthy' : 'degraded'
    };
  }
}

module.exports = UnifiedTechStackService;
