# ================================================================================================
# ENHANCED TECH STACK SELECTOR - MIGRATED VERSION
# Uses PostgreSQL data migrated to Neo4j with proper price-based relationships
# ================================================================================================

import os
import sys
import json
from datetime import datetime
from typing import Dict, Any, Optional, List
from pydantic import BaseModel
from fastapi import FastAPI, HTTPException, Request
from fastapi.middleware.cors import CORSMiddleware
from loguru import logger
import atexit
import anthropic
from neo4j import GraphDatabase
import psycopg2
from psycopg2.extras import RealDictCursor
from neo4j_namespace_service import Neo4jNamespaceService

# ================================================================================================
# CLAUDE AI SERVICE FOR INTELLIGENT RECOMMENDATIONS
# ================================================================================================

class ClaudeRecommendationService:
    def __init__(self, api_key: str):
        self.client = anthropic.Anthropic(api_key=api_key)
    
    def generate_tech_stack_recommendation(self, domain: str, budget: float):
        """Generate professional, budget-aware tech stack recommendation using Claude AI"""
        
        # PROFESSIONAL BUDGET CALCULATION - Based on 30+ years experience
        # For micro budgets, we need to be extremely realistic about costs
        if budget <= 5:
            monthly_budget = 0.0  # Everything must be free
            setup_budget = 0.0
        elif budget <= 10:
            monthly_budget = 0.0  # Free tier services only
            setup_budget = 0.0
        elif budget <= 25:
            monthly_budget = 5.0  # Basic paid service
            setup_budget = 0.0
        else:
            # For higher budgets, use proportional allocation
            monthly_budget = budget * 0.6 / 12
            setup_budget = budget * 0.4
        
        prompt = f"""
You are a senior technology architect with 15+ years of experience in enterprise software development. 
Your task is to recommend a PROFESSIONAL, PRODUCTION-READY technology stack for a {domain} application.

BUDGET CONSTRAINTS (CRITICAL):
- Total Annual Budget: ${budget}
- Monthly Operational Budget: ${monthly_budget:.2f}
- One-time Setup Budget: ${setup_budget:.2f}
- Total First Year Cost MUST NOT exceed ${budget}

DOMAIN-SPECIFIC REQUIREMENTS:
- {domain} applications require specific technology choices
- Consider industry best practices and compliance requirements
- Ensure scalability for {domain} use cases
- Prioritize technologies with strong {domain} ecosystem support

PROFESSIONAL CRITERIA:
1. Technology maturity and enterprise readiness
2. Community support and documentation quality
3. Integration capabilities and ecosystem
4. Security and compliance features
5. Performance and scalability characteristics
6. Team productivity and learning curve
7. Long-term maintenance and support

BUDGET-AWARE SELECTIONS:
- Choose technologies that fit within the specified budget
- Prioritize cost-effective solutions without compromising quality
- Consider both initial setup costs and ongoing operational costs
- Balance premium features with budget constraints

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

{{
    "stack_name": "Professional {domain.title()} Stack",
    "frontend": "Recommended frontend technology (with brief justification)",
    "backend": "Recommended backend technology (with brief justification)", 
    "database": "Recommended database technology (with brief justification)",
    "cloud": "Recommended cloud platform (with brief justification)",
    "testing": "Recommended testing framework (with brief justification)",
    "mobile": "Recommended mobile solution (with brief justification)",
    "devops": "Recommended DevOps tools (with brief justification)",
    "ai_ml": "Recommended AI/ML tools (or 'None' if not needed)",
    "tool": ["Essential development tools like Git, VS Code, Postman, Docker, etc."],
    "reasoning": "Professional explanation of why this stack is optimal for {domain} with ${budget} budget",
    "monthly_cost_estimate": {monthly_budget:.2f},
    "setup_cost_estimate": {setup_budget:.2f},
    "recommendation_score": 85,
    "team_size_range": "1-3",
    "development_time_months": 3,
    "satisfaction": 85,
    "success_rate": 85,
    "price_tier": "Medium",
    "recommended_domains": ["{domain}"],
    "description": "Professional {domain} technology stack optimized for ${budget} budget",
    "pros": ["Key advantages of this stack"],
    "cons": ["Potential limitations or considerations"]
}}

REQUIREMENTS:
- Ensure ALL technologies are production-ready and enterprise-grade
- Provide comprehensive stack covering all necessary layers
- Justify each technology choice based on {domain} requirements
- Maintain budget constraints while ensuring quality
- Focus on technologies with proven track records in {domain} applications
"""

        try:
            response = self.client.messages.create(
                model="claude-3-5-sonnet-20241022",
                max_tokens=1000,
                temperature=0.3,
                messages=[{
                    "role": "user",
                    "content": prompt
                }]
            )
            
            # Extract JSON from response
            content = response.content[0].text
            logger.info(f"Claude response: {content}")
            
            # Try to parse JSON from the response
            import re
            json_match = re.search(r'\{.*\}', content, re.DOTALL)
            if json_match:
                import json
                recommendation = json.loads(json_match.group())
                return recommendation
            else:
                logger.warning("Could not extract JSON from Claude response")
                return None
                
        except Exception as e:
            logger.error(f"Claude API error: {e}")
            return None

# ================================================================================================
# NEO4J SERVICE FOR MIGRATED DATA
# ================================================================================================

class MigratedNeo4jService:
    def __init__(self, uri, user, password):
        self.driver = GraphDatabase.driver(
            uri,
            auth=(user, password),
            connection_timeout=5
        )
        self.neo4j_healthy = False
        self.claude_service = None
        self.postgres_service = PostgreSQLMigrationService()
        
        # Initialize Claude service if API key is available
        claude_api_key = os.getenv("CLAUDE_API_KEY")
        if claude_api_key:
            try:
                self.claude_service = ClaudeRecommendationService(claude_api_key)
                logger.info("✅ Claude AI service initialized")
            except Exception as e:
                logger.warning(f"⚠️ Claude AI service failed to initialize: {e}")
        else:
            logger.warning("⚠️ Claude API key not found - Claude fallback disabled")
        
        try:
            self.driver.verify_connectivity()
            logger.info("✅ Migrated Neo4j Service connected successfully")
            self.neo4j_healthy = True
        except Exception as e:
            logger.error(f"❌ Neo4j connection failed: {e}")
            self.neo4j_healthy = False
    
    def close(self):
        if self.driver:
            self.driver.close()
    
    def is_neo4j_healthy(self):
        """Check if Neo4j is healthy and accessible"""
        try:
            with self.driver.session() as session:
                session.run("RETURN 1")
            self.neo4j_healthy = True
            return True
        except Exception as e:
            logger.warning(f"⚠️ Neo4j health check failed: {e}")
            self.neo4j_healthy = False
            return False

    def run_query(self, query: str, parameters: Optional[Dict[str, Any]] = None):
        with self.driver.session() as session:
            result = session.run(query, parameters or {})
            return [record.data() for record in result]
    
    def get_recommendations_with_fallback(self, budget: float, domain: Optional[str] = None, preferred_techs: Optional[List[str]] = None):
        """Get recommendations with robust fallback mechanism"""
        logger.info(f"🔄 Getting recommendations for budget ${budget}, domain '{domain}'")
        
        # PRIMARY: Try Neo4j Knowledge Graph
        if self.is_neo4j_healthy():
            try:
                logger.info("🎯 Using PRIMARY: Neo4j Knowledge Graph")
                recommendations = self.get_recommendations_by_budget(budget, domain, preferred_techs)
                if recommendations:
                    logger.info(f"✅ Neo4j returned {len(recommendations)} recommendations")
                    return {
                        "recommendations": recommendations,
                        "count": len(recommendations),
                        "data_source": "neo4j_knowledge_graph",
                        "fallback_level": "primary"
                    }
            except Exception as e:
                logger.error(f"❌ Neo4j query failed: {e}")
                self.neo4j_healthy = False
        
        # SECONDARY: Try Claude AI
        if self.claude_service:
            try:
                logger.info("🤖 Using SECONDARY: Claude AI")
                claude_rec = self.claude_service.generate_tech_stack_recommendation(domain or "general", budget)
                if claude_rec:
                    logger.info("✅ Claude AI generated recommendation")
                    return {
                        "recommendations": [claude_rec],
                        "count": 1,
                        "data_source": "claude_ai",
                        "fallback_level": "secondary"
                    }
            except Exception as e:
                logger.error(f"❌ Claude AI failed: {e}")
        else:
            logger.warning("⚠️ Claude AI service not available - skipping to PostgreSQL fallback")
        
        # TERTIARY: Try PostgreSQL
        try:
            logger.info("🗄️ Using TERTIARY: PostgreSQL")
            postgres_recs = self.get_postgres_fallback_recommendations(budget, domain)
            if postgres_recs:
                logger.info(f"✅ PostgreSQL returned {len(postgres_recs)} recommendations")
                return {
                    "recommendations": postgres_recs,
                    "count": len(postgres_recs),
                    "data_source": "postgresql",
                    "fallback_level": "tertiary"
                }
        except Exception as e:
            logger.error(f"❌ PostgreSQL fallback failed: {e}")
        
        # FINAL: Static fallback
        logger.warning("⚠️ Using FINAL: Static fallback")
        static_rec = self._create_static_fallback_recommendation(budget, domain)
        return {
            "recommendations": [static_rec],
            "count": 1,
            "data_source": "static_fallback",
            "fallback_level": "final"
        }
    
    def get_postgres_fallback_recommendations(self, budget: float, domain: Optional[str] = None):
        """Get recommendations directly from PostgreSQL as fallback"""
        if not self.postgres_service.connect():
            raise Exception("PostgreSQL connection failed")
        
        try:
            # Enhanced PostgreSQL query for professional, budget-aware recommendations
            query = """
            SELECT pbs.*, pt.tier_name as price_tier_name, 
                   COALESCE(array_agg(DISTINCT t.name) FILTER (WHERE t.name IS NOT NULL), ARRAY[]::text[]) as tools,
                   -- Professional scoring based on multiple factors
                   (COALESCE(pbs.user_satisfaction_score, 80) * 0.3 + 
                    COALESCE(pbs.success_rate_percentage, 80) * 0.3 +
                    CASE WHEN pbs.team_size_range IS NOT NULL THEN 20 ELSE 10 END +
                    CASE WHEN pbs.development_time_months IS NOT NULL THEN 10 ELSE 5 END +
                    CASE WHEN pbs.frontend_tech IS NOT NULL AND pbs.frontend_tech != 'None' THEN 5 ELSE 0 END +
                    CASE WHEN pbs.backend_tech IS NOT NULL AND pbs.backend_tech != 'None' THEN 5 ELSE 0 END +
                    CASE WHEN pbs.database_tech IS NOT NULL AND pbs.database_tech != 'None' THEN 5 ELSE 0 END +
                    CASE WHEN pbs.testing_tech IS NOT NULL AND pbs.testing_tech != 'None' THEN 5 ELSE 0 END
                   ) as professional_score
            FROM price_based_stacks pbs
            JOIN price_tiers pt ON pbs.price_tier_id = pt.id
            LEFT JOIN tools t ON t.price_tier_id = pt.id
            WHERE pt.min_price_usd <= %s AND pt.max_price_usd >= %s
            AND (%s IS NULL OR 
                 LOWER(pbs.stack_name) LIKE LOWER(%s) OR
                 LOWER(pbs.description) LIKE LOWER(%s) OR
                 EXISTS (SELECT 1 FROM unnest(pbs.recommended_domains) AS domain WHERE LOWER(domain) LIKE LOWER(%s)))
            GROUP BY pbs.id, pt.tier_name, pbs.user_satisfaction_score, pbs.success_rate_percentage, 
                     pbs.team_size_range, pbs.development_time_months, pbs.frontend_tech, pbs.backend_tech, 
                     pbs.database_tech, pbs.testing_tech
            ORDER BY professional_score DESC, pbs.user_satisfaction_score DESC, pbs.success_rate_percentage DESC
            LIMIT 10
            """
            
            # Create flexible domain pattern for better matching
            if domain:
                domain_lower = domain.lower()
                # Handle common domain variations
                if 'commerce' in domain_lower:
                    domain_pattern = f"%e-commerce%"
                else:
                    domain_pattern = f"%{domain_lower}%"
            else:
                domain_pattern = None
            self.postgres_service.cursor.execute(query, (
                budget, budget, domain, domain_pattern, domain_pattern, domain_pattern
            ))
            
            results = self.postgres_service.cursor.fetchall()
            logger.info(f"📊 PostgreSQL query returned {len(results)} results")
            
            recommendations = []
            
            for row in results:
                rec = {
                    "monthly_cost": float(row['total_monthly_cost_usd']),
                    "setup_cost": float(row['total_setup_cost_usd']),
                    "team_size": row['team_size_range'],
                    "development_time": row['development_time_months'],
                    "satisfaction": row['user_satisfaction_score'],
                    "success_rate": row['success_rate_percentage'],
                    "price_tier": row['price_tier_name'],
                    "frontend": row['frontend_tech'],
                    "backend": row['backend_tech'],
                    "database": row['database_tech'],
                    "cloud": row['cloud_tech'],
                    "testing": row['testing_tech'],
                    "mobile": row['mobile_tech'],
                    "devops": row['devops_tech'],
                    "ai_ml": row['ai_ml_tech'],
                    "tool": row['tools'] if row['tools'] else [],
                    "recommendation_score": float(row.get('professional_score', 75.0))  # Use professional score from PostgreSQL
                }
                recommendations.append(rec)
            
            logger.info(f"✅ PostgreSQL fallback created {len(recommendations)} recommendations")
            return recommendations
            
        finally:
            self.postgres_service.close()
    
    def _create_static_fallback_recommendation(self, budget: float, domain: Optional[str] = None):
        """Create a static fallback recommendation when all else fails - PROFESSIONAL BUDGET-AWARE"""
        # PROFESSIONAL COST CALCULATION - Based on 30+ years experience
        # For micro budgets, we need to be extremely realistic about costs
        
        if budget <= 5:  # Ultra-micro budget ($5) - Professional Assessment
            # For $5 budget, we can only afford completely free solutions
            techs = {
                "frontend": "HTML/CSS + Vanilla JavaScript",
                "backend": "None (Static Site Only)",
                "database": "None (Static Data/JSON)",
                "cloud": "GitHub Pages (Free)",
                "testing": "Browser Developer Tools",
                "mobile": "Responsive CSS Design",
                "devops": "Git (Free)",
                "ai_ml": "None",
                "tool": ["VS Code (Free)", "Git (Free)", "GitHub (Free)"]
            }
            stack_name = f"Ultra-Micro {domain.title() if domain else 'Personal'} Stack"
            price_tier = "Ultra-Micro Budget"
            team_size = "1 developer"
            development_time = 1
            satisfaction = 35.0
            success_rate = 45.0
            recommendation_score = 30.0
            # REALISTIC COSTS for $5 budget
            monthly_cost = 0.0  # Everything is free
            setup_cost = 0.0     # No setup costs for free services
            
        elif budget <= 10:  # Very low budget ($6-10) - Professional Assessment
            # For $10 budget, we can afford basic free tier services
            techs = {
                "frontend": "HTML/CSS + Vanilla JavaScript",
                "backend": "Node.js (Basic) or Python Flask",
                "database": "SQLite (File-based)",
                "cloud": "Netlify (Free Tier) or Vercel (Free)",
                "testing": "Browser Testing + Basic Unit Tests",
                "mobile": "Responsive CSS Design",
                "devops": "Git + GitHub Actions (Free)",
                "ai_ml": "None",
                "tool": ["VS Code (Free)", "Git (Free)", "Netlify/Vercel (Free)"]
            }
            stack_name = f"Micro {domain.title() if domain else 'Personal'} Stack"
            price_tier = "Micro Budget"
            team_size = "1 developer"
            development_time = 2
            satisfaction = 45.0
            success_rate = 55.0
            recommendation_score = 40.0
            # REALISTIC COSTS for $10 budget
            monthly_cost = 0.0  # Free tier services
            setup_cost = 0.0     # No setup costs for free services
            
        elif budget <= 25:  # Low budget ($11-25) - Professional Assessment
            # For $25 budget, we can afford basic paid services
            techs = {
                "frontend": "HTML/CSS + Vanilla JavaScript or Basic React",
                "backend": "Node.js or Python Flask/FastAPI",
                "database": "SQLite or PostgreSQL (Free Tier)",
                "cloud": "Railway ($5/month) or Heroku (Free Tier)",
                "testing": "Jest (Free) + Browser Testing",
                "mobile": "Responsive Design",
                "devops": "Git + GitHub Actions (Free)",
                "ai_ml": "None",
                "tool": ["VS Code (Free)", "Git (Free)", "Railway/Heroku"]
            }
            stack_name = f"Low-Budget {domain.title() if domain else 'Personal'} Stack"
            price_tier = "Low Budget"
            team_size = "1 developer"
            development_time = 3
            satisfaction = 55.0
            success_rate = 65.0
            recommendation_score = 50.0
            # REALISTIC COSTS for $25 budget
            monthly_cost = 5.0   # Basic cloud service
            setup_cost = 0.0      # No setup costs
            
        else:  # Higher budgets - use domain-specific recommendations
            domain_techs = {
                "ecommerce": {"frontend": "React", "backend": "Node.js", "database": "PostgreSQL", "cloud": "AWS"},
                "saas": {"frontend": "Vue.js", "backend": "Django", "database": "PostgreSQL", "cloud": "DigitalOcean"},
                "mobile": {"frontend": "React Native", "backend": "Express.js", "database": "MongoDB", "cloud": "Firebase"},
                "ai": {"frontend": "Next.js", "backend": "Python", "database": "PostgreSQL", "cloud": "AWS"},
                "finance": {"frontend": "React", "backend": "Node.js", "database": "PostgreSQL", "cloud": "AWS"},
                "default": {"frontend": "HTML/CSS + JavaScript", "backend": "Node.js", "database": "SQLite", "cloud": "GitHub Pages"}
            }
            
            techs = domain_techs.get(domain.lower() if domain else "default", domain_techs["default"])
            techs.update({
                "testing": "Jest",
                "mobile": "Responsive Design",
                "devops": "Git",
                "ai_ml": "None",
                "tool": ["Git", "VS Code", "Postman", "Docker"]
            })
            
            stack_name = f"Static {domain.title() if domain else 'General'} Stack"
            price_tier = "Budget"
            team_size = "1-3 developers"
            development_time = 3
            satisfaction = 60.0
            success_rate = 70.0
            recommendation_score = 50.0
            # REALISTIC COSTS for higher budgets
            monthly_cost = budget * 0.6 / 12  # 60% of budget for monthly costs
            setup_cost = budget * 0.4        # 40% of budget for setup costs
        
        return {
            "stack_name": stack_name,
            "monthly_cost": round(monthly_cost, 2),
            "setup_cost": round(setup_cost, 2),
            "team_size": team_size,
            "development_time": development_time,
            "satisfaction": satisfaction,
            "success_rate": success_rate,
            "price_tier": price_tier,
            "frontend": techs["frontend"],
            "backend": techs["backend"],
            "database": techs["database"],
            "cloud": techs["cloud"],
            "testing": techs["testing"],
            "mobile": techs["mobile"],
            "devops": techs["devops"],
            "ai_ml": techs["ai_ml"],
            "tool": techs["tool"],
            "recommendation_score": recommendation_score,
            "description": f"Budget-aware static fallback recommendation for ${budget} budget"
        }

    def get_recommendations_by_budget(self, budget: float, domain: Optional[str] = None, preferred_techs: Optional[List[str]] = None):
        """Get professional, budget-appropriate, domain-specific recommendations from Knowledge Graph only"""
        
        # BUDGET VALIDATION: For very low budgets, use budget-aware static recommendations
        if budget <= 5:
            logger.info(f"Ultra-micro budget ${budget} detected - using budget-aware static recommendation")
            return [self._create_static_fallback_recommendation(budget, domain)]
        elif budget <= 10:
            logger.info(f"Micro budget ${budget} detected - using budget-aware static recommendation")
            return [self._create_static_fallback_recommendation(budget, domain)]
        elif budget <= 25:
            logger.info(f"Low budget ${budget} detected - using budget-aware static recommendation")
            return [self._create_static_fallback_recommendation(budget, domain)]
        
        # Normalize domain for better matching with intelligent variations
        normalized_domain = domain.lower().strip() if domain else None
        
        # Create comprehensive domain variations for robust matching
        domain_variations = []
        if normalized_domain:
            domain_variations.append(normalized_domain)
            if 'commerce' in normalized_domain or 'ecommerce' in normalized_domain:
                domain_variations.extend(['e-commerce', 'ecommerce', 'online stores', 'product catalogs', 'marketplaces', 'retail', 'shopping'])
            if 'saas' in normalized_domain:
                domain_variations.extend(['web apps', 'business tools', 'data management', 'software as a service', 'cloud applications'])
            if 'mobile' in normalized_domain:
                domain_variations.extend(['mobile apps', 'ios', 'android', 'cross-platform', 'native apps'])
            if 'ai' in normalized_domain or 'ml' in normalized_domain:
                domain_variations.extend(['artificial intelligence', 'machine learning', 'data science', 'ai applications'])
            if 'healthcare' in normalized_domain:
                domain_variations.extend(['medical', 'health', 'clinical', 'patient management', 'healthcare systems'])
            if 'finance' in normalized_domain:
                domain_variations.extend(['financial', 'banking', 'fintech', 'payment', 'trading', 'investment'])
            if 'education' in normalized_domain:
                domain_variations.extend(['learning', 'elearning', 'educational', 'academic', 'training'])
            if 'gaming' in normalized_domain:
                domain_variations.extend(['games', 'entertainment', 'interactive', 'real-time'])
        
        logger.info(f"🎯 Knowledge Graph: Searching for professional tech stacks with budget ${budget} and domain '{domain}'")
        
        # Enhanced Knowledge Graph query with professional scoring and budget precision
        existing_stacks = self.run_query("""
            MATCH (s:TechStack)-[:BELONGS_TO_TIER]->(p:PriceTier)
            WHERE p.min_price_usd <= $budget AND p.max_price_usd >= $budget
            AND ($domain IS NULL OR 
                 toLower(s.name) CONTAINS $normalized_domain OR
                 toLower(s.description) CONTAINS $normalized_domain OR
                 EXISTS { MATCH (d:Domain)-[:RECOMMENDS]->(s) WHERE toLower(d.name) = $normalized_domain } OR
                 EXISTS { MATCH (d:Domain)-[:RECOMMENDS]->(s) WHERE toLower(d.name) CONTAINS $normalized_domain } OR
                 ANY(rd IN s.recommended_domains WHERE toLower(rd) CONTAINS $normalized_domain) OR
                 ANY(rd IN s.recommended_domains WHERE toLower(rd) CONTAINS $normalized_domain + ' ' OR toLower(rd) CONTAINS ' ' + $normalized_domain) OR
                 ANY(rd IN s.recommended_domains WHERE ANY(variation IN $domain_variations WHERE toLower(rd) CONTAINS variation)))
            
            OPTIONAL MATCH (s)-[:USES_FRONTEND]->(frontend:Technology)
            OPTIONAL MATCH (s)-[:USES_BACKEND]->(backend:Technology)
            OPTIONAL MATCH (s)-[:USES_DATABASE]->(database:Technology)
            OPTIONAL MATCH (s)-[:USES_CLOUD]->(cloud:Technology)
            OPTIONAL MATCH (s)-[:USES_TESTING]->(testing:Technology)
            OPTIONAL MATCH (s)-[:USES_MOBILE]->(mobile:Technology)
            OPTIONAL MATCH (s)-[:USES_DEVOPS]->(devops:Technology)
            OPTIONAL MATCH (s)-[:USES_AI_ML]->(ai_ml:Technology)
            OPTIONAL MATCH (s)-[:BELONGS_TO_TIER]->(pt2)<-[:BELONGS_TO_TIER]-(tool:Tool)
            
            WITH s, frontend, backend, database, cloud, testing, mobile, devops, ai_ml, collect(DISTINCT tool.name)[0] AS tool, p,
                 ($budget * 0.6 / 12) AS calculated_monthly_cost,
                 ($budget * 0.4) AS calculated_setup_cost,
                 (COALESCE(s.satisfaction_score, 80) * 0.4 + COALESCE(s.success_rate, 80) * 0.4 + 
                  CASE WHEN s.team_size_range IS NOT NULL THEN 20 ELSE 10 END) AS base_score
            
            WITH s, frontend, backend, database, cloud, testing, mobile, devops, ai_ml, tool, base_score, p, calculated_monthly_cost, calculated_setup_cost,
                 CASE WHEN $preferred_techs IS NOT NULL THEN 
                     size([x IN $preferred_techs WHERE 
                         toLower(x) IN [toLower(frontend.name), toLower(backend.name), toLower(database.name), 
                                       toLower(cloud.name), toLower(testing.name), toLower(mobile.name), 
                                       toLower(devops.name), toLower(ai_ml.name)]]) * 8
                 ELSE 0 END AS preference_bonus,
                 
                 // Professional scoring based on technology maturity and domain fit
                 CASE 
                     WHEN frontend.maturity_score >= 80 AND backend.maturity_score >= 80 THEN 15
                     WHEN frontend.maturity_score >= 70 AND backend.maturity_score >= 70 THEN 10
                     ELSE 5
                 END AS maturity_bonus,
                 
                 // Domain-specific scoring
                 CASE 
                     WHEN $normalized_domain IS NOT NULL AND 
                          (toLower(s.name) CONTAINS $normalized_domain OR 
                           ANY(rd IN s.recommended_domains WHERE toLower(rd) CONTAINS $normalized_domain)) THEN 20
                     ELSE 0
                 END AS domain_bonus
            
            RETURN s.name AS stack_name,
                   calculated_monthly_cost AS monthly_cost,
                   calculated_setup_cost AS setup_cost,
                   s.team_size_range AS team_size,
                   s.development_time_months AS development_time,
                   s.satisfaction_score AS satisfaction,
                   s.success_rate AS success_rate,
                   p.tier_name AS price_tier,
                   s.recommended_domains AS recommended_domains,
                   s.description AS description,
                   s.pros AS pros,
                   s.cons AS cons,
                   COALESCE(frontend.name, s.frontend_tech) AS frontend,
                   COALESCE(backend.name, s.backend_tech) AS backend,
                   COALESCE(database.name, s.database_tech) AS database,
                   COALESCE(cloud.name, s.cloud_tech) AS cloud,
                   COALESCE(testing.name, s.testing_tech) AS testing,
                   COALESCE(mobile.name, s.mobile_tech) AS mobile,
                   COALESCE(devops.name, s.devops_tech) AS devops,
                   COALESCE(ai_ml.name, s.ai_ml_tech) AS ai_ml,
                   tool AS tool,
                   CASE WHEN (base_score + preference_bonus + maturity_bonus + domain_bonus) > 100 THEN 100 
                        ELSE (base_score + preference_bonus + maturity_bonus + domain_bonus) END AS recommendation_score
            ORDER BY recommendation_score DESC, 
                     // Secondary sort by budget efficiency
                     CASE WHEN (calculated_monthly_cost * 12 + calculated_setup_cost) <= $budget THEN 1 ELSE 2 END,
                     (calculated_monthly_cost * 12 + calculated_setup_cost) ASC
            LIMIT 20
        """, {
            "budget": budget,
            "domain": domain,
            "normalized_domain": normalized_domain,
            "domain_variations": domain_variations,
            "preferred_techs": preferred_techs or []
        })
        
        logger.info(f"📊 Found {len(existing_stacks)} existing stacks with relationships")
        
        if existing_stacks:
            return existing_stacks
        
        # If no existing stacks with domain filtering, try without domain filtering
        if domain:
            print(f"No stacks found for domain '{domain}', trying without domain filter...")
            existing_stacks_no_domain = self.run_query("""
                MATCH (s:TechStack)-[:BELONGS_TO_TIER]->(p:PriceTier)
                WHERE p.min_price_usd <= $budget AND p.max_price_usd >= $budget
                
                OPTIONAL MATCH (s)-[:USES_FRONTEND]->(frontend:Technology)
                OPTIONAL MATCH (s)-[:USES_BACKEND]->(backend:Technology)
                OPTIONAL MATCH (s)-[:USES_DATABASE]->(database:Technology)
                OPTIONAL MATCH (s)-[:USES_CLOUD]->(cloud:Technology)
                OPTIONAL MATCH (s)-[:USES_TESTING]->(testing:Technology)
                OPTIONAL MATCH (s)-[:USES_MOBILE]->(mobile:Technology)
                OPTIONAL MATCH (s)-[:USES_DEVOPS]->(devops:Technology)
                OPTIONAL MATCH (s)-[:USES_AI_ML]->(ai_ml:Technology)
                OPTIONAL MATCH (s)-[:BELONGS_TO_TIER]->(pt3)<-[:BELONGS_TO_TIER]-(tool:Tool)
                
                WITH s, frontend, backend, database, cloud, testing, mobile, devops, ai_ml, collect(DISTINCT tool.name)[0] AS tool, p,
                     ($budget * 0.6 / 12) AS calculated_monthly_cost,
                     ($budget * 0.4) AS calculated_setup_cost,
                     (COALESCE(s.satisfaction_score, 80) * 0.5 + COALESCE(s.success_rate, 80) * 0.5) AS base_score
                
                WITH s, frontend, backend, database, cloud, testing, mobile, devops, ai_ml, tools, base_score, p, calculated_monthly_cost, calculated_setup_cost,
                     CASE WHEN $preferred_techs IS NOT NULL THEN 
                         size([x IN $preferred_techs WHERE 
                             toLower(x) IN [toLower(frontend.name), toLower(backend.name), toLower(database.name), 
                                           toLower(cloud.name), toLower(testing.name), toLower(mobile.name), 
                                           toLower(devops.name), toLower(ai_ml.name)]]) * 5
                     ELSE 0 END AS preference_bonus
                
                RETURN s.name AS stack_name,
                       calculated_monthly_cost AS monthly_cost,
                       calculated_setup_cost AS setup_cost,
                       s.team_size_range AS team_size,
                       s.development_time_months AS development_time,
                       s.satisfaction_score AS satisfaction,
                       s.success_rate AS success_rate,
                       p.tier_name AS price_tier,
                       s.recommended_domains AS recommended_domains,
                       s.description AS description,
                       s.pros AS pros,
                       s.cons AS cons,
                       COALESCE(frontend.name, s.frontend_tech) AS frontend,
                       COALESCE(backend.name, s.backend_tech) AS backend,
                       COALESCE(database.name, s.database_tech) AS database,
                       COALESCE(cloud.name, s.cloud_tech) AS cloud,
                       COALESCE(testing.name, s.testing_tech) AS testing,
                       COALESCE(mobile.name, s.mobile_tech) AS mobile,
                       COALESCE(devops.name, s.devops_tech) AS devops,
                       COALESCE(ai_ml.name, s.ai_ml_tech) AS ai_ml,
                       tool AS tool,
                       CASE WHEN (base_score + preference_bonus) > 100 THEN 100 ELSE (base_score + preference_bonus) END AS recommendation_score
                ORDER BY recommendation_score DESC, (s.monthly_cost * 12 + s.setup_cost) ASC
                LIMIT 50
            """, {
                "budget": budget,
                "preferred_techs": preferred_techs or []
            })
            
            if existing_stacks_no_domain:
                return existing_stacks_no_domain
        
        # If no existing stacks, create dynamic recommendations using tools and technologies
        return self.get_dynamic_recommendations(budget, domain, preferred_techs)
    
    def get_dynamic_recommendations(self, budget: float, domain: Optional[str] = None, preferred_techs: Optional[List[str]] = None):
        """Create dynamic recommendations using tools and technologies"""
        # Normalize domain for better matching
        normalized_domain = domain.lower().strip() if domain else None
        
        # Get tools within budget
        tools_query = """
        MATCH (tool:Tool)-[:BELONGS_TO_TIER]->(p:PriceTier)
        WHERE tool.monthly_cost_usd <= $budget
        RETURN tool.name as tool_name,
               tool.category as category,
               tool.monthly_cost_usd as monthly_cost,
               tool.total_cost_of_ownership_score as tco_score,
               tool.price_performance_ratio as price_performance,
               p.tier_name as price_tier
        ORDER BY tool.price_performance_ratio DESC, tool.monthly_cost_usd ASC
        LIMIT 20
        """
        
        tools = self.run_query(tools_query, {"budget": budget})
        
        # Get technologies by category (without pricing constraints)
        tech_categories = ["frontend", "backend", "database", "cloud", "testing", "mobile", "devops", "ai_ml"]
        recommendations = []
        
        # Create domain-specific recommendations
        domain_specific_stacks = self._create_domain_specific_stacks(normalized_domain, budget)
        if domain_specific_stacks:
            recommendations.extend(domain_specific_stacks)
        
        for category in tech_categories:
            tech_query = f"""
            MATCH (t:Technology {{category: '{category}'}})
            RETURN t.name as name,
                   t.category as category,
                   t.maturity_score as maturity_score,
                   t.learning_curve as learning_curve,
                   t.performance_rating as performance_rating,
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as price_performance
            ORDER BY t.total_cost_of_ownership_score DESC, t.maturity_score DESC
            LIMIT 3
            """
            
            technologies = self.run_query(tech_query)
            
            if technologies:
                # Create a recommendation entry for this category
                best_tech = technologies[0]
                recommendation = {
                    "stack_name": f"Dynamic {category.title()} Stack - {best_tech['name']}",
                    "monthly_cost": 0.0,  # Technologies don't have pricing
                    "setup_cost": 0.0,
                    "team_size_range": "2-5",
                    "development_time_months": 2,
                    "satisfaction_score": best_tech.get('tco_score') or 80,
                    "success_rate": best_tech.get('maturity_score') or 80,
                    "price_tier": "Custom",
                    "budget_efficiency": 100.0,
                    "recommendation_score": ((best_tech.get('tco_score') or 80) + (best_tech.get('maturity_score') or 80)) / 2
                }
                
                # Only add the technology field for the current category
                if category == 'frontend':
                    recommendation["frontend"] = best_tech['name']
                elif category == 'backend':
                    recommendation["backend"] = best_tech['name']
                elif category == 'database':
                    recommendation["database"] = best_tech['name']
                elif category == 'cloud':
                    recommendation["cloud"] = best_tech['name']
                elif category == 'testing':
                    recommendation["testing"] = best_tech['name']
                elif category == 'mobile':
                    recommendation["mobile"] = best_tech['name']
                elif category == 'devops':
                    recommendation["devops"] = best_tech['name']
                elif category == 'ai_ml':
                    recommendation["ai_ml"] = best_tech['name']
                recommendations.append(recommendation)
        
        # Add tool-based recommendations
        if tools:
            # Group tools by category and create recommendations
            tool_categories = {}
            for tool in tools:
                category = tool['category']
                if category not in tool_categories:
                    tool_categories[category] = []
                tool_categories[category].append(tool)
            
            for category, category_tools in tool_categories.items():
                if category_tools:
                    best_tool = category_tools[0]
                    total_cost = sum(t['monthly_cost'] for t in category_tools[:3])  # Top 3 tools
                    
                    # Check total first-year cost: (monthly_cost * 12) + setup_cost
                    total_first_year_cost = total_cost * 12 + (total_cost * 0.5)
                    if total_first_year_cost <= budget:
                        recommendation = {
                            "stack_name": f"Tool-based {category.title()} Stack - {best_tool['tool_name']}",
                            "monthly_cost": total_cost,
                            "setup_cost": total_cost * 0.5,
                            "team_size_range": "1-3",
                            "development_time_months": 1,
                            "satisfaction_score": best_tool.get('tco_score') or 80,
                            "success_rate": best_tool.get('price_performance') or 80,
                            "price_tier": best_tool.get('price_tier', 'Custom'),
                            "budget_efficiency": 100.0 - ((total_cost / budget) * 20) if budget > 0 else 100.0,
                            "recommendation_score": ((best_tool.get('tco_score') or 80) + (best_tool.get('price_performance') or 80)) / 2,
                            "tools": [t['tool_name'] for t in category_tools[:3]]
                        }
                        recommendations.append(recommendation)
        
        # Sort by recommendation score and return top 50
        recommendations.sort(key=lambda x: x['recommendation_score'], reverse=True)
        return recommendations[:50]
    
    def _create_domain_specific_stacks(self, domain: Optional[str], budget: float):
        """Create domain-specific technology stacks"""
        if not domain:
            return []
        
        # Domain-specific technology mappings
        domain_tech_mapping = {
            'healthcare': {
                'frontend': 'React',
                'backend': 'Django',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'TensorFlow'
            },
            'finance': {
                'frontend': 'Angular',
                'backend': 'Java Spring',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'JUnit',
                'mobile': 'Flutter',
                'devops': 'Kubernetes',
                'ai_ml': 'Scikit-learn'
            },
            'gaming': {
                'frontend': 'Unity',
                'backend': 'Node.js',
                'database': 'MongoDB',
                'cloud': 'AWS',
                'testing': 'Unity Test Framework',
                'mobile': 'Unity',
                'devops': 'Docker',
                'ai_ml': 'TensorFlow'
            },
            'education': {
                'frontend': 'React',
                'backend': 'Django',
                'database': 'PostgreSQL',
                'cloud': 'DigitalOcean',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'Scikit-learn'
            },
            'media': {
                'frontend': 'Next.js',
                'backend': 'Node.js',
                'database': 'MongoDB',
                'cloud': 'Vercel',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'Hugging Face'
            },
            'iot': {
                'frontend': 'React',
                'backend': 'Python',
                'database': 'InfluxDB',
                'cloud': 'AWS',
                'testing': 'Pytest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'TensorFlow'
            },
            'social': {
                'frontend': 'React',
                'backend': 'Node.js',
                'database': 'MongoDB',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'Hugging Face'
            },
            'elearning': {
                'frontend': 'Vue.js',
                'backend': 'Django',
                'database': 'PostgreSQL',
                'cloud': 'DigitalOcean',
                'testing': 'Jest',
                'mobile': 'Flutter',
                'devops': 'Docker',
                'ai_ml': 'Scikit-learn'
            },
            'realestate': {
                'frontend': 'React',
                'backend': 'Node.js',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'Not specified'
            },
            'travel': {
                'frontend': 'React',
                'backend': 'Node.js',
                'database': 'MongoDB',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'Not specified'
            },
            'manufacturing': {
                'frontend': 'Angular',
                'backend': 'Java Spring',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'JUnit',
                'mobile': 'Flutter',
                'devops': 'Kubernetes',
                'ai_ml': 'TensorFlow'
            }
        }
        
        # Get technology mapping for domain
        tech_mapping = domain_tech_mapping.get(domain)
        if not tech_mapping:
            return []
        
        # Create domain-specific stack
        stack = {
            "stack_name": f"Domain-Specific {domain.title()} Stack",
            "monthly_cost": min(budget * 0.8, 100.0),  # Use 80% of budget or max $100
            "setup_cost": min(budget * 0.4, 500.0),    # Use 40% of budget or max $500
            "team_size_range": "3-6",
            "development_time_months": 4,
            "satisfaction_score": 85,
            "success_rate": 88,
            "price_tier": "Custom",
            "recommended_domains": [domain.title()],
            "description": f"Specialized technology stack optimized for {domain} applications",
            "pros": [
                f"Optimized for {domain}",
                "Domain-specific features",
                "Proven technology choices",
                "Good performance"
            ],
            "cons": [
                "Domain-specific complexity",
                "Learning curve",
                "Customization needs"
            ],
            "frontend": tech_mapping['frontend'],
            "backend": tech_mapping['backend'],
            "database": tech_mapping['database'],
            "cloud": tech_mapping['cloud'],
            "testing": tech_mapping['testing'],
            "mobile": tech_mapping['mobile'],
            "devops": tech_mapping['devops'],
            "ai_ml": tech_mapping['ai_ml'],
            "recommendation_score": 90.0
        }
        
        return [stack]

    def get_available_domains(self):
        """Get all available domains from the database"""
        query = """
        MATCH (d:Domain)
        RETURN d.name as domain_name,
               d.project_scale as project_scale,
               d.team_experience_level as team_experience_level
        ORDER BY d.name
        """
        return self.run_query(query)

    def get_all_stacks(self):
        """Get all tech stacks in the database for debugging"""
        query = """
        MATCH (s:TechStack)
        RETURN s.name AS stack_name,
               s.monthly_cost AS monthly_cost,
               s.setup_cost AS setup_cost,
               s.team_size_range AS team_size,
               s.development_time_months AS development_time,
               s.satisfaction_score AS satisfaction,
               s.success_rate AS success_rate,
               s.price_tier AS price_tier,
               s.recommended_domains AS recommended_domains,
               s.description AS description,
               s.pros AS pros,
               s.cons AS cons,
               s.frontend_tech AS frontend,
               s.backend_tech AS backend,
               s.database_tech AS database,
               s.cloud_tech AS cloud,
               s.testing_tech AS testing,
               s.mobile_tech AS mobile,
               s.devops_tech AS devops,
               s.ai_ml_tech AS ai_ml,
               exists((s)-[:BELONGS_TO_TIER]->()) as has_price_tier,
               exists((s)-[:USES_FRONTEND]->()) as has_frontend,
               exists((s)-[:USES_BACKEND]->()) as has_backend,
               exists((s)-[:USES_DATABASE]->()) as has_database,
               exists((s)-[:USES_CLOUD]->()) as has_cloud
        ORDER BY s.name
        """
        return self.run_query(query)

    def get_technologies_by_price_tier(self, tier_name: str):
        """Get technologies for a specific price tier"""
        query = f"""
        MATCH (t:{self.get_namespaced_label('Technology')})-[:{self.get_namespaced_relationship('BELONGS_TO_TIER')}]->(p:{self.get_namespaced_label('PriceTier')} {{tier_name: $tier_name}})
        RETURN t.name as name,
               t.category as category,
               t.monthly_cost_usd as monthly_cost,
               t.total_cost_of_ownership_score as tco_score,
               t.price_performance_ratio as price_performance,
               t.maturity_score as maturity_score,
               t.learning_curve as learning_curve
        ORDER BY t.total_cost_of_ownership_score DESC, t.monthly_cost_usd ASC
        """
        return self.run_query(query, {"tier_name": tier_name})

    def get_tools_by_price_tier(self, tier_name: str):
        """Get tools for a specific price tier"""
        query = f"""
        MATCH (tool:{self.get_namespaced_label('Tool')})-[:{self.get_namespaced_relationship('BELONGS_TO_TIER')}]->(p:{self.get_namespaced_label('PriceTier')} {{tier_name: $tier_name}})
        RETURN tool.name as name,
               tool.category as category,
               tool.monthly_cost_usd as monthly_cost,
               tool.total_cost_of_ownership_score as tco_score,
               tool.price_performance_ratio as price_performance,
               tool.popularity_score as popularity_score
        ORDER BY tool.price_performance_ratio DESC, tool.monthly_cost_usd ASC
        """
        return self.run_query(query, {"tier_name": tier_name})

    def get_price_tier_analysis(self):
        """Get analysis of all price tiers"""
        query = f"""
        MATCH (p:{self.get_namespaced_label('PriceTier')})
        OPTIONAL MATCH (p)<-[:{self.get_namespaced_relationship('BELONGS_TO_TIER')}]-(t:{self.get_namespaced_label('Technology')})
        OPTIONAL MATCH (p)<-[:{self.get_namespaced_relationship('BELONGS_TO_TIER')}]-(tool:{self.get_namespaced_label('Tool')})
        OPTIONAL MATCH (p)<-[:{self.get_namespaced_relationship('BELONGS_TO_TIER')}]-(s:{self.get_namespaced_label('TechStack')})
        
        RETURN p.tier_name as tier_name,
               p.min_price_usd as min_price,
               p.max_price_usd as max_price,
               p.target_audience as target_audience,
               p.typical_project_scale as project_scale,
               count(DISTINCT t) as technology_count,
               count(DISTINCT tool) as tool_count,
               count(DISTINCT s) as stack_count,
               avg(t.monthly_cost_usd) as avg_tech_cost,
               avg(tool.monthly_cost_usd) as avg_tool_cost
        ORDER BY p.min_price_usd
        """
        return self.run_query(query)

    def get_optimal_combinations(self, budget: float, category: str):
        """Get optimal technology combinations within budget for a category"""
        query = """
        MATCH (t:Technology {category: $category})-[:BELONGS_TO_TIER]->(p:PriceTier)
        WHERE t.monthly_cost_usd <= $budget
        RETURN t.name as name,
               t.monthly_cost_usd as monthly_cost,
               t.total_cost_of_ownership_score as tco_score,
               t.price_performance_ratio as price_performance,
               p.tier_name as price_tier,
               (t.total_cost_of_ownership_score * 0.6 + t.price_performance_ratio * 0.4) as combined_score
        ORDER BY combined_score DESC, t.monthly_cost_usd ASC
        LIMIT 10
        """
        return self.run_query(query, {"budget": budget, "category": category})

    def get_compatibility_analysis(self, tech_name: str):
        """Get compatibility analysis for a specific technology"""
        query = """
        MATCH (t:Technology {name: $tech_name})-[r:COMPATIBLE_WITH]-(compatible:Technology)
        RETURN compatible.name as compatible_tech,
               compatible.category as category,
               r.compatibility_score as score,
               r.integration_effort as effort,
               r.reason as reason
        ORDER BY r.compatibility_score DESC
        """
        return self.run_query(query, {"tech_name": tech_name})

    def validate_data_integrity(self):
        """Validate the integrity of migrated data"""
        query = """
        MATCH (s:TechStack)
        RETURN s.name as stack_name,
               exists((s)-[:BELONGS_TO_TIER]->()) as has_price_tier,
               exists((s)-[:USES_FRONTEND]->()) as has_frontend,
               exists((s)-[:USES_BACKEND]->()) as has_backend,
               exists((s)-[:USES_DATABASE]->()) as has_database,
               exists((s)-[:USES_CLOUD]->()) as has_cloud,
               s.monthly_cost as monthly_cost,
               s.price_tier as price_tier
        ORDER BY s.monthly_cost
        """
        return self.run_query(query)

    def get_optimized_single_recommendation(self, budget: float, domain: str, claude_service):
        """Get a single optimized tech stack recommendation using Claude AI and Neo4j"""
        # Normalize domain for better matching
        normalized_domain = domain.lower().strip()
        
        # First, try to get existing Claude recommendation from Neo4j
        existing_claude_rec = self.get_claude_recommendation(normalized_domain, budget)
        if existing_claude_rec:
            logger.info(f"Found existing Claude recommendation for {domain} with budget ${budget}")
            return {
                "monthly_cost": existing_claude_rec.get("monthly_cost", 0.0),
                "setup_cost": existing_claude_rec.get("setup_cost", 0.0),
                "frontend": existing_claude_rec.get("frontend", "Unknown"),
                "backend": existing_claude_rec.get("backend", "Unknown"),
                "database": existing_claude_rec.get("database", "Unknown"),
                "cloud": existing_claude_rec.get("cloud", "Unknown"),
                "testing": existing_claude_rec.get("testing", "Unknown"),
                "mobile": existing_claude_rec.get("mobile", "Unknown"),
                "devops": existing_claude_rec.get("devops", "Unknown"),
                "ai_ml": existing_claude_rec.get("ai_ml", "None"),
                "recommendation_score": 95.0,  # High score for Claude recommendations
                "source": "claude_cached"
            }
        
        # If no existing Claude recommendation, generate new one
        logger.info(f"Generating new Claude recommendation for {domain} with budget ${budget}")
        claude_recommendation = claude_service.generate_tech_stack_recommendation(domain, budget)
        
        if claude_recommendation:
            # Store the new recommendation in Neo4j
            self.store_claude_recommendation(normalized_domain, budget, claude_recommendation)
            
            return {
                "monthly_cost": claude_recommendation.get("monthly_cost_estimate", budget * 0.6 / 12),
                "setup_cost": claude_recommendation.get("setup_cost_estimate", budget * 0.4),
                "frontend": claude_recommendation.get("frontend", "Unknown"),
                "backend": claude_recommendation.get("backend", "Unknown"),
                "database": claude_recommendation.get("database", "Unknown"),
                "cloud": claude_recommendation.get("cloud", "Unknown"),
                "testing": claude_recommendation.get("testing", "Unknown"),
                "mobile": claude_recommendation.get("mobile", "Unknown"),
                "devops": claude_recommendation.get("devops", "Unknown"),
                "ai_ml": claude_recommendation.get("ai_ml", "None"),
                "recommendation_score": 90.0,  # High score for fresh Claude recommendations
                "source": "claude_fresh"
            }
        
        # Get recommendations from Knowledge Graph only
        logger.info(f"Getting recommendations from Knowledge Graph for {domain} with budget ${budget}")
        return self._get_kg_recommendations(budget, normalized_domain)
    
    def _get_kg_recommendations(self, budget: float, domain: str):
        """Get recommendations from Knowledge Graph only"""
        try:
            query = """
            MATCH (s:TechStack)-[:BELONGS_TO_TIER]->(p:PriceTier)
            WHERE p.min_price_usd <= $budget AND p.max_price_usd >= $budget
            AND ($domain IS NULL OR 
                 toLower(s.name) CONTAINS $normalized_domain OR
                 toLower(s.description) CONTAINS $normalized_domain OR
                 EXISTS { MATCH (d:Domain)-[:RECOMMENDS]->(s) WHERE toLower(d.name) = $normalized_domain } OR
                 ANY(rd IN s.recommended_domains WHERE toLower(rd) CONTAINS $normalized_domain))
            
            OPTIONAL MATCH (s)-[:USES_FRONTEND]->(frontend:Technology)
            OPTIONAL MATCH (s)-[:USES_BACKEND]->(backend:Technology)
            OPTIONAL MATCH (s)-[:USES_DATABASE]->(database:Technology)
            OPTIONAL MATCH (s)-[:USES_CLOUD]->(cloud:Technology)
            OPTIONAL MATCH (s)-[:USES_TESTING]->(testing:Technology)
            OPTIONAL MATCH (s)-[:USES_MOBILE]->(mobile:Technology)
            OPTIONAL MATCH (s)-[:USES_DEVOPS]->(devops:Technology)
            OPTIONAL MATCH (s)-[:USES_AI_ML]->(ai_ml:Technology)
            
            RETURN s.name AS stack_name,
                   ($budget * 0.6 / 12) AS monthly_cost,
                   ($budget * 0.4) AS setup_cost,
                   COALESCE(frontend.name, s.frontend_tech) AS frontend,
                   COALESCE(backend.name, s.backend_tech) AS backend,
                   COALESCE(database.name, s.database_tech) AS database,
                   COALESCE(cloud.name, s.cloud_tech) AS cloud,
                   COALESCE(testing.name, s.testing_tech) AS testing,
                   COALESCE(mobile.name, s.mobile_tech) AS mobile,
                   COALESCE(devops.name, s.devops_tech) AS devops,
                   COALESCE(ai_ml.name, s.ai_ml_tech) AS ai_ml,
                   p.tier_name AS price_tier,
                   75.0 AS recommendation_score
            ORDER BY (s.monthly_cost * 12 + s.setup_cost) ASC
            LIMIT 1
            """
            
            result = self.run_query(query, {
                "budget": budget,
                "domain": domain,
                "normalized_domain": domain
            })
            
            if result:
                return result[0]
            
            # Final fallback to domain mapping
            return self._create_dynamic_single_recommendation(budget, domain, None)
            
        except Exception as e:
            logger.error(f"Error in fallback recommendation: {e}")
            return self._create_dynamic_single_recommendation(budget, domain, None)
    
    def _create_dynamic_single_recommendation(self, budget: float, domain: str, preferred_techs: Optional[List[str]] = None):
        """Create a dynamic single recommendation when no existing stacks match"""
        # Get domain-specific technology mapping
        domain_tech_mapping = self._get_domain_tech_mapping(domain)
        
        # Calculate monthly cost based on budget (use 60% of budget for monthly, 40% for setup)
        monthly_cost = budget * 0.6 / 12  # Convert annual budget to monthly
        setup_cost = budget * 0.4
        
        # PROFESSIONAL FIX: Use professional database, frontend, backend, cloud, testing, and mobile selection algorithms
        professional_database = self.get_professional_database_selection(budget, domain)
        professional_frontend = self.get_professional_frontend_selection(budget, domain)
        professional_backend = self.get_professional_backend_selection(budget, domain)
        professional_cloud = self.get_professional_cloud_selection(budget, domain)
        professional_testing = self.get_professional_testing_selection(budget, domain)
        professional_mobile = self.get_professional_mobile_selection(budget, domain)


        professional_devops = self.get_professional_devops_selection(budget, domain)
        
        # Create recommendation with domain-specific technologies
        professional_ai_ml = self.get_professional_ai_ml_selection(budget, domain)
        professional_tool = self.get_professional_tool_selection(budget, domain)
        
        # Determine price tier based on budget
        price_tier = self._get_price_tier_for_budget(budget)
        
        recommendation = {
            "stack_name": f"Custom {domain.title()} Stack",
            "monthly_cost": round(monthly_cost, 2),
            "setup_cost": round(setup_cost, 2),
            "price_tier": price_tier,  # PROFESSIONAL FIX: Add price tier based on budget
            "frontend": professional_frontend,  # PROFESSIONAL FIX: Use professional frontend selection
            "backend": professional_backend,  # PROFESSIONAL FIX: Use professional backend selection
            "database": professional_database,  # PROFESSIONAL FIX: Use professional database selection
            "cloud": professional_cloud,  # PROFESSIONAL FIX: Use professional cloud selection
            "testing": professional_testing,  # PROFESSIONAL FIX: Use professional testing selection
            "mobile": professional_mobile,  # PROFESSIONAL FIX: Use professional mobile selection
            "devops": professional_devops,  # PROFESSIONAL FIX: Use professional DevOps selection
            "ai_ml": professional_ai_ml,  # PROFESSIONAL FIX: Use professional AI/ML selection
            "tool": professional_tool,  # PROFESSIONAL FIX: Use professional tool selection
            "recommendation_score": 75.0
        }
        
        # Apply preferred technologies if they match domain mapping
        if preferred_techs:
            preference_score = 0
            for tech in preferred_techs:
                tech_lower = tech.lower()
                if 'vue' in tech_lower and 'frontend' in domain_tech_mapping:
                    recommendation["frontend"] = tech
                    preference_score += 5
                elif 'django' in tech_lower and 'backend' in domain_tech_mapping:
                    recommendation["backend"] = tech
                    preference_score += 5
                elif 'redis' in tech_lower and 'database' in domain_tech_mapping:
                    recommendation["database"] = tech
                    preference_score += 5
            
            recommendation["recommendation_score"] = min(95.0, 75.0 + preference_score)
        
        return recommendation
    
    def _get_price_tier_for_budget(self, budget: float):
        """Get the appropriate price tier for a given budget"""
        if budget <= 25.0:
            return "Micro Budget"
        elif budget <= 100.0:
            return "Startup Budget"
        elif budget <= 300.0:
            return "Small Business"
        elif budget <= 600.0:
            return "Growth Stage"
        elif budget <= 1000.0:
            return "Scale-Up"
        elif budget <= 2000.0:
            return "Enterprise"
        elif budget <= 5000.0:
            return "Premium"
        elif budget <= 10000.0:
            return "Corporate"
        elif budget <= 20000.0:
            return "Enterprise Plus"
        elif budget <= 35000.0:
            return "Fortune 500"
        elif budget <= 50000.0:
            return "Global Enterprise"
        elif budget <= 75000.0:
            return "Mega Enterprise"
        else:
            return "Ultra Enterprise"
    
    def _get_domain_tech_mapping(self, domain: str):
        """Get technology mapping for a specific domain"""
        domain_tech_mapping = {
            'healthcare': {
                'frontend': 'React',
                'backend': 'Django',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'TensorFlow'
            },
            'finance': {
                'frontend': 'Angular',
                'backend': 'Java Spring',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'JUnit',
                'mobile': 'Flutter',
                'devops': 'Kubernetes',
                'ai_ml': 'Scikit-learn'
            },
            'gaming': {
                'frontend': 'Unity',
                'backend': 'Node.js',
                'database': 'MongoDB',
                'cloud': 'AWS',
                'testing': 'Unity Test Framework',
                'mobile': 'Unity',
                'devops': 'Docker',
                'ai_ml': 'TensorFlow'
            },
            'education': {
                'frontend': 'React',
                'backend': 'Django',
                'database': 'PostgreSQL',
                'cloud': 'DigitalOcean',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'Scikit-learn'
            },
            'media': {
                'frontend': 'Next.js',
                'backend': 'Node.js',
                'database': 'MongoDB',
                'cloud': 'Vercel',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'Hugging Face'
            },
            'iot': {
                'frontend': 'React',
                'backend': 'Python',
                'database': 'InfluxDB',
                'cloud': 'AWS',
                'testing': 'Pytest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'TensorFlow'
            },
            'social': {
                'frontend': 'React',
                'backend': 'Node.js',
                'database': 'MongoDB',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'Hugging Face'
            },
            'elearning': {
                'frontend': 'Vue.js',
                'backend': 'Django',
                'database': 'PostgreSQL',
                'cloud': 'DigitalOcean',
                'testing': 'Jest',
                'mobile': 'Flutter',
                'devops': 'Docker',
                'ai_ml': 'Scikit-learn'
            },
            'realestate': {
                'frontend': 'React',
                'backend': 'Node.js',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'None'
            },
            'travel': {
                'frontend': 'React',
                'backend': 'Node.js',
                'database': 'MongoDB',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'None'
            },
            'manufacturing': {
                'frontend': 'Angular',
                'backend': 'Java Spring',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'JUnit',
                'mobile': 'Flutter',
                'devops': 'Kubernetes',
                'ai_ml': 'TensorFlow'
            },
            'ecommerce': {
                'frontend': 'React',
                'backend': 'Node.js',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'None'
            },
            'saas': {
                'frontend': 'React',
                'backend': 'Node.js',
                'database': 'PostgreSQL',
                'cloud': 'AWS',
                'testing': 'Jest',
                'mobile': 'React Native',
                'devops': 'Docker',
                'ai_ml': 'None'
            }
        }
        
        return domain_tech_mapping.get(domain.lower(), {
            'frontend': 'HTML/CSS + JavaScript',
            'backend': 'Node.js',
            'database': 'SQLite',
            'cloud': 'GitHub Pages',
            'testing': 'Jest',
            'mobile': 'Responsive Design',
            'devops': 'Git',
            'ai_ml': 'None'
        })
    
    def store_claude_recommendation(self, domain: str, budget: float, recommendation: dict):
        """Store Claude-generated recommendation in Neo4j"""
        try:
            query = """
            MERGE (d:Domain {name: $domain})
            CREATE (s:ClaudeTechStack {
                name: $stack_name,
                domain: $domain,
                budget: $budget,
                frontend: $frontend,
                backend: $backend,
                database: $database,
                cloud: $cloud,
                testing: $testing,
                mobile: $mobile,
                devops: $devops,
                ai_ml: $ai_ml,
                reasoning: $reasoning,
                monthly_cost: $monthly_cost,
                setup_cost: $setup_cost,
                created_at: datetime(),
                source: 'claude_ai'
            })
            CREATE (d)-[:HAS_CLAUDE_RECOMMENDATION]->(s)
            RETURN s.name as stack_name
            """
            
            result = self.run_query(query, {
                "domain": domain,
                "budget": budget,
                "stack_name": f"Claude {domain.title()} Stack - ${budget}",
                "frontend": recommendation.get("frontend", "Unknown"),
                "backend": recommendation.get("backend", "Unknown"),
                "database": recommendation.get("database", "Unknown"),
                "cloud": recommendation.get("cloud", "Unknown"),
                "testing": recommendation.get("testing", "Unknown"),
                "mobile": recommendation.get("mobile", "Unknown"),
                "devops": recommendation.get("devops", "Unknown"),
                "ai_ml": recommendation.get("ai_ml", "None"),
                "reasoning": recommendation.get("reasoning", ""),
                "monthly_cost": recommendation.get("monthly_cost_estimate", 0.0),
                "setup_cost": recommendation.get("setup_cost_estimate", 0.0)
            })
            
            logger.info(f"Stored Claude recommendation for {domain} with budget ${budget}")
            return True
            
        except Exception as e:
            logger.error(f"Error storing Claude recommendation: {e}")
            return False
    
    def get_claude_recommendation(self, domain: str, budget: float):
        """Get existing Claude recommendation from Neo4j"""
        try:
            query = """
            MATCH (d:Domain {name: $domain})-[:HAS_CLAUDE_RECOMMENDATION]->(s:ClaudeTechStack)
            WHERE s.budget = $budget
            RETURN s.name as stack_name,
                   s.frontend as frontend,
                   s.backend as backend,
                   s.database as database,
                   s.cloud as cloud,
                   s.testing as testing,
                   s.mobile as mobile,
                   s.devops as devops,
                   s.ai_ml as ai_ml,
                   s.reasoning as reasoning,
                   s.monthly_cost as monthly_cost,
                   s.setup_cost as setup_cost,
                   s.created_at as created_at
            ORDER BY s.created_at DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {
                "domain": domain,
                "budget": budget
            })
            
            if result:
                return result[0]
            return None
            
        except Exception as e:
            logger.error(f"Error getting Claude recommendation: {e}")
            return None

    def _get_tools_from_kg(self, budget: float, domain: str):
        """Get domain-specific tools from Knowledge Graph based on budget"""
        try:
            # Normalize domain for better matching
            normalized_domain = domain.lower().strip() if domain else None
            
            # Map domain to tool categories
            domain_tool_categories = {
                'ecommerce': ['e-commerce', 'marketing', 'analytics', 'crm'],
                'e-commerce': ['e-commerce', 'marketing', 'analytics', 'crm'],
                'saas': ['crm', 'analytics', 'business-intelligence', 'customer-support'],
                'finance': ['analytics', 'business-intelligence', 'crm'],
                'healthcare': ['analytics', 'business-intelligence', 'crm'],
                'education': ['analytics', 'business-intelligence', 'crm'],
                'gaming': ['analytics', 'marketing'],
                'media': ['analytics', 'marketing', 'design'],
                'social': ['analytics', 'marketing', 'customer-support'],
                'travel': ['analytics', 'marketing', 'crm'],
                'realestate': ['analytics', 'marketing', 'crm']
            }
            
            # Get relevant categories for the domain
            relevant_categories = domain_tool_categories.get(normalized_domain, ['analytics', 'marketing', 'crm'])
            
            # Query tools from KG based on budget and domain (prioritize domain-specific tools)
            query = """
            MATCH (t:Tool)-[:BELONGS_TO_TIER]->(p:PriceTier)
            WHERE p.min_price_usd <= $budget AND p.max_price_usd >= $budget
            AND t.category IN $categories
            RETURN t.name as tool_name, t.category as category,
                   CASE 
                     WHEN t.category = 'e-commerce' AND $normalized_domain CONTAINS 'commerce' THEN 1
                     WHEN t.category = 'crm' AND $normalized_domain CONTAINS 'saas' THEN 2
                     WHEN t.category = 'analytics' AND ($normalized_domain CONTAINS 'finance' OR $normalized_domain CONTAINS 'gaming' OR $normalized_domain CONTAINS 'healthcare' OR $normalized_domain CONTAINS 'education' OR $normalized_domain CONTAINS 'travel' OR $normalized_domain CONTAINS 'realestate' OR $normalized_domain CONTAINS 'social' OR $normalized_domain CONTAINS 'media') THEN 3
                     WHEN t.category = 'marketing' AND ($normalized_domain CONTAINS 'gaming' OR $normalized_domain CONTAINS 'social' OR $normalized_domain CONTAINS 'media') THEN 4
                     WHEN t.category = 'design' AND $normalized_domain CONTAINS 'media' THEN 5
                     ELSE 6
                   END as priority
            ORDER BY priority ASC, t.name
            LIMIT 1
            """
            
            result = self.run_query(query, {
                "budget": budget,
                "categories": relevant_categories,
                "normalized_domain": normalized_domain
            })
            
            if result:
                return result[0]['tool_name']
            
            # Fallback: get any tools within budget
            fallback_query = """
            MATCH (t:Tool)-[:BELONGS_TO_TIER]->(p:PriceTier)
            WHERE p.min_price_usd <= $budget AND p.max_price_usd >= $budget
            RETURN t.name as tool_name
            ORDER BY t.name
            LIMIT 1
            """
            
            fallback_result = self.run_query(fallback_query, {"budget": budget})
            if fallback_result:
                return fallback_result[0]['tool_name']
            
            # Final fallback: return domain-specific default tools
            return self._get_domain_default_tools(normalized_domain)
            
        except Exception as e:
            logger.error(f"Error getting tools from KG: {e}")
            return self._get_domain_default_tools(domain)
    
    def _get_domain_default_tools(self, domain: str):
        """Get default tools for domain when KG query fails"""
        domain_defaults = {
            'ecommerce': 'Shopify',
            'e-commerce': 'Shopify',
            'saas': 'Salesforce CRM',
            'finance': 'Tableau',
            'healthcare': 'Tableau',
            'education': 'Google Analytics',
            'gaming': 'Google Analytics',
            'media': 'Google Analytics',
            'social': 'Google Analytics',
            'travel': 'Google Analytics',
            'realestate': 'Google Analytics'
        }
        
        return domain_defaults.get(domain.lower() if domain else 'general', 'Google Analytics')

    def get_professional_database_selection(self, budget: float, domain: str = None):
        """Professional database selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Query Neo4j for appropriate database technology based on budget and domain
            # For higher budgets, we want more sophisticated technologies
            query = """
            MATCH (t:Technology {category: 'database'})
            MATCH (p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            RETURN t.name as name, t.monthly_cost_usd as cost, 
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {"budget": budget})
            
            if result and len(result) > 0:
                logger.info(f"Database selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level
                if budget >= 1000:
                    return "PostgreSQL"
                elif budget >= 500:
                    return "MySQL"
                else:
                    return "SQLite"
                
        except Exception as e:
            logger.error(f"Error getting database selection from Neo4j: {e}")
            # Fallback based on budget level
            if budget >= 1000:
                return "PostgreSQL"
            elif budget >= 500:
                return "MySQL"
            else:
                return "SQLite"

    def get_professional_frontend_selection(self, budget: float, domain: str = None):
        """Professional frontend selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Query Neo4j for appropriate frontend technology based on budget and domain
            query = """
            MATCH (t:Technology {category: 'frontend'})
            MATCH (p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            RETURN t.name as name, t.monthly_cost_usd as cost, 
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {"budget": budget})
            
            if result and len(result) > 0:
                logger.info(f"Frontend selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level
                if budget >= 1000:
                    return "React"
                elif budget >= 500:
                    return "Vue.js"
                else:
                    return "HTML/CSS + JavaScript"
                
        except Exception as e:
            logger.error(f"Error getting frontend selection from Neo4j: {e}")
            # Fallback based on budget level
            if budget >= 1000:
                return "React"
            elif budget >= 500:
                return "Vue.js"
            else:
                return "HTML/CSS + JavaScript"

    def get_professional_backend_selection(self, budget: float, domain: str = None):
        """Professional backend selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Query Neo4j for appropriate backend technology based on budget and domain
            query = """
            MATCH (t:Technology {category: 'backend'})
            MATCH (p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            RETURN t.name as name, t.monthly_cost_usd as cost, 
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {"budget": budget})
            
            if result and len(result) > 0:
                logger.info(f"Backend selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level
                if budget >= 1000:
                    return "Java Spring Boot"
                elif budget >= 500:
                    return "Python Django"
                else:
                    return "Node.js"
                
        except Exception as e:
            logger.error(f"Error getting backend selection from Neo4j: {e}")
            # Fallback based on budget level
            if budget >= 1000:
                return "Java Spring Boot"
            elif budget >= 500:
                return "Python Django"
            else:
                return "Node.js"

    def get_professional_cloud_selection(self, budget: float, domain: str = None):
        """Professional cloud selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Query Neo4j for appropriate cloud technology based on budget and domain
            query = """
            MATCH (t:Technology {category: 'cloud'})
            MATCH (p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            RETURN t.name as name, t.monthly_cost_usd as cost, 
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {"budget": budget})
            
            if result and len(result) > 0:
                logger.info(f"Cloud selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level
                if budget >= 1000:
                    return "AWS"
                elif budget >= 500:
                    return "DigitalOcean"
                else:
                    return "GitHub Pages"
                
        except Exception as e:
            logger.error(f"Error getting cloud selection from Neo4j: {e}")
            # Fallback based on budget level
            if budget >= 1000:
                return "AWS"
            elif budget >= 500:
                return "DigitalOcean"
            else:
                return "GitHub Pages"

    def get_professional_testing_selection(self, budget: float, domain: str = None):
        """Professional testing selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Query Neo4j for appropriate testing technology based on budget and domain
            query = """
            MATCH (t:Technology {category: 'testing'})
            MATCH (p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            RETURN t.name as name, t.monthly_cost_usd as cost, 
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {"budget": budget})
            
            if result and len(result) > 0:
                logger.info(f"Testing selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level
                if budget >= 1000:
                    return "Selenium"
                elif budget >= 500:
                    return "Cypress"
                else:
                    return "Jest"
                
        except Exception as e:
            logger.error(f"Error getting testing selection from Neo4j: {e}")
            # Fallback based on budget level
            if budget >= 1000:
                return "Selenium"
            elif budget >= 500:
                return "Cypress"
            else:
                return "Jest"

    def get_professional_mobile_selection(self, budget: float, domain: str = None):
        """Professional mobile selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Query Neo4j for appropriate mobile technology based on budget and domain
            query = """
            MATCH (t:Technology {category: 'mobile'})
            MATCH (p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            RETURN t.name as name, t.monthly_cost_usd as cost, 
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {"budget": budget})
            
            if result and len(result) > 0:
                logger.info(f"Mobile selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level
                if budget >= 1000:
                    return "Flutter"
                elif budget >= 500:
                    return "React Native"
                else:
                    return "React Native"
                
        except Exception as e:
            logger.error(f"Error getting mobile selection from Neo4j: {e}")
            # Fallback based on budget level
            if budget >= 1000:
                return "Flutter"
            elif budget >= 500:
                return "React Native"
            else:
                return "React Native"

    def get_professional_devops_selection(self, budget: float, domain: str = None):
        """Professional DevOps selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Query Neo4j for appropriate DevOps technology based on budget and domain
            query = """
            MATCH (t:Technology {category: 'devops'})
            MATCH (p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            RETURN t.name as name, t.monthly_cost_usd as cost, 
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {"budget": budget})
            
            if result and len(result) > 0:
                logger.info(f"DevOps selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level
                if budget >= 1000:
                    return "Kubernetes"
                elif budget >= 500:
                    return "Docker"
                else:
                    return "Git"
                
        except Exception as e:
            logger.error(f"Error getting DevOps selection from Neo4j: {e}")
            # Fallback based on budget level
            if budget >= 1000:
                return "Kubernetes"
            elif budget >= 500:
                return "Docker"
            else:
                return "Git"

    def get_professional_ai_ml_selection(self, budget: float, domain: str = None):
        """Professional AI/ML selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Query Neo4j for appropriate AI/ML technology based on budget and domain
            query = """
            MATCH (t:Technology {category: 'ai_ml'})
            MATCH (p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            RETURN t.name as name, t.monthly_cost_usd as cost, 
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {"budget": budget})
            
            if result and len(result) > 0:
                logger.info(f"AI/ML selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level
                if budget >= 1000:
                    return "TensorFlow"
                elif budget >= 500:
                    return "Scikit-learn"
                else:
                    return "Hugging Face"
                
        except Exception as e:
            logger.error(f"Error getting AI/ML selection from Neo4j: {e}")
            # Fallback based on budget level
            if budget >= 1000:
                return "TensorFlow"
            elif budget >= 500:
                return "Scikit-learn"
            else:
                return "Hugging Face"

    def get_professional_tool_selection(self, budget: float, domain: str = None):
        """Professional tool selection from Neo4j knowledge graph - 30+ years experience logic"""
        
        try:
            # Normalize domain for better matching
            normalized_domain = domain.lower().strip() if domain else 'general'
            
            # Domain-specific tool categories
            domain_tool_categories = {
                'ecommerce': ['e-commerce', 'analytics', 'marketing'],
                'healthcare': ['analytics', 'crm', 'security'],
                'finance': ['analytics', 'security', 'crm'],
                'education': ['analytics', 'crm', 'marketing'],
                'realestate': ['analytics', 'crm', 'marketing'],
                'general': ['analytics', 'marketing', 'crm']
            }
            
            # Get relevant categories for the domain
            relevant_categories = domain_tool_categories.get(normalized_domain, ['analytics', 'marketing', 'crm'])
            
            # Query Neo4j for appropriate tool based on budget and domain
            query = """
            MATCH (t:Tool)-[:BELONGS_TO_TIER]->(p:PriceTier)
            WHERE p.min_price_usd <= $budget
            AND p.max_price_usd >= $budget
            AND t.monthly_cost_usd <= $budget
            AND t.category IN $categories
            RETURN t.name as name, t.category as category,
                   t.monthly_cost_usd as cost,
                   t.total_cost_of_ownership_score as tco_score,
                   t.price_performance_ratio as performance_score,
                   p.tier_name as tier_name
            ORDER BY 
                CASE 
                    WHEN $budget >= 1000 THEN t.total_cost_of_ownership_score
                    WHEN $budget >= 500 THEN t.price_performance_ratio
                    ELSE t.monthly_cost_usd
                END DESC,
                t.total_cost_of_ownership_score DESC
            LIMIT 1
            """
            
            result = self.run_query(query, {
                "budget": budget,
                "categories": relevant_categories
            })
            
            if result and len(result) > 0:
                logger.info(f"Tool selection for budget ${budget}: {result[0]['name']} (tier: {result[0].get('tier_name', 'Unknown')})")
                return result[0]['name']
            else:
                # Fallback based on budget level and domain
                if budget >= 1000:
                    if normalized_domain == 'ecommerce':
                        return "Shopify"
                    elif normalized_domain in ['healthcare', 'finance']:
                        return "Tableau"
                    else:
                        return "Google Analytics"
                elif budget >= 500:
                    if normalized_domain == 'ecommerce':
                        return "BigCommerce"
                    else:
                        return "Google Analytics"
                else:
                    if normalized_domain == 'ecommerce':
                        return "Squarespace Commerce"
                    else:
                        return "Google Analytics"
                
        except Exception as e:
            logger.error(f"Error getting tool selection from Neo4j: {e}")
            # Fallback based on budget level and domain
            if budget >= 1000:
                return "Shopify"
            elif budget >= 500:
                return "BigCommerce"
            else:
                return "Google Analytics"

    def get_single_recommendation_from_kg(self, budget: float, domain: str):
        """Get a single tech stack recommendation from Knowledge Graph based on budget"""
        
        logger.info(f"🚀 UPDATED METHOD CALLED: get_single_recommendation_from_kg with budget=${budget}, domain={domain}")
        
        # CRITICAL BUDGET VALIDATION: For very low budgets, use budget-aware static recommendations
        # This MUST be the first check to prevent inappropriate enterprise technologies
        # PROFESSIONAL 30+ YEARS EXPERIENCE: Micro budgets require completely different approach
        # SIMPLE BUDGET VALIDATION - Revert to working approach
        if budget <= 5:
            logger.info(f"🚨 ULTRA-MICRO BUDGET ${budget} DETECTED - FORCING BUDGET-AWARE STATIC RECOMMENDATION")
            return self._create_static_fallback_recommendation(budget, domain)
        elif budget <= 10:
            logger.info(f"🚨 MICRO BUDGET ${budget} DETECTED - FORCING BUDGET-AWARE STATIC RECOMMENDATION")
            return self._create_static_fallback_recommendation(budget, domain)
        elif budget <= 25:
            logger.info(f"🚨 LOW BUDGET ${budget} DETECTED - FORCING BUDGET-AWARE STATIC RECOMMENDATION")
            return self._create_static_fallback_recommendation(budget, domain)
        
        logger.info(f"🔍 DEBUG: Budget ${budget} is above threshold, proceeding to KG query")
        
        try:
            # Normalize domain for better matching
            normalized_domain = domain.lower().strip() if domain else None
            domain_variations = []
            if normalized_domain:
                domain_variations.append(normalized_domain)
                if 'commerce' in normalized_domain:
                    domain_variations.extend(['e-commerce', 'ecommerce', 'online stores', 'product catalogs', 'marketplaces'])
                elif 'saas' in normalized_domain:
                    domain_variations.extend(['software as a service', 'web applications', 'business tools'])
                elif 'finance' in normalized_domain:
                    domain_variations.extend(['fintech', 'banking', 'financial services'])
                elif 'health' in normalized_domain:
                    domain_variations.extend(['healthcare', 'medical', 'health tech'])
                elif 'education' in normalized_domain:
                    domain_variations.extend(['edtech', 'learning', 'educational'])
                elif 'game' in normalized_domain:
                    domain_variations.extend(['gaming', 'entertainment', 'interactive'])
                elif 'media' in normalized_domain:
                    domain_variations.extend(['content', 'publishing', 'streaming'])
                elif 'social' in normalized_domain:
                    domain_variations.extend(['social media', 'networking', 'community'])
                elif 'travel' in normalized_domain:
                    domain_variations.extend(['tourism', 'hospitality', 'booking'])
                elif 'real' in normalized_domain:
                    domain_variations.extend(['real estate', 'property', 'housing'])
            
            # Enhanced Knowledge Graph query with PROFESSIONAL budget-appropriate filtering
            # For micro budgets, we need to be extremely strict about technology appropriateness
            query = """
            MATCH (s:TechStack)-[:BELONGS_TO_TIER]->(p:PriceTier)
            WHERE p.min_price_usd <= $budget AND p.max_price_usd >= $budget
            AND ($domain IS NULL OR 
                 toLower(s.name) CONTAINS $normalized_domain OR
                 toLower(s.description) CONTAINS $normalized_domain OR
                 EXISTS { MATCH (d:Domain)-[:RECOMMENDS]->(s) WHERE toLower(d.name) = $normalized_domain } OR
                 ANY(rd IN s.recommended_domains WHERE toLower(rd) CONTAINS $normalized_domain) OR
                 ANY(rd IN s.recommended_domains WHERE ANY(variation IN $domain_variations WHERE toLower(rd) CONTAINS variation)))
            
            
            OPTIONAL MATCH (s)-[:USES_FRONTEND]->(frontend:Technology)
            OPTIONAL MATCH (s)-[:USES_BACKEND]->(backend:Technology)
            OPTIONAL MATCH (s)-[:USES_DATABASE]->(database:Technology)
            OPTIONAL MATCH (s)-[:USES_CLOUD]->(cloud:Technology)
            OPTIONAL MATCH (s)-[:USES_TESTING]->(testing:Technology)
            OPTIONAL MATCH (s)-[:USES_MOBILE]->(mobile:Technology)
            OPTIONAL MATCH (s)-[:USES_DEVOPS]->(devops:Technology)
            OPTIONAL MATCH (s)-[:USES_AI_ML]->(ai_ml:Technology)
            OPTIONAL MATCH (s)-[:BELONGS_TO_TIER]->(pt)<-[:BELONGS_TO_TIER]-(tool:Tool)
            
            
            WITH s, frontend, backend, database, cloud, testing, mobile, devops, ai_ml, collect(DISTINCT tool.name)[0] AS tool, p,
                 ($budget * 0.6 / 12) AS calculated_monthly_cost,
                 ($budget * 0.4) AS calculated_setup_cost,
                 (COALESCE(s.satisfaction_score, 85) * 0.3 + COALESCE(s.success_rate, 85) * 0.3 + 
                  CASE WHEN s.team_size_range IS NOT NULL THEN 15 ELSE 5 END) AS base_score
            
            WITH s, frontend, backend, database, cloud, testing, mobile, devops, ai_ml, tool, base_score, p, calculated_monthly_cost, calculated_setup_cost,
                 // Professional scoring based on technology maturity and completeness
                 CASE 
                     WHEN frontend.maturity_score >= 85 AND backend.maturity_score >= 85 AND database.maturity_score >= 85 THEN 25
                     WHEN frontend.maturity_score >= 75 AND backend.maturity_score >= 75 AND database.maturity_score >= 75 THEN 20
                     WHEN frontend.maturity_score >= 65 AND backend.maturity_score >= 65 THEN 15
                     ELSE 10
                 END AS maturity_bonus,
                 
                 // Domain-specific scoring
                 CASE 
                     WHEN $normalized_domain IS NOT NULL AND 
                          (toLower(s.name) CONTAINS $normalized_domain OR 
                           ANY(rd IN s.recommended_domains WHERE toLower(rd) CONTAINS $normalized_domain)) THEN 30
                     ELSE 0
                 END AS domain_bonus,
                 
                 // Budget efficiency scoring
                 CASE 
                     WHEN (calculated_monthly_cost * 12 + calculated_setup_cost) <= $budget * 0.9 THEN 15
                     WHEN (calculated_monthly_cost * 12 + calculated_setup_cost) <= $budget THEN 10
                     ELSE 5
                 END AS budget_efficiency_bonus,
                 
                 // Completeness scoring - prioritize complete stacks
                 CASE 
                     WHEN s.backend_tech IS NOT NULL AND s.backend_tech != 'None' AND
                          s.database_tech IS NOT NULL AND s.database_tech != 'None' AND
                          s.testing_tech IS NOT NULL AND s.testing_tech != 'None' THEN 20
                     WHEN s.backend_tech IS NOT NULL AND s.backend_tech != 'None' AND
                          s.database_tech IS NOT NULL AND s.database_tech != 'None' THEN 15
                     WHEN s.backend_tech IS NOT NULL AND s.backend_tech != 'None' THEN 10
                     ELSE 5
                 END AS completeness_bonus
            
            RETURN s.name AS stack_name,
                   calculated_monthly_cost AS monthly_cost,
                   calculated_setup_cost AS setup_cost,
                   s.team_size_range AS team_size,
                   s.development_time_months AS development_time,
                   s.satisfaction_score AS satisfaction,
                   s.success_rate AS success_rate,
                   p.tier_name AS price_tier,
                   s.recommended_domains AS recommended_domains,
                   s.description AS description,
                   s.pros AS pros,
                   s.cons AS cons,
                   COALESCE(frontend.name, s.frontend_tech) AS frontend,
                   COALESCE(backend.name, s.backend_tech) AS backend,
                   COALESCE(database.name, s.database_tech) AS database,
                   COALESCE(cloud.name, s.cloud_tech) AS cloud,
                   COALESCE(testing.name, s.testing_tech) AS testing,
                   COALESCE(mobile.name, s.mobile_tech) AS mobile,
                   COALESCE(devops.name, s.devops_tech) AS devops,
                   COALESCE(ai_ml.name, s.ai_ml_tech) AS ai_ml,
                   tool AS tool,
                   CASE WHEN (base_score + maturity_bonus + domain_bonus + budget_efficiency_bonus + completeness_bonus) > 100 THEN 100 
                        ELSE (base_score + maturity_bonus + domain_bonus + budget_efficiency_bonus + completeness_bonus) END AS recommendation_score
            ORDER BY 
                // Primary: Professional recommendation score
                recommendation_score DESC,
                // Secondary: Budget efficiency
                CASE WHEN (calculated_monthly_cost * 12 + calculated_setup_cost) <= $budget THEN 1 ELSE 2 END,
                (calculated_monthly_cost * 12 + calculated_setup_cost) ASC,
                // Tertiary: Completeness priority
                CASE 
                    WHEN s.backend_tech IS NULL OR s.backend_tech = 'None' THEN 1
                    WHEN s.database_tech IS NULL OR s.database_tech = 'None' THEN 2
                    WHEN s.testing_tech IS NULL OR s.testing_tech = 'None' THEN 3
                    ELSE 0
                END ASC
            LIMIT 1
            """
            
            result = self.run_query(query, {
                "budget": budget,
                "domain": domain,
                "normalized_domain": normalized_domain,
                "domain_variations": domain_variations
            })
            
            logger.info(f"KG query for budget {budget} returned {len(result) if result else 0} results")
            if result:
                # KG OPTIMIZATION: Skip professional algorithm calls when KG data is available
                # KG OPTIMIZATION: Use KG data directly when available (100% KG utilization)
                # Only override stack name to be domain-specific
                result[0]['stack_name'] = f"Professional {domain.title()} Stack"
                logger.info(f"✅ Using KG stack: {result[0].get('stack_name', 'Unknown')} - KG data: database={result[0].get('database')}, frontend={result[0].get('frontend')}, backend={result[0].get('backend')}, cloud={result[0].get('cloud')}, testing={result[0].get('testing')}, mobile={result[0].get('mobile')}, devops={result[0].get('devops')}, ai_ml={result[0].get('ai_ml')}, tool={result[0].get('tool')}")
                return result[0]
            
            # If no domain-specific stack found, get any stack within budget
            fallback_query = """
            MATCH (s:TechStack)-[:BELONGS_TO_TIER]->(p:PriceTier)
            WHERE p.min_price_usd <= $budget AND p.max_price_usd >= $budget
            
            OPTIONAL MATCH (s)-[:USES_FRONTEND]->(frontend:Technology)
            OPTIONAL MATCH (s)-[:USES_BACKEND]->(backend:Technology)
            OPTIONAL MATCH (s)-[:USES_DATABASE]->(database:Technology)
            OPTIONAL MATCH (s)-[:USES_CLOUD]->(cloud:Technology)
            OPTIONAL MATCH (s)-[:USES_TESTING]->(testing:Technology)
            OPTIONAL MATCH (s)-[:USES_MOBILE]->(mobile:Technology)
            OPTIONAL MATCH (s)-[:USES_DEVOPS]->(devops:Technology)
            OPTIONAL MATCH (s)-[:USES_AI_ML]->(ai_ml:Technology)
            OPTIONAL MATCH (s)-[:BELONGS_TO_TIER]->(pt)<-[:BELONGS_TO_TIER]-(tool:Tool)
            
            WITH s, frontend, backend, database, cloud, testing, mobile, devops, ai_ml, collect(DISTINCT tool.name)[0] AS tool, p,
                 (COALESCE(s.satisfaction_score, 80) * 0.5 + COALESCE(s.success_rate, 80) * 0.5) AS base_score
            
            RETURN s.name AS stack_name,
                   ($budget * 0.6 / 12) AS monthly_cost,
                   ($budget * 0.4) AS setup_cost,
                   s.team_size_range AS team_size,
                   s.development_time_months AS development_time,
                   s.satisfaction_score AS satisfaction,
                   s.success_rate AS success_rate,
                   p.tier_name AS price_tier,
                   s.recommended_domains AS recommended_domains,
                   s.description AS description,
                   s.pros AS pros,
                   s.cons AS cons,
                   COALESCE(frontend.name, s.frontend_tech) AS frontend,
                   COALESCE(backend.name, s.backend_tech) AS backend,
                   COALESCE(database.name, s.database_tech) AS database,
                   COALESCE(cloud.name, s.cloud_tech) AS cloud,
                   COALESCE(testing.name, s.testing_tech) AS testing,
                   COALESCE(mobile.name, s.mobile_tech) AS mobile,
                   COALESCE(devops.name, s.devops_tech) AS devops,
                   COALESCE(ai_ml.name, s.ai_ml_tech) AS ai_ml,
                   tool AS tool,
                   CASE WHEN base_score > 100 THEN 100 ELSE base_score END AS recommendation_score
            ORDER BY 
                CASE 
                    WHEN s.backend_tech IS NULL OR s.backend_tech = 'None' THEN 1
                    WHEN s.database_tech IS NULL OR s.database_tech = 'None' THEN 2
                    WHEN s.testing_tech IS NULL OR s.testing_tech = 'None' THEN 3
                    WHEN s.mobile_tech IS NULL OR s.mobile_tech = 'None' THEN 4
                    WHEN s.ai_ml_tech IS NULL OR s.ai_ml_tech = 'None' THEN 5
                    ELSE 0
                END ASC,
                recommendation_score DESC,
                (s.monthly_cost * 12 + s.setup_cost) ASC
            LIMIT 1
            """
            
            fallback_result = self.run_query(fallback_query, {"budget": budget})
            if fallback_result:
                # KG OPTIMIZATION: Use fallback KG data directly without professional algorithm overrides
                # Only override stack name to be domain-specific
                fallback_result[0]['stack_name'] = f"Professional {domain.title()} Stack"
                logger.info(f"✅ Using KG fallback stack: {fallback_result[0].get('stack_name', 'Unknown')} - KG data: database={fallback_result[0].get('database')}, frontend={fallback_result[0].get('frontend')}, backend={fallback_result[0].get('backend')}, cloud={fallback_result[0].get('cloud')}, testing={fallback_result[0].get('testing')}, mobile={fallback_result[0].get('mobile')}, devops={fallback_result[0].get('devops')}, ai_ml={fallback_result[0].get('ai_ml')}, tool={fallback_result[0].get('tool')}")
                return fallback_result[0]
            
            # SECONDARY FALLBACK: Try Claude AI
            if self.claude_service:
                try:
                    logger.info("🤖 Using SECONDARY: Claude AI fallback")
                    claude_rec = self.claude_service.generate_tech_stack_recommendation(domain or "general", budget)
                    if claude_rec:
                        # Apply professional override to Claude result
                        professional_database = self.get_professional_database_selection(budget, domain)
                        professional_frontend = self.get_professional_frontend_selection(budget, domain)
                        professional_backend = self.get_professional_backend_selection(budget, domain)
                        professional_cloud = self.get_professional_cloud_selection(budget, domain)
                        professional_testing = self.get_professional_testing_selection(budget, domain)
                        professional_mobile = self.get_professional_mobile_selection(budget, domain)
                        professional_devops = self.get_professional_devops_selection(budget, domain)
                        professional_ai_ml = self.get_professional_ai_ml_selection(budget, domain)
                        professional_tool = self.get_professional_tool_selection(budget, domain)
                        claude_rec['database'] = professional_database
                        claude_rec['frontend'] = professional_frontend
                        claude_rec['backend'] = professional_backend
                        claude_rec['cloud'] = professional_cloud
                        claude_rec['testing'] = professional_testing
                        claude_rec['mobile'] = professional_mobile
                        claude_rec['devops'] = professional_devops
                        claude_rec['ai_ml'] = professional_ai_ml
                        claude_rec['tool'] = professional_tool
                        # PROFESSIONAL FIX: Override stack name to be domain-specific
                        claude_rec['stack_name'] = f"Professional {domain.title()} Stack"
                        logger.info(f"✅ Claude AI generated recommendation - Overriding database to: {professional_database}, frontend to: {professional_frontend}, backend to: {professional_backend}, cloud to: {professional_cloud}, testing to: {professional_testing}, mobile to: {professional_mobile}, devops to: {professional_devops}, ai_ml to: {professional_ai_ml}, tool to: {professional_tool}")
                        return claude_rec
                except Exception as e:
                    logger.error(f"❌ Claude AI fallback failed: {e}")
            else:
                logger.warning("⚠️ Claude AI service not available - skipping to PostgreSQL fallback")
            
            # TERTIARY FALLBACK: Try PostgreSQL
            try:
                logger.info("🗄️ Using TERTIARY: PostgreSQL fallback")
                postgres_recs = self.get_postgres_fallback_recommendations(budget, domain)
                if postgres_recs and len(postgres_recs) > 0:
                    postgres_rec = postgres_recs[0]
                    # Apply professional override to PostgreSQL result
                    professional_database = self.get_professional_database_selection(budget, domain)
                    professional_frontend = self.get_professional_frontend_selection(budget, domain)
                    professional_backend = self.get_professional_backend_selection(budget, domain)
                    professional_cloud = self.get_professional_cloud_selection(budget, domain)
                    professional_testing = self.get_professional_testing_selection(budget, domain)
                    professional_mobile = self.get_professional_mobile_selection(budget, domain)
                    professional_devops = self.get_professional_devops_selection(budget, domain)
                    professional_ai_ml = self.get_professional_ai_ml_selection(budget, domain)
                    professional_tool = self.get_professional_tool_selection(budget, domain)
                    postgres_rec['database'] = professional_database
                    postgres_rec['frontend'] = professional_frontend
                    postgres_rec['backend'] = professional_backend
                    postgres_rec['cloud'] = professional_cloud
                    postgres_rec['testing'] = professional_testing
                    postgres_rec['mobile'] = professional_mobile
                    postgres_rec['devops'] = professional_devops
                    postgres_rec['ai_ml'] = professional_ai_ml
                    postgres_rec['tool'] = professional_tool
                    # PROFESSIONAL FIX: Override stack name to be domain-specific
                    postgres_rec['stack_name'] = f"Professional {domain.title()} Stack"
                    logger.info(f"✅ PostgreSQL generated recommendation - Overriding database to: {professional_database}, frontend to: {professional_frontend}, backend to: {professional_backend}, cloud to: {professional_cloud}, testing to: {professional_testing}, mobile to: {professional_mobile}, devops to: {professional_devops}, ai_ml to: {professional_ai_ml}, tool to: {professional_tool}")
                    return postgres_rec
            except Exception as e:
                logger.error(f"❌ PostgreSQL fallback failed: {e}")
            
            # FINAL FALLBACK: Create dynamic recommendation
            logger.info("🔧 Using FINAL: Dynamic recommendation creation")
            return self._create_dynamic_single_recommendation(budget, domain, None)
            
        except Exception as e:
            logger.error(f"Error getting single recommendation from KG: {e}")
            # Try Claude AI as emergency fallback
            if self.claude_service:
                try:
                    logger.info("🚨 Emergency Claude AI fallback")
                    claude_rec = self.claude_service.generate_tech_stack_recommendation(domain or "general", budget)
                    if claude_rec:
                        # Apply professional override to Claude result
                        professional_database = self.get_professional_database_selection(budget, domain)
                        professional_frontend = self.get_professional_frontend_selection(budget, domain)
                        professional_backend = self.get_professional_backend_selection(budget, domain)
                        professional_cloud = self.get_professional_cloud_selection(budget, domain)
                        professional_testing = self.get_professional_testing_selection(budget, domain)
                        professional_mobile = self.get_professional_mobile_selection(budget, domain)
                        claude_rec['database'] = professional_database
                        claude_rec['frontend'] = professional_frontend
                        claude_rec['backend'] = professional_backend
                        claude_rec['cloud'] = professional_cloud
                        claude_rec['testing'] = professional_testing
                        claude_rec['mobile'] = professional_mobile
                        return claude_rec
                except Exception as claude_error:
                    logger.error(f"❌ Emergency Claude AI fallback failed: {claude_error}")
            
            # Ultimate fallback: dynamic recommendation
            return self._create_dynamic_single_recommendation(budget, domain, None)

# ================================================================================================
# POSTGRESQL MIGRATION SERVICE (SAME AS BEFORE)
# ================================================================================================

class PostgreSQLMigrationService:
    def __init__(self, 
                 host=None, 
                 port=5432,
                 user="pipeline_admin", 
                 password="secure_pipeline_2024", 
                 database="dev_pipeline"):
        self.config = {
            "host": host or os.getenv("POSTGRES_HOST", "postgres"),
            "port": port,
            "user": user,
            "password": password,
            "database": database
        }
        self.connection = None
        self.cursor = None
        self.last_error: Optional[str] = None
    
    def is_open(self) -> bool:
        try:
            return (
                self.connection is not None and
                getattr(self.connection, "closed", 1) == 0 and
                self.cursor is not None and
                not getattr(self.cursor, "closed", True)
            )
        except Exception:
            return False
    
    def connect(self):
        try:
            if self.is_open():
                self.last_error = None
                return True
            self.connection = psycopg2.connect(**self.config)
            self.cursor = self.connection.cursor(cursor_factory=RealDictCursor)
            logger.info("Connected to PostgreSQL successfully")
            self.last_error = None
            return True
        except Exception as e:
            logger.error(f"Error connecting to PostgreSQL: {e}")
            self.last_error = str(e)
            return False
    
    def close(self):
        try:
            if self.cursor and not getattr(self.cursor, "closed", True):
                self.cursor.close()
        finally:
            self.cursor = None
        try:
            if self.connection and getattr(self.connection, "closed", 1) == 0:
                self.connection.close()
        finally:
            self.connection = None

# ================================================================================================
# FASTAPI APPLICATION
# ================================================================================================

app = FastAPI(
    title="Enhanced Tech Stack Selector - Migrated Version",
    description="Tech stack selector using PostgreSQL data migrated to Neo4j with price-based relationships",
    version="15.0.0"
)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# ================================================================================================
# CONFIGURATION
# ================================================================================================

logger.remove()
logger.add(sys.stdout, level="INFO", format="{time} | {level} | {message}")

CLAUDE_API_KEY = "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"

if not os.getenv("CLAUDE_API_KEY") and CLAUDE_API_KEY:
    os.environ["CLAUDE_API_KEY"] = CLAUDE_API_KEY

api_key = os.getenv("CLAUDE_API_KEY") or CLAUDE_API_KEY
logger.info(f"🔑 Claude API Key loaded: {api_key[:20]}..." if api_key else "❌ No Claude API Key found")

# Initialize services
NEO4J_URI = os.getenv("NEO4J_URI", "bolt://localhost:7687")
NEO4J_USER = os.getenv("NEO4J_USER", "neo4j")
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD", "password")

# Initialize services
claude_service = ClaudeRecommendationService(api_key=api_key)

postgres_migration_service = PostgreSQLMigrationService(
    host=os.getenv("POSTGRES_HOST", "localhost"),
    port=int(os.getenv("POSTGRES_PORT", "5432")),
    user=os.getenv("POSTGRES_USER", "pipeline_admin"),
    password=os.getenv("POSTGRES_PASSWORD", "secure_pipeline_2024"),
    database=os.getenv("POSTGRES_DB", "dev_pipeline")
)

# Initialize Neo4j Namespace Service with TSS namespace
neo4j_service = Neo4jNamespaceService(
    uri=NEO4J_URI,
    user=NEO4J_USER,
    password=NEO4J_PASSWORD,
    namespace="TSS"
)

# Set external services to avoid circular imports
neo4j_service.claude_service = claude_service
neo4j_service.postgres_service = postgres_migration_service

# ================================================================================================
# SHUTDOWN HANDLER
# ================================================================================================

@app.on_event("shutdown")
async def shutdown_event():
    neo4j_service.close()
    postgres_migration_service.close()

atexit.register(lambda: neo4j_service.close())
atexit.register(lambda: postgres_migration_service.close())

# ================================================================================================
# ENDPOINTS
# ================================================================================================

@app.get("/health")
async def health_check():
    return {
        "status": "healthy",
        "service": "enhanced-tech-stack-selector-migrated",
        "version": "15.0.0",
        "features": ["migrated_neo4j", "postgresql_source", "claude_ai", "price_based_relationships"]
    }

@app.get("/diagnostics")
async def diagnostics():
    diagnostics_result = {
        "service": "enhanced-tech-stack-selector-migrated",
        "version": "15.0.0",
        "timestamp": datetime.utcnow().isoformat(),
        "checks": {}
    }

    # Check Neo4j
    neo4j_check = {"status": "unknown"}
    try:
        with neo4j_service.driver.session() as session:
            result = session.run("MATCH (n) RETURN count(n) AS count")
            node_count = result.single().get("count", 0)
        neo4j_check.update({
            "status": "ok",
            "node_count": int(node_count)
        })
    except Exception as e:
        neo4j_check.update({
            "status": "error",
            "error": str(e)
        })
    diagnostics_result["checks"]["neo4j"] = neo4j_check

    # Check data integrity
    try:
        integrity = neo4j_service.validate_data_integrity()
        neo4j_check["data_integrity"] = {
            "total_stacks": len(integrity),
            "complete_stacks": len([s for s in integrity if all([
                s["has_price_tier"], s["has_frontend"], s["has_backend"], 
                s["has_database"], s["has_cloud"]
            ])])
        }
    except Exception as e:
        neo4j_check["data_integrity"] = {"error": str(e)}

    return diagnostics_result

# ================================================================================================
# RECOMMENDATION ENDPOINTS
# ================================================================================================

class RecommendBestRequest(BaseModel):
    domain: Optional[str] = None
    budget: Optional[float] = None
    preferredTechnologies: Optional[List[str]] = None

class RecommendStackRequest(BaseModel):
    domain: str
    budget: float

@app.post("/recommend/best")
async def recommend_best(req: RecommendBestRequest):
    """Get recommendations with robust fallback mechanism"""
    try:
        if not req.budget or req.budget <= 0:
            raise HTTPException(status_code=400, detail="Budget must be greater than 0")
        
        # Use the new fallback mechanism
        result = neo4j_service.get_recommendations_with_fallback(
            budget=req.budget,
            domain=req.domain,
            preferred_techs=req.preferredTechnologies
        )
        
        return {
            "success": True,
            "recommendations": result["recommendations"],
            "count": result["count"],
            "budget": req.budget,
            "domain": req.domain,
            "data_source": result["data_source"],
            "fallback_level": result["fallback_level"]
        }
    except Exception as e:
        logger.error(f"Error in recommendations: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.post("/recommend/stack")
async def recommend_stack(req: RecommendStackRequest):
    """Get a single optimized tech stack recommendation using Claude AI"""
    try:
        if not req.budget or req.budget <= 0:
            raise HTTPException(status_code=400, detail="Budget must be greater than 0")
        
        if not req.domain:
            raise HTTPException(status_code=400, detail="Domain is required")
        
        # Get single optimized recommendation from Knowledge Graph based on budget
        logger.info(f"🔍 API CALL: budget={req.budget}, domain={req.domain}")
        recommendation = neo4j_service.get_single_recommendation_from_kg(
            budget=req.budget,
            domain=req.domain
        )
        logger.info(f"🔍 API RESULT: {recommendation}")
        
        # Format response to match the requested structure
        response = {
            "price_tier": recommendation.get("price_tier"),
            "monthly_cost": recommendation.get("monthly_cost", 0.0),
            "setup_cost": recommendation.get("setup_cost", 0.0),
            "frontend": recommendation.get("frontend", "HTML/CSS + JavaScript"),
            "backend": recommendation.get("backend", "Node.js"),
            "database": recommendation.get("database", "SQLite"),
            "cloud": recommendation.get("cloud", "GitHub Pages"),
            "testing": recommendation.get("testing", "Jest"),
            "mobile": recommendation.get("mobile", "Responsive Design"),
            "devops": recommendation.get("devops", "Git"),
            "ai_ml": recommendation.get("ai_ml", "None"),
            "tool": recommendation.get("tool", "Google Analytics"),
            "recommendation_score": round(recommendation.get("recommendation_score", 75.0), 1)
        }
        
        return response
        
    except Exception as e:
        logger.error(f"Error in stack recommendation: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/price-tiers")
async def get_price_tiers():
    """Get all price tiers with analysis"""
    try:
        analysis = neo4j_service.get_price_tier_analysis()
        return {
            "success": True,
            "price_tiers": analysis,
            "count": len(analysis)
        }
    except Exception as e:
        logger.error(f"Error fetching price tiers: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/technologies/{tier_name}")
async def get_technologies_by_tier(tier_name: str):
    """Get technologies for a specific price tier"""
    try:
        technologies = neo4j_service.get_technologies_by_price_tier(tier_name)
        return {
            "success": True,
            "tier_name": tier_name,
            "technologies": technologies,
            "count": len(technologies)
        }
    except Exception as e:
        logger.error(f"Error fetching technologies for tier {tier_name}: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/tools/{tier_name}")
async def get_tools_by_tier(tier_name: str):
    """Get tools for a specific price tier"""
    try:
        tools = neo4j_service.get_tools_by_price_tier(tier_name)
        return {
            "success": True,
            "tier_name": tier_name,
            "tools": tools,
            "count": len(tools)
        }
    except Exception as e:
        logger.error(f"Error fetching tools for tier {tier_name}: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/combinations/optimal")
async def get_optimal_combinations(budget: float, category: str):
    """Get optimal technology combinations within budget"""
    try:
        if budget <= 0:
            raise HTTPException(status_code=400, detail="Budget must be greater than 0")
        
        combinations = neo4j_service.get_optimal_combinations(budget, category)
        return {
            "success": True,
            "combinations": combinations,
            "count": len(combinations),
            "budget": budget,
            "category": category
        }
    except Exception as e:
        logger.error(f"Error finding optimal combinations: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/compatibility/{tech_name}")
async def get_compatibility_analysis(tech_name: str):
    """Get compatibility analysis for a technology"""
    try:
        compatibility = neo4j_service.get_compatibility_analysis(tech_name)
        return {
            "success": True,
            "tech_name": tech_name,
            "compatible_technologies": compatibility,
            "count": len(compatibility)
        }
    except Exception as e:
        logger.error(f"Error fetching compatibility for {tech_name}: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/validate/integrity")
async def validate_data_integrity():
    """Validate data integrity of migrated data"""
    try:
        integrity = neo4j_service.validate_data_integrity()
        return {
            "success": True,
            "integrity_check": integrity,
            "summary": {
                "total_stacks": len(integrity),
                "complete_stacks": len([s for s in integrity if all([
                    s["has_price_tier"], s["has_frontend"], s["has_backend"], 
                    s["has_database"], s["has_cloud"]
                ])]),
                "incomplete_stacks": len([s for s in integrity if not all([
                    s["has_price_tier"], s["has_frontend"], s["has_backend"], 
                    s["has_database"], s["has_cloud"]
                ])])
            }
        }
    except Exception as e:
        logger.error(f"Error validating data integrity: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/domains")
async def get_available_domains():
    """Get all available domains"""
    try:
        domains = neo4j_service.get_available_domains()
        return {
            "success": True,
            "domains": domains,
            "count": len(domains)
        }
    except Exception as e:
        logger.error(f"Error fetching domains: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/stacks/all")
async def get_all_stacks():
    """Get all tech stacks in the database for debugging"""
    try:
        all_stacks = neo4j_service.get_all_stacks()
        return {
            "success": True,
            "stacks": all_stacks,
            "count": len(all_stacks),
            "data_source": "neo4j_all_stacks"
        }
    except Exception as e:
        logger.error(f"Error fetching all stacks: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@app.get("/health/fallback")
async def health_check_fallback():
    health_status = {
        "neo4j": {"status": "unknown", "healthy": False},
        "claude": {"status": "unknown", "healthy": False},
        "postgres": {"status": "unknown", "healthy": False},
        "overall": {"status": "unknown", "fallback_level": "unknown"}
    }
    
    # Check Neo4j
    try:
        neo4j_healthy = neo4j_service.is_neo4j_healthy()
        health_status["neo4j"] = {
            "status": "healthy" if neo4j_healthy else "unhealthy",
            "healthy": neo4j_healthy
        }
    except Exception as e:
        health_status["neo4j"] = {"status": "error", "error": str(e), "healthy": False}
    
    # Check PostgreSQL
    try:
        postgres_healthy = neo4j_service.postgres_service.connect()
        health_status["postgres"] = {
            "status": "healthy" if postgres_healthy else "unhealthy",
            "healthy": postgres_healthy
        }
        neo4j_service.postgres_service.close()
    except Exception as e:
        health_status["postgres"] = {"status": "error", "error": str(e), "healthy": False}
    
    # Check Claude (basic check)
    try:
        # Simple check - if service is initialized
        claude_healthy = neo4j_service.claude_service is not None
        health_status["claude"] = {
            "status": "healthy" if claude_healthy else "unhealthy",
            "healthy": claude_healthy
        }
    except Exception as e:
        health_status["claude"] = {"status": "error", "error": str(e), "healthy": False}
    
    # Determine overall status and fallback level
    if health_status["neo4j"]["healthy"]:
        health_status["overall"] = {"status": "healthy", "fallback_level": "primary"}
    elif health_status["claude"]["healthy"]:
        health_status["overall"] = {"status": "degraded", "fallback_level": "secondary"}
    elif health_status["postgres"]["healthy"]:
        health_status["overall"] = {"status": "degraded", "fallback_level": "tertiary"}
    else:
        health_status["overall"] = {"status": "critical", "fallback_level": "final"}
    
    return health_status

# ================================================================================================
# MAIN ENTRY POINT
# ================================================================================================

if __name__ == "__main__":
    import uvicorn
    
    logger.info("="*60)
    logger.info("🚀 ENHANCED TECH STACK SELECTOR v15.0 - MIGRATED VERSION")
    logger.info("="*60)
    
    logger.info("✅ Using migrated PostgreSQL data from Neo4j")
    logger.info("✅ Price-based relationships")
    logger.info("✅ Real data from PostgreSQL")
    logger.info("✅ Claude AI recommendations")
    logger.info("✅ Comprehensive pricing analysis")
    logger.info("="*60)
    
    uvicorn.run("main_migrated:app", host="0.0.0.0", port=8002, log_level="info")
