<?php
/**
 * ============================================================================
 * AIAssistant.php - Enhanced AI Assistant with Smart Classification
 * ============================================================================
 * Features:
 * - Intelligent query classification
 * - Context-aware responses
 * - Multi-source knowledge with priority
 * - Database optimization
 * - Better pattern matching
 */

namespace App;

class AIAssistant {
    private $db;
    private $openaiApiKey;
    private $model;
    private $maxTokens = 1000;
    private $temperature = 0.7;
    private $timeout = 30;
    private $userId;
    
    private static $knowledgeBase = null;
    private static $learnedPatterns = [];
    private static $cropList = null;
    private static $stopWords = null;
    
    public function __construct() {
        $this->db = Database::getInstance();
        $this->openaiApiKey = $_ENV['OPENAI_API_KEY'] ?? '';
        $this->model = $_ENV['OPENAI_MODEL'] ?? 'gpt-3.5-turbo';
        
        // Load learned patterns from database
        $this->loadLearnedPatterns();
        $this->loadCropList();
        $this->loadStopWords();
    }
    
    /**
     * Main method to get AI response with intelligent classification
     */
    public function getResponse($message, $userId, $context = [], $sessionId = null) {
        try {
            $this->userId = $userId;
            
            // Validate input
            if (empty($message)) {
                throw new \Exception('Message cannot be empty');
            }
            
            if (strlen($message) > 2000) {
                throw new \Exception('Message too long. Maximum 2000 characters.');
            }
            
            // Generate or use existing session ID
            if (empty($sessionId)) {
                $sessionId = $this->generateSessionId($userId);
            }
            
            // Detect language
            $language = $this->detectLanguage($message);
            
            // Get time-aware greeting if applicable
            $timeGreeting = $this->getTimeBasedGreeting($language);
            
            // Get conversation history for context
            $conversationHistory = $this->getSessionHistory($sessionId, 5);
            
            // Enhance context with user profile data
            $enrichedContext = $this->enrichContext($userId, $context);
            
            // Check for special patterns (greetings, thanks, etc.)
            $specialResponse = $this->handleSpecialPatterns($message, $language, $timeGreeting);
            if ($specialResponse) {
                $this->saveConversation($userId, $sessionId, $message, $specialResponse, $language, 'pattern_match');
                return [
                    'success' => true,
                    'response' => $specialResponse,
                    'language' => $language,
                    'source' => 'pattern_match',
                    'session_id' => $sessionId,
                    'timestamp' => date('Y-m-d H:i:s')
                ];
            }
            
            // Classify the query for intelligent routing
            $classification = $this->classifyQuery($message, $language);
            
            // Try multi-source knowledge retrieval with classification
            $knowledgeResponse = $this->getMultiSourceKnowledge($message, $language, $enrichedContext, $classification);
            
            if ($knowledgeResponse) {
                // Enhance with context awareness
                $enhancedResponse = $this->getContextAwareResponse($message, $language, $enrichedContext, $classification);
                $response = $enhancedResponse . $knowledgeResponse;
                $source = 'knowledge_base';
            } elseif ($this->isOpenAIConfigured()) {
                // Try OpenAI with enhanced prompt
                try {
                    error_log("Attempting OpenAI request for user: $userId");
                    
                    $response = $this->getOpenAIResponse(
                        $message, 
                        $language, 
                        $enrichedContext, 
                        $conversationHistory,
                        $classification
                    );
                    
                    error_log("OpenAI response received successfully");
                    $source = 'openai';
                    
                    // Learn from successful OpenAI responses
                    $this->learnFromResponse($message, $response, $language);
                    
                } catch (\Exception $e) {
                    error_log('OpenAI Error: ' . $e->getMessage());
                    
                    // Fallback to enhanced rule-based
                    $response = $this->getEnhancedRuleBasedResponse(
                        $message, 
                        $language, 
                        $enrichedContext, 
                        $conversationHistory,
                        $classification
                    );
                    $source = 'enhanced_rules';
                }
            } else {
                // Enhanced rule-based system with classification
                $response = $this->getEnhancedRuleBasedResponse(
                    $message, 
                    $language, 
                    $enrichedContext, 
                    $conversationHistory,
                    $classification
                );
                $source = 'enhanced_rules';
            }
            
            // Save conversation with classification data
            $this->saveConversation($userId, $sessionId, $message, $response, $language, $source);
            
            // Update user interaction statistics
            $this->updateUserStats($userId, $language);
            
            return [
                'success' => true,
                'response' => $response,
                'language' => $language,
                'source' => $source,
                'session_id' => $sessionId,
                'timestamp' => date('Y-m-d H:i:s'),
                'context_used' => !empty($enrichedContext),
                'classification' => $classification
            ];
            
        } catch (\Exception $e) {
            error_log('AI Assistant Error: ' . $e->getMessage());
            
            return [
                'success' => false,
                'message' => $e->getMessage(),
                'response' => $this->getErrorResponse($language ?? 'en'),
                'language' => $language ?? 'en',
                'source' => 'error',
                'session_id' => $sessionId ?? null,
                'timestamp' => date('Y-m-d H:i:s')
            ];
        }
    }
    
    /**
     * Classify user query for intelligent routing
     */
    private function classifyQuery($message, $language) {
        $messageLower = mb_strtolower(trim($message), 'UTF-8');
        
        $classification = [
            'type' => 'general',
            'crop' => null,
            'topic' => null,
            'subtopic' => null,
            'urgency' => 'normal',
            'language' => $language,
            'confidence' => 1.0
        ];
        
        // Detect specific crop
        $classification['crop'] = $this->detectCrop($messageLower, $language);
        
        // Detect main topic
        $classification['topic'] = $this->detectTopic($messageLower, $language);
        
        // Detect subtopic
        $classification['subtopic'] = $this->detectSubtopic($messageLower, $language);
        
        // Detect urgency
        $classification['urgency'] = $this->detectUrgency($messageLower, $language);
        
        // Determine query type based on classification
        if ($classification['crop'] && $classification['topic']) {
            $classification['type'] = 'specific';
        } elseif ($classification['topic'] && !$classification['crop']) {
            $classification['type'] = 'general_topic';
        }
        
        return $classification;
    }
    
    /**
     * Detect specific crop in message
     */
    private function detectCrop($message, $language) {
        $crops = self::$cropList[$language] ?? self::$cropList['en'];
        
        foreach ($crops as $crop => $aliases) {
            foreach ($aliases as $alias) {
                if (strpos($message, $alias) !== false) {
                    return $crop;
                }
            }
        }
        
        return null;
    }
    
    /**
     * Detect main topic in message
     */
    private function detectTopic($message, $language) {
        $topics = [
            'en' => [
                'disease' => ['disease', 'sick', 'illness', 'infected', 'infection', 'symptom'],
                'pest' => ['pest', 'insect', 'bug', 'worm', 'caterpillar', 'aphid', 'beetle'],
                'growing' => ['grow', 'plant', 'cultivate', 'planting', 'growing', 'cultivation'],
                'schedule' => ['when', 'time', 'season', 'schedule', 'calendar', 'month'],
                'price' => ['price', 'cost', 'sell', 'buy', 'market', 'value', 'costing'],
                'fertilizer' => ['fertilizer', 'manure', 'nutrient', 'fertilize', 'dap', 'urea', 'npk'],
                'soil' => ['soil', 'earth', 'dirt', 'land', 'ground', 'fertility'],
                'water' => ['water', 'irrigation', 'rain', 'drought', 'dry', 'moisture'],
                'harvest' => ['harvest', 'harvesting', 'yield', 'produce', 'output'],
                'storage' => ['store', 'storage', 'preserve', 'keep', 'save']
            ],
            'lusoga' => [
                'disease' => ['bulwadhe', 'kufa', 'obulwadhe', 'obulema'],
                'pest' => ['ebiwuka', 'enjooka', 'ebinyonyi', 'ebikoko'],
                'growing' => ['okulima', 'okusimba', 'okukula', 'okusimba'],
                'schedule' => ['dijja', 'obudde', 'essaawa', 'omwezi', 'emyaka'],
                'price' => ['emiwendo', 'okutunda', 'okugula', 'bbanja'],
                'fertilizer' => ['okuzuukusa', 'fertilizer', 'obusa', 'amafuta'],
                'soil' => ['ettaka', 'ensi', 'obugimu'],
                'water' => ['amazzi', 'enkuba', 'okusisinkana'],
                'harvest' => ['okungula', 'okuzuula', 'okusasula'],
                'storage' => ['okutereka', 'okusigala', 'okukuuma']
            ]
        ];
        
        $langTopics = $topics[$language] ?? $topics['en'];
        
        foreach ($langTopics as $topic => $keywords) {
            foreach ($keywords as $keyword) {
                if (strpos($message, $keyword) !== false) {
                    return $topic;
                }
            }
        }
        
        return null;
    }
    
    /**
     * Detect subtopic in message
     */
    private function detectSubtopic($message, $language) {
        $subtopics = [
            'en' => [
                'prevention' => ['prevent', 'avoid', 'stop', 'protect'],
                'treatment' => ['treat', 'cure', 'control', 'spray', 'medicine'],
                'identification' => ['identify', 'recognize', 'know', 'tell', 'look like'],
                'causes' => ['cause', 'reason', 'why', 'because'],
                'symptoms' => ['symptom', 'sign', 'show', 'appear'],
                'organic' => ['organic', 'natural', 'traditional', 'home'],
                'chemical' => ['chemical', 'pesticide', 'herbicide', 'fungicide'],
                'profit' => ['profit', 'income', 'money', 'earn', 'make money'],
                'loss' => ['loss', 'damage', 'destroy', 'waste']
            ],
            'lusoga' => [
                'prevention' => ['okuziyiza', 'okweyisa', 'okwewala'],
                'treatment' => ['okujjanjaba', 'eddagala', 'okufumya'],
                'identification' => ['okuzuula', 'okumanya', 'okulaba'],
                'causes' => ['ensonga', 'kubanga', 'olw\'ensonga'],
                'symptoms' => ['obubonero', 'okulabika', 'okweeka'],
                'organic' => ['obuwangwa', 'obutonde', 'omu maka'],
                'chemical' => ['eddagala', 'chemical', 'obuwuka'],
                'profit' => ['omugaso', 'ssente', 'okufuna'],
                'loss' => ['okufiirwa', 'okwononeka', 'obubi']
            ]
        ];
        
        $langSubtopics = $subtopics[$language] ?? $subtopics['en'];
        
        foreach ($langSubtopics as $subtopic => $keywords) {
            foreach ($keywords as $keyword) {
                if (strpos($message, $keyword) !== false) {
                    return $subtopic;
                }
            }
        }
        
        return null;
    }
    
    /**
     * Detect urgency in message
     */
    private function detectUrgency($message, $language) {
        $urgentWords = [
            'en' => ['emergency', 'urgent', 'help', 'quick', 'now', 'immediately', 'asap', 'critical'],
            'lusoga' => ['mangu', 'akawungeezi', 'kizibu', 'bulungi', 'nsanyuse']
        ];
        
        $langUrgent = $urgentWords[$language] ?? $urgentWords['en'];
        
        foreach ($langUrgent as $word) {
            if (strpos($message, $word) !== false) {
                return 'urgent';
            }
        }
        
        return 'normal';
    }
    
    /**
     * Get multi-source knowledge with intelligent routing
     */
    private function getMultiSourceKnowledge($message, $language, $context, $classification) {
        $messageLower = mb_strtolower($message, 'UTF-8');
        
        // 1. Check learned patterns first (exact matches)
        $learnedResponse = $this->checkLearnedPatterns($messageLower, $language);
        if ($learnedResponse) {
            return $learnedResponse;
        }
        
        // 2. Route based on classification
        if ($classification['type'] === 'specific' && $classification['crop'] && $classification['topic']) {
            // Specific crop + topic query - prioritize exact matches
            return $this->handleSpecificQuery($classification, $language, $context);
        } elseif ($classification['type'] === 'general_topic' && $classification['topic']) {
            // General topic query - broader search
            return $this->handleGeneralTopicQuery($message, $classification, $language, $context);
        } else {
            // General query - comprehensive search
            return $this->handleGeneralQuery($message, $language, $context);
        }
    }
    
    /**
     * Handle specific crop + topic queries
     */
    private function handleSpecificQuery($classification, $language, $context) {
        $crop = $classification['crop'];
        $topic = $classification['topic'];
        $subtopic = $classification['subtopic'];
        
        switch ($topic) {
            case 'disease':
            case 'pest':
                // Try diseases/pests first for specific crop
                $response = $this->searchCropDiseases($crop, $language, $subtopic);
                if ($response) return $response;
                
                // Try agricultural tips with disease focus
                $response = $this->searchAgriculturalTips($crop, $language, 'disease_control');
                if ($response) return $response;
                break;
                
            case 'growing':
                // Try agricultural tips for growing
                $response = $this->searchAgriculturalTips($crop, $language, 'growing');
                if ($response) return $response;
                
                // Try farming schedules
                $response = $this->searchFarmingSchedules($crop, $language);
                if ($response) return $response;
                break;
                
            case 'schedule':
                // Try farming schedules
                $response = $this->searchFarmingSchedules($crop, $language);
                if ($response) return $response;
                break;
                
            case 'price':
                // Try market prices
                $response = $this->searchMarketPrices($crop, $language, $context);
                if ($response) return $response;
                break;
                
            case 'fertilizer':
            case 'soil':
                // Try agricultural tips for soil/fertilizer
                $response = $this->searchAgriculturalTips($crop, $language, 'fertilizer');
                if ($response) return $response;
                break;
                
            case 'harvest':
                // Try agricultural tips for harvesting
                $response = $this->searchAgriculturalTips($crop, $language, 'harvesting');
                if ($response) return $response;
                break;
                
            case 'storage':
                // Try agricultural tips for storage
                $response = $this->searchAgriculturalTips($crop, $language, 'storage');
                if ($response) return $response;
                break;
        }
        
        // Fallback: general agricultural tips for the crop
        return $this->searchAgriculturalTips($crop, $language, 'general');
    }
    
    /**
     * Handle general topic queries
     */
    private function handleGeneralTopicQuery($message, $classification, $language, $context) {
        $topic = $classification['topic'];
        
        switch ($topic) {
            case 'disease':
            case 'pest':
                // Search diseases without specific crop
                $response = $this->searchCropDiseases($message, $language, null);
                if ($response) return $response;
                break;
                
            case 'price':
                // Search market prices
                $response = $this->searchMarketPrices($message, $language, $context);
                if ($response) return $response;
                break;
                
            case 'fertilizer':
            case 'soil':
                // Search soil/fertilizer tips
                $response = $this->searchAgriculturalTips($message, $language, 'soil_health');
                if ($response) return $response;
                break;
        }
        
        // Fallback: general search
        return $this->searchAgriculturalTips($message, $language, 'general');
    }
    
    /**
     * Handle general queries
     */
    private function handleGeneralQuery($message, $language, $context) {
        // Try multiple sources in order of relevance
        
        // 1. Try agricultural tips
        $response = $this->searchAgriculturalTips($message, $language, 'general');
        if ($response) return $response;
        
        // 2. Try crop diseases
        $response = $this->searchCropDiseases($message, $language, null);
        if ($response) return $response;
        
        // 3. Try farming schedules
        $response = $this->searchFarmingSchedules($message, $language);
        if ($response) return $response;
        
        // 4. Try market prices
        $response = $this->searchMarketPrices($message, $language, $context);
        if ($response) return $response;
        
        // 5. Try static knowledge base
        $response = $this->searchKnowledgeBase($message, $language, $context);
        if ($response) return $response;
        
        return null;
    }
    
    /**
     * Get context-aware response prefix
     */
    private function getContextAwareResponse($message, $language, $context, $classification) {
        $response = '';
        
        if ($classification['crop'] && $classification['topic']) {
            $cropName = $this->getCropDisplayName($classification['crop'], $language);
            $topicName = $this->getTopicDisplayName($classification['topic'], $language);
            
            if ($language === 'en') {
                $response .= "## {$cropName} {$topicName} Information\n\n";
                
                // Add location-specific note if available
                if (!empty($context['location']) && $context['location'] !== 'Uganda') {
                    $response .= "*Information specific to {$context['location']} region*\n\n";
                }
                
                // Add urgency note if urgent
                if ($classification['urgency'] === 'urgent') {
                    $response .= "⚠️ **Urgent Issue Detected** - Immediate attention recommended\n\n";
                }
            } else {
                $response .= "## {$cropName} {$topicName}\n\n";
                
                if (!empty($context['location']) && $context['location'] !== 'Uganda') {
                    $response .= "*Amagezi agakwatagana ne {$context['location']}*\n\n";
                }
                
                if ($classification['urgency'] === 'urgent') {
                    $response .= "⚠️ **Kizibu ekisaba okukolagana mangu**\n\n";
                }
            }
        }
        
        return $response;
    }
    
    /**
     * Search agricultural tips with improved matching
     */
    private function searchAgriculturalTips($query, $language, $category = null) {
        try {
            // Extract relevant keywords
            $keywords = $this->extractRelevantKeywords($query, ['agriculture']);
            
            if (empty($keywords) && !$category) {
                return null;
            }
            
            // Build query based on parameters
            $sql = "SELECT * FROM agricultural_tips 
                    WHERE language = ? AND is_published = 1";
            
            $params = [$language];
            
            // Add category filter if provided
            if ($category) {
                $sql .= " AND category = ?";
                $params[] = $category;
            }
            
            // Add keyword search if keywords exist
            if (!empty($keywords)) {
                $conditions = [];
                foreach ($keywords as $keyword) {
                    $conditions[] = "(title LIKE ? OR content LIKE ? OR crop_type LIKE ?)";
                    $params[] = "%{$keyword}%";
                    $params[] = "%{$keyword}%";
                    $params[] = "%{$keyword}%";
                }
                $sql .= " AND (" . implode(' OR ', $conditions) . ")";
            }
            
            // Add ordering for relevance
            $sql .= " ORDER BY 
                CASE 
                    WHEN title LIKE ? THEN 1
                    WHEN crop_type LIKE ? THEN 2
                    WHEN content LIKE ? THEN 3
                    ELSE 4
                END,
                created_at DESC 
                LIMIT 3";
            
            // Add relevance parameters
            $relevanceQuery = !empty($keywords) ? $keywords[0] : $query;
            $params[] = "%{$relevanceQuery}%";
            $params[] = "%{$relevanceQuery}%";
            $params[] = "%{$relevanceQuery}%";
            
            $tips = $this->db->fetchAll($sql, $params);
            
            if (!empty($tips)) {
                return $this->formatAgriculturalTips($tips, $language);
            }
            
            return null;
            
        } catch (\Exception $e) {
            error_log('Error searching agricultural tips: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * Search crop diseases with improved matching
     */
    private function searchCropDiseases($query, $language, $subtopic = null) {
        try {
            // Check if query is a specific crop name
            $crop = $this->detectCrop(mb_strtolower($query, 'UTF-8'), $language);
            
            $sql = "SELECT * FROM crop_diseases 
                    WHERE language = ? AND is_published = 1";
            
            $params = [$language];
            
            if ($crop) {
                // Search for specific crop
                $sql .= " AND crop_type LIKE ?";
                $params[] = "%{$crop}%";
            } else {
                // Search with keywords
                $keywords = $this->extractRelevantKeywords($query, ['disease']);
                if (empty($keywords)) {
                    return null;
                }
                
                $conditions = [];
                foreach ($keywords as $keyword) {
                    $conditions[] = "(disease_name LIKE ? OR symptoms LIKE ? OR crop_type LIKE ?)";
                    $params[] = "%{$keyword}%";
                    $params[] = "%{$keyword}%";
                    $params[] = "%{$keyword}%";
                }
                $sql .= " AND (" . implode(' OR ', $conditions) . ")";
            }
            
            // Filter by subtopic if provided
            if ($subtopic) {
                switch ($subtopic) {
                    case 'treatment':
                        $sql .= " AND treatment IS NOT NULL AND treatment != ''";
                        break;
                    case 'prevention':
                        $sql .= " AND prevention IS NOT NULL AND prevention != ''";
                        break;
                    case 'symptoms':
                        $sql .= " AND symptoms IS NOT NULL AND symptoms != ''";
                        break;
                }
            }
            
            // Order by relevance and severity
            $sql .= " ORDER BY 
                CASE 
                    WHEN crop_type = ? THEN 1
                    WHEN disease_name LIKE ? THEN 2
                    ELSE 3
                END,
                CASE severity_level
                    WHEN 'critical' THEN 1
                    WHEN 'high' THEN 2
                    WHEN 'medium' THEN 3
                    WHEN 'low' THEN 4
                    ELSE 5
                END,
                created_at DESC 
                LIMIT 3";
            
            // Add relevance parameters
            $searchTerm = $crop ?: (!empty($keywords) ? $keywords[0] : $query);
            $params[] = $searchTerm;
            $params[] = "%{$searchTerm}%";
            
            $diseases = $this->db->fetchAll($sql, $params);
            
            if (!empty($diseases)) {
                return $this->formatCropDiseases($diseases, $language, $subtopic);
            }
            
            return null;
            
        } catch (\Exception $e) {
            error_log('Error searching crop diseases: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * Search farming schedules
     */
    private function searchFarmingSchedules($query, $language) {
        try {
            $crop = $this->detectCrop(mb_strtolower($query, 'UTF-8'), $language);
            
            if (!$crop) {
                return null;
            }
            
            $sql = "SELECT * FROM farming_schedules 
                    WHERE language = ? AND is_published = 1 
                    AND crop_type LIKE ?
                    ORDER BY 
                        CASE 
                            WHEN crop_type = ? THEN 1
                            ELSE 2
                        END,
                        week_from_planting ASC,
                        priority ASC
                    LIMIT 5";
            
            $schedules = $this->db->fetchAll($sql, [$language, "%{$crop}%", $crop]);
            
            if (!empty($schedules)) {
                return $this->formatFarmingSchedules($schedules, $language);
            }
            
            return null;
            
        } catch (\Exception $e) {
            error_log('Error searching farming schedules: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * Search market prices
     */
    private function searchMarketPrices($query, $language, $context) {
        try {
            $crop = $this->detectCrop(mb_strtolower($query, 'UTF-8'), $language);
            
            if (!$crop) {
                // Check if asking about prices in general
                $priceKeywords = ['price', 'cost', 'sell', 'buy', 'market', 'miwendo', 'tunda', 'gula'];
                $hasPrice = false;
                foreach ($priceKeywords as $keyword) {
                    if (stripos($query, $keyword) !== false) {
                        $hasPrice = true;
                        break;
                    }
                }
                
                if (!$hasPrice) {
                    return null;
                }
                
                // Try to extract product from query
                $keywords = $this->extractRelevantKeywords($query, ['price']);
                if (empty($keywords)) {
                    return null;
                }
                
                $crop = $keywords[0];
            }
            
            $location = $context['location'] ?? 'Eastern Uganda';
            
            $sql = "SELECT * FROM market_prices 
                    WHERE product_type LIKE ? 
                    AND price_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
                    ORDER BY 
                        CASE 
                            WHEN market_location LIKE ? THEN 1
                            ELSE 2
                        END,
                        price_date DESC
                    LIMIT 5";
            
            $prices = $this->db->fetchAll($sql, ["%{$crop}%", "%{$location}%"]);
            
            if (!empty($prices)) {
                return $this->formatMarketPrices($prices, $language, $crop, $location);
            }
            
            return null;
            
        } catch (\Exception $e) {
            error_log('Error searching market prices: ' . $e->getMessage());
            return null;
        }
    }
    
    /**
     * Format agricultural tips response
     */
    private function formatAgriculturalTips($tips, $language) {
        if ($language === 'en') {
            $response = "**🌱 Agricultural Tips**\n\n";
        } else {
            $response = "**🌱 Amagezi g'Okulima**\n\n";
        }
        
        foreach ($tips as $tip) {
            $response .= "### " . htmlspecialchars($tip['title']) . "\n";
            
            if ($tip['crop_type']) {
                $response .= "*Crop: " . ucfirst($tip['crop_type']) . "*\n";
            }
            
            $response .= "\n" . $tip['content'] . "\n\n";
            
            if ($tip['category']) {
                $category = ucfirst(str_replace('_', ' ', $tip['category']));
                $response .= "📌 *Category: {$category}*\n";
            }
            
            $response .= "\n---\n\n";
        }
        
        if ($language === 'en') {
            $response .= "💡 *Source: AIMS Agricultural Knowledge Base*";
        } else {
            $response .= "💡 *Ensibuko: AIMS Eby'obulimi*";
        }
        
        return $response;
    }
    
    /**
     * Format crop diseases response
     */
    private function formatCropDiseases($diseases, $language, $subtopic = null) {
        if ($language === 'en') {
            $response = "**🦠 Crop Diseases & Pests**\n\n";
        } else {
            $response = "**🦠 Obulwadhe bw'Ebirime n'Ebiwuka**\n\n";
        }
        
        foreach ($diseases as $disease) {
            $response .= "### " . htmlspecialchars($disease['disease_name']) . "\n";
            
            if ($disease['scientific_name']) {
                $response .= "*" . htmlspecialchars($disease['scientific_name']) . "*\n";
            }
            
            $response .= "\n**" . ($language === 'en' ? 'Crop:' : 'Ekirime:') . "** " . 
                        ucfirst($disease['crop_type']) . "\n";
            
            $response .= "**" . ($language === 'en' ? 'Type:' : 'Ekika:') . "** " . 
                        ucfirst($disease['category']) . "\n";
            
            $response .= "**" . ($language === 'en' ? 'Severity:' : 'Obuzito:') . "** " . 
                        ucfirst($disease['severity_level']) . "\n\n";
            
            // Show symptoms unless user asked for something specific
            if (!$subtopic || $subtopic === 'symptoms') {
                if (!empty($disease['symptoms'])) {
                    $response .= "**" . ($language === 'en' ? 'Symptoms:' : 'Obubonero:') . "**\n" . 
                                $disease['symptoms'] . "\n\n";
                }
            }
            
            // Show treatment if available and relevant
            if ((!$subtopic || $subtopic === 'treatment') && !empty($disease['treatment'])) {
                $response .= "**" . ($language === 'en' ? 'Treatment:' : 'Okujjanjaba:') . "**\n" . 
                            $disease['treatment'] . "\n\n";
            }
            
            // Show prevention if available and relevant
            if ((!$subtopic || $subtopic === 'prevention') && !empty($disease['prevention'])) {
                $response .= "**" . ($language === 'en' ? 'Prevention:' : 'Okuziyiza:') . "**\n" . 
                            $disease['prevention'] . "\n\n";
            }
            
            $response .= "---\n\n";
        }
        
        if ($language === 'en') {
            $response .= "⚠️ *Always consult with an agricultural extension officer for proper diagnosis*";
        } else {
            $response .= "⚠️ *Bulijjo kubuuza omukulembeze w'eby'obulimi okufuna obujjanjabi obulungi*";
        }
        
        return $response;
    }
    
    /**
     * Format farming schedules response
     */
    private function formatFarmingSchedules($schedules, $language) {
        if ($language === 'en') {
            $response = "**📅 Farming Schedule**\n\n";
        } else {
            $response = "**📅 Oludda lw'Okulima**\n\n";
        }
        
        foreach ($schedules as $schedule) {
            $response .= "### " . htmlspecialchars($schedule['title']) . "\n";
            
            $crop = ucfirst($schedule['crop_type']);
            $activity = ucfirst(str_replace('_', ' ', $schedule['activity_type']));
            $response .= "*{$crop} - {$activity}*\n\n";
            
            if ($schedule['description']) {
                $response .= $schedule['description'] . "\n\n";
            }
            
            if ($schedule['timing']) {
                $response .= "⏰ **" . ($language === 'en' ? 'Timing:' : 'Essawa:') . "** " . 
                            $schedule['timing'] . "\n";
            }
            
            if ($schedule['week_from_planting']) {
                $weeks = $schedule['week_from_planting'];
                $response .= ($language === 'en' ? 
                    "📆 **Week from planting:** {$weeks} weeks\n" :
                    "📆 **Wiiki okuva okusimba:** {$weeks} wiiki\n");
            }
            
            if ($schedule['instructions']) {
                $response .= "\n**" . ($language === 'en' ? 'Instructions:' : 'Enkola:') . "**\n" . 
                            $schedule['instructions'] . "\n";
            }
            
            $response .= "\n---\n\n";
        }
        
        return $response;
    }
    
    /**
     * Format market prices response
     */
    private function formatMarketPrices($prices, $language, $product, $location) {
        $productDisplay = $this->getCropDisplayName($product, $language) ?: ucfirst($product);
        
        if ($language === 'en') {
            $response = "**💰 Market Prices for {$productDisplay}**\n\n";
            $response .= "*Recent prices in {$location}*\n\n";
        } else {
            $response = "**💰 Emiwendo gy'{$productDisplay}**\n\n";
            $response .= "*Emiwendo gya kumpi mu {$location}*\n\n";
        }
        
        $locations = [];
        foreach ($prices as $price) {
            $locations[$price['market_location']][] = $price;
        }
        
        foreach ($locations as $market => $marketPrices) {
            $response .= "📍 **" . htmlspecialchars($market) . "**\n";
            
            foreach ($marketPrices as $price) {
                $date = date('M d, Y', strtotime($price['price_date']));
                $formattedPrice = number_format($price['price'], 0);
                
                $response .= "   UGX {$formattedPrice} per {$price['unit']}\n";
                $response .= "   *{$date}*\n";
            }
            
            $response .= "\n";
        }
        
        // Add advice
        if ($language === 'en') {
            $response .= "💡 **Tips for Better Prices:**\n";
            $response .= "- Sell during dry season (December-February)\n";
            $response .= "- Improve product quality for higher prices\n";
            $response .= "- Use AIMS marketplace to connect directly with buyers\n";
            $response .= "- Join farmer groups for collective bargaining\n";
        } else {
            $response .= "💡 **Amagezi g'Okufuna Emiwendo Amanyi:**\n";
            $response .= "- Tunda mu kyeya (December-February)\n";
            $response .= "- Kozesa omutindo gwa kungulu okufuna emiwendo amanyi\n";
            $response .= "- Kozesa AIMS marketplace okusisinkana n'abagula butereevu\n";
            $response .= "- Yingira mu bibiina by'abalimi okwogera bulungi\n";
        }
        
        return $response;
    }
    
    /**
     * Extract relevant keywords
     */
    private function extractRelevantKeywords($message, $excludeCategories = []) {
        $stopWords = array_merge(
            self::$stopWords['general'],
            self::$stopWords['agriculture']
        );
        
        // Add category-specific stop words
        foreach ($excludeCategories as $category) {
            if (isset(self::$stopWords[$category])) {
                $stopWords = array_merge($stopWords, self::$stopWords[$category]);
            }
        }
        
        $words = preg_split('/\s+/', mb_strtolower($message, 'UTF-8'));
        $keywords = array_filter($words, function($word) use ($stopWords) {
            // Keep meaningful words
            return strlen($word) > 2 && 
                   !in_array($word, $stopWords) &&
                   !is_numeric($word) &&
                   !preg_match('/^[^a-z]*$/', $word); // Remove non-alphabetic
        });
        
        return array_values(array_unique($keywords));
    }
    
    /**
     * Get crop display name
     */
    private function getCropDisplayName($crop, $language) {
        $displayNames = [
            'tomato' => ['en' => 'Tomato', 'lusoga' => 'Nyaanya'],
            'maize' => ['en' => 'Maize', 'lusoga' => 'Kasooli'],
            'beans' => ['en' => 'Beans', 'lusoga' => 'Bikooge'],
            'cassava' => ['en' => 'Cassava', 'lusoga' => 'Muwogo'],
            'cabbage' => ['en' => 'Cabbage', 'lusoga' => 'Nakati'],
            'coffee' => ['en' => 'Coffee', 'lusoga' => 'Emmwanyi'],
            'potato' => ['en' => 'Potato', 'lusoga' => 'Lumonde'],
            'onion' => ['en' => 'Onion', 'lusoga' => 'Katungulu'],
            'banana' => ['en' => 'Banana', 'lusoga' => 'Ndizi'],
            'sugarcane' => ['en' => 'Sugarcane', 'lusoga' => 'Enkoko']
        ];
        
        return $displayNames[$crop][$language] ?? ucfirst($crop);
    }
    
    /**
     * Get topic display name
     */
    private function getTopicDisplayName($topic, $language) {
        $displayNames = [
            'en' => [
                'disease' => 'Diseases',
                'pest' => 'Pests',
                'growing' => 'Growing',
                'schedule' => 'Planting Schedule',
                'price' => 'Market Prices',
                'fertilizer' => 'Fertilizer',
                'soil' => 'Soil Management',
                'water' => 'Water Management',
                'harvest' => 'Harvesting',
                'storage' => 'Storage'
            ],
            'lusoga' => [
                'disease' => 'Obulwadhe',
                'pest' => 'Ebiwuka',
                'growing' => 'Okulima',
                'schedule' => 'Okusimba',
                'price' => 'Emiwendo',
                'fertilizer' => 'Okuzuukusa',
                'soil' => 'Ettaka',
                'water' => 'Amazzi',
                'harvest' => 'Okungula',
                'storage' => 'Okutereka'
            ]
        ];
        
        return $displayNames[$language][$topic] ?? ucfirst($topic);
    }
    
    /**
     * Load crop list from database or cache
     */
    private function loadCropList() {
        if (self::$cropList !== null) {
            return;
        }
        
        try {
            // Load from database
            $sql = "SELECT DISTINCT crop_type FROM crop_diseases 
                    WHERE is_published = 1 
                    UNION 
                    SELECT DISTINCT crop_type FROM agricultural_tips 
                    WHERE is_published = 1
                    UNION
                    SELECT DISTINCT crop_type FROM farming_schedules 
                    WHERE is_published = 1";
            
            $crops = $this->db->fetchAll($sql);
            
            // Create crop list with aliases
            self::$cropList = [
                'en' => [],
                'lusoga' => []
            ];
            
            foreach ($crops as $crop) {
                $cropName = strtolower($crop['crop_type']);
                
                // English aliases
                self::$cropList['en'][$cropName] = [$cropName];
                
                // Lusoga aliases (simplified - would need actual mapping)
                if (isset($this->getCropToLusogaMap()[$cropName])) {
                    self::$cropList['lusoga'][$cropName] = $this->getCropToLusogaMap()[$cropName];
                } else {
                    self::$cropList['lusoga'][$cropName] = [$cropName];
                }
            }
            
            // Add common crops that might not be in database
            $commonCrops = [
                'tomato' => ['en' => ['tomato'], 'lusoga' => ['nyaanya', 'tomaato']],
                'maize' => ['en' => ['maize', 'corn'], 'lusoga' => ['kasooli', 'maize']],
                'beans' => ['en' => ['beans'], 'lusoga' => ['bikooge', 'beans']],
                'cassava' => ['en' => ['cassava'], 'lusoga' => ['muwogo', 'cassava']]
            ];
            
            foreach ($commonCrops as $crop => $aliases) {
                if (!isset(self::$cropList['en'][$crop])) {
                    self::$cropList['en'][$crop] = $aliases['en'];
                    self::$cropList['lusoga'][$crop] = $aliases['lusoga'];
                }
            }
            
        } catch (\Exception $e) {
            error_log('Error loading crop list: ' . $e->getMessage());
            
            // Fallback to basic list
            self::$cropList = [
                'en' => [
                    'tomato' => ['tomato'],
                    'maize' => ['maize', 'corn'],
                    'beans' => ['beans'],
                    'cassava' => ['cassava'],
                    'cabbage' => ['cabbage'],
                    'coffee' => ['coffee']
                ],
                'lusoga' => [
                    'tomato' => ['nyaanya'],
                    'maize' => ['kasooli'],
                    'beans' => ['bikooge'],
                    'cassava' => ['muwogo'],
                    'cabbage' => ['nakati'],
                    'coffee' => ['emmwanyi']
                ]
            ];
        }
    }
    
    /**
     * Get crop to Lusoga mapping
     */
    private function getCropToLusogaMap() {
        return [
            'tomato' => ['nyaanya', 'tomaato'],
            'maize' => ['kasooli', 'maize'],
            'beans' => ['bikooge', 'beans'],
            'cassava' => ['muwogo', 'cassava'],
            'cabbage' => ['nakati', 'cabbage'],
            'coffee' => ['emmwanyi', 'coffee'],
            'potato' => ['lumonde', 'potato'],
            'onion' => ['katungulu', 'onion'],
            'banana' => ['ndizi', 'banana'],
            'sugarcane' => ['enkoko', 'sugarcane']
        ];
    }
    
    /**
     * Load stop words
     */
    private function loadStopWords() {
        if (self::$stopWords !== null) {
            return;
        }
        
        self::$stopWords = [
            'general' => [
                'the', 'is', 'at', 'which', 'on', 'a', 'an', 'as', 'are', 'was', 'were',
                'how', 'what', 'when', 'where', 'why', 'can', 'could', 'would', 'should',
                'my', 'your', 'our', 'their', 'i', 'you', 'we', 'they', 'mu', 'ku', 'oba',
                'and', 'or', 'but', 'if', 'then', 'so', 'because', 'since', 'although',
                'please', 'tell', 'me', 'about', 'information', 'advice', 'help'
            ],
            'agriculture' => [
                'growing', 'planting', 'farm', 'farming', 'crop', 'crops', 'plant', 'plants',
                'disease', 'diseases', 'pest', 'pests', 'control', 'management',
                'need', 'want', 'know', 'learn', 'understand', 'explain', 'describe'
            ],
            'disease' => [
                'sick', 'ill', 'infected', 'infection', 'problem', 'issue', 'wrong'
            ],
            'price' => [
                'cost', 'costing', 'value', 'worth', 'expensive', 'cheap', 'affordable'
            ]
        ];
    }
    
    /**
     * Enhanced OpenAI response with classification
     */
    private function getOpenAIResponse($message, $language, $context, $conversationHistory = [], $classification = []) {
        $systemPrompt = $this->buildEnhancedSystemPrompt($language, $context, $classification);
        
        // Build messages array with history
        $messages = [
            [
                'role' => 'system',
                'content' => $systemPrompt
            ]
        ];
        
        // Add conversation history for context (limit to last 5)
        $historyCount = 0;
        foreach ($conversationHistory as $hist) {
            if ($historyCount >= 5) break;
            
            $messages[] = [
                'role' => 'user',
                'content' => $hist['message']
            ];
            $messages[] = [
                'role' => 'assistant',
                'content' => $hist['response']
            ];
            $historyCount++;
        }
        
        // Add current message with classification context
        $enhancedMessage = $message;
        if (!empty($classification['crop'])) {
            $cropName = $this->getCropDisplayName($classification['crop'], $language);
            $enhancedMessage = "Question about {$cropName}: " . $message;
        }
        
        $messages[] = [
            'role' => 'user',
            'content' => $enhancedMessage
        ];
        
        $requestData = [
            'model' => $this->model,
            'messages' => $messages,
            'temperature' => $this->temperature,
            'max_tokens' => $this->maxTokens,
            'top_p' => 0.9,
            'frequency_penalty' => 0.3,
            'presence_penalty' => 0.3
        ];
        
        error_log("OpenAI Request Data: " . json_encode($requestData, JSON_PRETTY_PRINT));
        
        // Make API request with retry logic
        $maxRetries = 2;
        $retryCount = 0;
        $lastError = null;
        
        while ($retryCount < $maxRetries) {
            try {
                $ch = curl_init('https://api.openai.com/v1/chat/completions');
                curl_setopt_array($ch, [
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_POST => true,
                    CURLOPT_POSTFIELDS => json_encode($requestData),
                    CURLOPT_HTTPHEADER => [
                        'Content-Type: application/json',
                        'Authorization: Bearer ' . $this->openaiApiKey
                    ],
                    CURLOPT_TIMEOUT => $this->timeout,
                    CURLOPT_SSL_VERIFYPEER => true
                ]);
                
                $response = curl_exec($ch);
                $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                $curlError = curl_error($ch);
                curl_close($ch);
                
                if ($curlError) {
                    throw new \Exception('cURL Error: ' . $curlError);
                }
                
                error_log("OpenAI HTTP Code: $httpCode");
                error_log("OpenAI Response: " . substr($response, 0, 500));
                
                if ($httpCode === 200) {
                    $result = json_decode($response, true);
                    
                    if (isset($result['choices'][0]['message']['content'])) {
                        return trim($result['choices'][0]['message']['content']);
                    }
                    
                    throw new \Exception('Invalid API response format: ' . $response);
                }
                
                // Handle specific error codes
                if ($httpCode === 429) {
                    // Rate limit - wait and retry
                    sleep(pow(2, $retryCount));
                    $retryCount++;
                    continue;
                }
                
                if ($httpCode === 401) {
                    throw new \Exception('Invalid API key');
                }
                
                if ($httpCode === 400) {
                    $errorData = json_decode($response, true);
                    throw new \Exception('Bad request: ' . ($errorData['error']['message'] ?? 'Unknown error'));
                }
                
                throw new \Exception("HTTP $httpCode: $response");
                
            } catch (\Exception $e) {
                $lastError = $e;
                $retryCount++;
                
                if ($retryCount >= $maxRetries) {
                    break;
                }
                
                sleep(1);
            }
        }
        
        throw $lastError ?? new \Exception('OpenAI request failed');
    }
    
    /**
     * Build enhanced system prompt with classification
     */
    private function buildEnhancedSystemPrompt($language, $context, $classification) {
        $date = date('F j, Y');
        $season = $this->getCurrentSeason();
        
        $basePrompt = "You are AIM AI, an intelligent agricultural assistant for farmers in Uganda. ";
        $basePrompt .= "Today is {$date}. Current agricultural season: {$season}.\n\n";
        
        // Add classification context
        if (!empty($classification['crop'])) {
            $cropName = $this->getCropDisplayName($classification['crop'], $language);
            $basePrompt .= "The user is asking about {$cropName}";
            
            if (!empty($classification['topic'])) {
                $topicName = $this->getTopicDisplayName($classification['topic'], $language);
                $basePrompt .= " specifically about {$topicName}";
            }
            $basePrompt .= ".\n\n";
        }
        
        if ($language === 'lusoga') {
            $basePrompt .= "CRITICAL: You MUST respond ONLY in Lusoga language. Never use English.\n\n";
            $basePrompt .= "**Ebirowoozo byo:**\n";
            $basePrompt .= "- Obulwadhe bw'ebirime (kasooli, muwogo, bikooge, nakati)\n";
            $basePrompt .= "- Okusimba, okulima n'okungula\n";
            $basePrompt .= "- Emiwendo gy'ebintu mu bbabali za Uganda\n";
            $basePrompt .= "- Okuzuukusa ettaka n'eby'obugimu\n";
            $basePrompt .= "- Obudde n'okulima okw'amagezi\n";
            $basePrompt .= "- Ebisolo: enkoko, ente, embuzi\n\n";
            $basePrompt .= "**Enkola:**\n";
            $basePrompt .= "- Waayo obwogezi obutuufu, obw'amagezi (200-500 words)\n";
            $basePrompt .= "- Kozesa Lusoga ennyangu, etategeerekeka\n";
            $basePrompt .= "- Waayo amagezi amangi ag'amagezi\n";
            $basePrompt .= "- Teeka emiwendo mu Ugandan Shillings (UGX)\n";
            $basePrompt .= "- Kozesa bullet points ku steps\n";
        } else {
            $basePrompt .= "**Your Expertise:**\n";
            $basePrompt .= "- Crop diseases, pests, and treatments\n";
            $basePrompt .= "- Livestock management (poultry, cattle, goats, pigs)\n";
            $basePrompt .= "- Planting schedules for Uganda's climate\n";
            $basePrompt .= "- Market prices and selling strategies\n";
            $basePrompt .= "- Soil health and organic farming\n";
            $basePrompt .= "- Weather-smart agriculture\n";
            $basePrompt .= "- Farm financial management\n\n";
            $basePrompt .= "**Response Guidelines:**\n";
            $basePrompt .= "- Keep responses practical and actionable (200-500 words)\n";
            $basePrompt .= "- Use simple, farmer-friendly language\n";
            $basePrompt .= "- Give specific recommendations with quantities and timing\n";
            $basePrompt .= "- Suggest affordable, locally available solutions\n";
            $basePrompt .= "- Include costs in Ugandan Shillings (UGX) when relevant\n";
            $basePrompt .= "- Use bullet points for steps and lists\n";
            $basePrompt .= "- Be encouraging and supportive\n";
        }
        
        // Add user context
        if (!empty($context['user_name'])) {
            $basePrompt .= "\n**User Profile:**\n";
            $basePrompt .= "- Name: " . $context['user_name'] . "\n";
        }
        
        if (!empty($context['location'])) {
            $basePrompt .= "- Location: " . $context['location'] . "\n";
        }
        
        if (!empty($context['farming_experience'])) {
            $basePrompt .= "- Farming Experience: " . $context['farming_experience'] . " years\n";
        }
        
        if (!empty($context['current_crops'])) {
            if (is_array($context['current_crops'])) {
                $crops = implode(', ', $context['current_crops']);
            } else {
                $crops = $context['current_crops'];
            }
            $basePrompt .= "- Current Crops: " . $crops . "\n";
        }
        
        return $basePrompt;
    }
    
    /**
     * Get current season
     */
    private function getCurrentSeason() {
        $month = date('n');
        
        if ($month >= 3 && $month <= 6) {
            return "First Season (Planting/Growing)";
        } elseif ($month >= 7 && $month <= 9) {
            return "Between Seasons";
        } elseif ($month >= 10 || $month <= 2) {
            return "Second Season (Planting/Growing)";
        }
        
        return "Transition Period";
    }
    
    /**
     * Generate session ID
     */
    private function generateSessionId($userId) {
        return 'session_' . $userId . '_' . time() . '_' . bin2hex(random_bytes(8));
    }
    
    /**
     * Get session history
     */
    private function getSessionHistory($sessionId, $limit = 5) {
        try {
            $sql = "SELECT message, response, language 
                    FROM ai_conversations 
                    WHERE session_id = ? 
                    ORDER BY created_at DESC 
                    LIMIT ?";
            
            $history = $this->db->fetchAll($sql, [$sessionId, $limit]);
            return array_reverse($history);
            
        } catch (\Exception $e) {
            error_log('Error fetching session history: ' . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Check if OpenAI is configured
     */
    private function isOpenAIConfigured() {
        $isConfigured = !empty($this->openaiApiKey) && 
                       $this->openaiApiKey !== 'your_openai_api_key' &&
                       strpos($this->openaiApiKey, 'sk-') === 0;
        
        return $isConfigured;
    }
    
    /**
     * Detect language
     */
    private function detectLanguage($message) {
        $lusogaPatterns = [
            'obulwadhe', 'okusimba', 'okuzuukusa', 'amasimu', 'ebirime',
            'omwezi', 'ditya', 'bwa', 'ndobulaba', 'ndisima', 'gange',
            'muwogo', 'emmere', 'okungula', 'omusaija', 'omukazi',
            'ebikoola', 'emiggo', 'ettaka', 'enkuba', 'obudde',
            'obulo', 'kasooli', 'bikooge', 'nakati', 'ensigo',
            'wasuze', 'osiibiile', 'oli otya', 'webale', 'mwebale',
            'nze', 'gwe', 'ye', 'ffe', 'mmwe', 'bo', 'ndiyinza'
        ];
        
        $messageLower = mb_strtolower($message, 'UTF-8');
        
        $matches = 0;
        foreach ($lusogaPatterns as $pattern) {
            if (mb_strpos($messageLower, $pattern) !== false) {
                $matches++;
            }
        }
        
        return $matches >= 2 ? 'lusoga' : 'en';
    }
    
    /**
     * Get time-based greeting
     */
    private function getTimeBasedGreeting($language = 'en') {
        $hour = date('G');
        
        if ($language === 'lusoga') {
            if ($hour >= 5 && $hour < 12) {
                return "Wasuze otya nno!";
            } elseif ($hour >= 12 && $hour < 17) {
                return "Osiibiile otya!";
            } elseif ($hour >= 17 && $hour < 22) {
                return "Oiwiire otya!";
            } else {
                return "Osula otya!";
            }
        } else {
            if ($hour >= 5 && $hour < 12) {
                return "Good morning!";
            } elseif ($hour >= 12 && $hour < 17) {
                return "Good afternoon!";
            } elseif ($hour >= 17 && $hour < 22) {
                return "Good evening!";
            } else {
                return "Hello!";
            }
        }
    }
    
    /**
     * Handle special patterns
     */
    private function handleSpecialPatterns($message, $language, $timeGreeting) {
        $messageLower = mb_strtolower(trim($message), 'UTF-8');
        
        // Greeting patterns
        $greetingPatterns = [
            'en' => '/^(hi|hello|hey|good morning|good afternoon|good evening|greetings|howdy|sup|wassup)$/i',
            'lusoga' => '/^(wasuze|osiibiile|oiwiire|oli otya|suubi|hello|hi)$/i'
        ];
        
        if (preg_match($greetingPatterns[$language], $messageLower)) {
            return $this->getGreetingResponse($language, $timeGreeting);
        }
        
        // Thank you patterns
        $thanksPatterns = [
            'en' => '/^(thank you|thanks|thank|thx|appreciate|grateful)$/i',
            'lusoga' => '/^(webale|mwebale|nsonyiwa|thanks)$/i'
        ];
        
        if (preg_match($thanksPatterns[$language], $messageLower)) {
            return $this->getThanksResponse($language);
        }
        
        // How are you patterns
        $howAreYouPatterns = [
            'en' => '/how are you|how do you do|how is it going|whats up/i',
            'lusoga' => '/oli otya|biriwo|osiibiile otya/i'
        ];
        
        if (preg_match($howAreYouPatterns[$language], $messageLower)) {
            return $this->getHowAreYouResponse($language);
        }
        
        return null;
    }
    
    /**
     * Get greeting response
     */
    private function getGreetingResponse($language, $timeGreeting) {
        if ($language === 'lusoga') {
            return "{$timeGreeting} 👋\n\n" .
                   "Nze **AIM AI**, omuyambi wo mu by'obulimi owa Uganda. Ndi musanyufu okukuwulira!\n\n" .
                   "**Ndiyinza okukuyamba mu:**\n" .
                   "🌱 **Obulwadhe bw'ebirime** - Okuzuula n'okujjanjaba\n" .
                   "📅 **Obudde bw'okusimba** - Okumanyi essaawa entuufu\n" .
                   "💰 **Emiwendo** - Emiwendo egiriwo kaakati\n" .
                   "🌾 **Enkola ennungi** - Amagezi g'okulima\n" .
                   "🐔 **Ebisolo** - Okufuga enkoko, ente, embuzi\n\n" .
                   "Oyagala nkuyambe mu ki? 😊";
        } else {
            return "{$timeGreeting} 👋\n\n" .
                   "I'm **AIM AI**, your intelligent agricultural assistant for Uganda. Great to connect with you!\n\n" .
                   "**I can help you with:**\n" .
                   "🌱 **Crop Diseases** - Identify and treat problems\n" .
                   "📅 **Planting Schedules** - Best times to plant\n" .
                   "💰 **Market Prices** - Current prices and trends\n" .
                   "🌾 **Best Practices** - Modern farming techniques\n" .
                   "🐔 **Livestock Care** - Poultry, cattle, goats\n\n" .
                   "What would you like to know today? 😊";
        }
    }
    
    /**
     * Get thanks response
     */
    private function getThanksResponse($language) {
        if ($language === 'lusoga') {
            return "Webale nyo! 😊\n\n" .
                   "Ndi musanyufu okukuyamba. Ndi wano buli kaseera singa oyagala okumbuuza ekirungi ekirala!\n\n" .
                   "**Jjukira:**\n" .
                   "✅ Kebera ebirime byo buli kaseera\n" .
                   "✅ Kozesa AIMS marketplace okutunda\n" .
                   "✅ Teekawo alerts za miwendo\n" .
                   "✅ Yingira mu bibiina by'abalimi\n\n" .
                   "Kabisaana mu by'obulimi! 🌾🚜";
        } else {
            return "You're very welcome! 😊\n\n" .
                   "I'm happy to help. Feel free to ask me anything else about farming!\n\n" .
                   "**Quick Tips:**\n" .
                   "✅ Monitor your crops regularly\n" .
                   "✅ Use AIMS marketplace to sell\n" .
                   "✅ Set price alerts\n" .
                   "✅ Join farmer groups\n\n" .
                   "Happy farming! 🌾🚜";
        }
    }
    
    /**
     * Get how are you response
     */
    private function getHowAreYouResponse($language) {
        if ($language === 'lusoga') {
            return "Ndi bulungi nnyo, webale okubuuza! 😊\n\n" .
                   "Ndi mwetegefu okuyamba abalimi nga ggwe okufuna omukisa mu bulimi!\n\n" .
                   "**Oyinza okumbuuza ku:**\n" .
                   "- Obulwadhe bw'ebirime\n" .
                   "- Obudde bw'okusimba\n" .
                   "- Emiwendo mu bbabali\n" .
                   "- Okuddukanya omusimu\n\n" .
                   "Mbuuza kyonna! 🌾";
        } else {
            return "I'm doing great, thank you for asking! 😊\n\n" .
                   "I'm ready to help farmers like you succeed in agriculture!\n\n" .
                   "**You can ask me about:**\n" .
                   "- Crop diseases and pests\n" .
                   "- Planting schedules\n" .
                   "- Market prices\n" .
                   "- Farm management\n\n" .
                   "What would you like to know? 🌾";
        }
    }
    
    /**
     * Enrich context with user data
     */
    private function enrichContext($userId, $context = []) {
        try {
            // Get user profile data
            $sql = "SELECT u.*, up.*, r.region_name, d.district_name, s.subcounty_name
                    FROM users u
                    LEFT JOIN user_profiles up ON u.id = up.user_id
                    LEFT JOIN regions r ON u.region_id = r.id
                    LEFT JOIN districts d ON u.district_id = d.id
                    LEFT JOIN subcounties s ON u.subcounty_id = s.id
                    WHERE u.id = ?";
            
            $user = $this->db->fetchOne($sql, [$userId]);
            
            if ($user) {
                $context['user_name'] = $user['full_name'];
                $context['location'] = $user['district_name'] ?? 'Uganda';
                $context['region'] = $user['region_name'] ?? null;
                $context['subcounty'] = $user['subcounty_name'] ?? null;
                $context['farming_experience'] = $user['years_in_farming'] ?? 0;
                $context['farm_size'] = $user['farm_size_acres'] ?? 0;
                $context['farming_type'] = $user['farming_type'] ?? null;
                
                // Get crops from profile
                if (!empty($user['crops_grown'])) {
                    $context['current_crops'] = json_decode($user['crops_grown'], true);
                }
                
                // Get livestock from profile
                if (!empty($user['livestock_kept'])) {
                    $context['livestock'] = json_decode($user['livestock_kept'], true);
                }
            }
            
            // Get user's active enterprises
            $enterpriseSql = "SELECT e.* FROM enterprises e
                             INNER JOIN farms f ON e.farm_id = f.id
                             WHERE f.user_id = ? AND e.status != 'completed'
                             ORDER BY e.created_at DESC LIMIT 5";
            
            $enterprises = $this->db->fetchAll($enterpriseSql, [$userId]);
            if (!empty($enterprises)) {
                $context['enterprises'] = $enterprises;
            }
            
            // Get recent products
            $productSql = "SELECT * FROM products 
                          WHERE seller_id = ? AND status = 'available'
                          ORDER BY created_at DESC LIMIT 3";
            
            $products = $this->db->fetchAll($productSql, [$userId]);
            if (!empty($products)) {
                $context['products'] = $products;
            }
            
            return $context;
            
        } catch (\Exception $e) {
            error_log('Error enriching context: ' . $e->getMessage());
            return $context;
        }
    }
    
    /**
     * Check learned patterns
     */
    private function checkLearnedPatterns($message, $language) {
        if (empty(self::$learnedPatterns[$language])) {
            return null;
        }
        
        foreach (self::$learnedPatterns[$language] as $pattern) {
            $similarity = 0;
            similar_text($message, $pattern['question'], $similarity);
            
            if ($similarity > 85) { // 85% similarity threshold
                $pattern['usage_count']++;
                $this->updatePatternUsage($pattern['id']);
                return $pattern['response'];
            }
        }
        
        return null;
    }
    
    /**
     * Load learned patterns
     */
    private function loadLearnedPatterns() {
        try {
            $sql = "SELECT * FROM ai_learned_patterns 
                    WHERE is_active = 1 AND success_rate >= 0.7
                    ORDER BY usage_count DESC, success_rate DESC";
            
            $patterns = $this->db->fetchAll($sql);
            
            foreach ($patterns as $pattern) {
                $lang = $pattern['language'];
                if (!isset(self::$learnedPatterns[$lang])) {
                    self::$learnedPatterns[$lang] = [];
                }
                self::$learnedPatterns[$lang][] = $pattern;
            }
            
        } catch (\Exception $e) {
            error_log('Error loading learned patterns: ' . $e->getMessage());
        }
    }
    
    /**
     * Update pattern usage
     */
    private function updatePatternUsage($patternId) {
        try {
            $sql = "UPDATE ai_learned_patterns 
                    SET usage_count = usage_count + 1, last_used = NOW()
                    WHERE id = ?";
            $this->db->execute($sql, [$patternId]);
        } catch (\Exception $e) {
            error_log('Error updating pattern usage: ' . $e->getMessage());
        }
    }
    
    /**
     * Enhanced rule-based response with classification
     */
    private function getEnhancedRuleBasedResponse($message, $language, $context, $history, $classification) {
        $knowledgeBase = $this->getKnowledgeBase($language);
        $messageLower = mb_strtolower($message, 'UTF-8');
        
        // Check for context-specific responses
        if (!empty($context['enterprises'])) {
            $contextResponse = $this->getContextualResponse($message, $context, $language);
            if ($contextResponse) {
                return $contextResponse;
            }
        }
        
        // Use conversation history for context
        if (!empty($history)) {
            $historyResponse = $this->getHistoryAwareResponse($message, $history, $language);
            if ($historyResponse) {
                return $historyResponse;
            }
        }
        
        // Check for helpful guidance based on classification
        $helpfulGuidance = $this->getHelpfulGuidance($message, $language, $classification);
        if ($helpfulGuidance) {
            return $helpfulGuidance;
        }
        
        // Standard knowledge base search
        foreach ($knowledgeBase as $pattern => $response) {
            if (preg_match($pattern, $messageLower)) {
                return $this->personalizeResponse($response, $context, $language);
            }
        }
        
        // Default response
        return $this->getDefaultResponse($language);
    }
    
    /**
     * Get helpful guidance based on classification
     */
    private function getHelpfulGuidance($message, $language, $classification) {
        if ($classification['crop']) {
            $cropName = $this->getCropDisplayName($classification['crop'], $language);
            
            if ($language === 'en') {
                return "I can help you with information about {$cropName}!\n\n" .
                       "You can ask me about:\n" .
                       "- **Diseases and pests** affecting {$cropName}\n" .
                       "- **Best practices** for growing {$cropName}\n" .
                       "- **Planting schedules** for {$cropName}\n" .
                       "- **Market prices** for {$cropName}\n" .
                       "- **Harvesting and storage** of {$cropName}\n\n" .
                       "Try asking a specific question like:\n" .
                       "• 'What diseases affect {$cropName}?'\n" .
                       "• 'When should I plant {$cropName}?'\n" .
                       "• 'How do I grow {$cropName} organically?'";
            } else {
                return "Ndiyinza okukuyamba ku {$cropName}!\n\n" .
                       "Oyinza okumbuuza ku:\n" .
                       "- **Obulwadhe n'ebiwuka** ebikwata ku {$cropName}\n" .
                       "- **Enkola ennungi** z'okulima {$cropName}\n" .
                       "- **Obudde bw'okusimba** {$cropName}\n" .
                       "- **Emiwendo** gy'{$cropName}\n" .
                       "- **Okungula n'okutereka** {$cropName}\n\n" .
                       "Gezaako okubuuza ekirungi nga:\n" .
                       "• 'Obulwadhe ki obukwata ku {$cropName}?'\n" .
                       "• 'Dijja okusimba {$cropName}?'\n" .
                       "• 'Ndiya {$cropName} mu buwangwa?'";
            }
        }
        
        return $this->getDefaultResponse($language);
    }
    
    /**
     * Get contextual response
     */
    private function getContextualResponse($message, $context, $language) {
        $messageLower = mb_strtolower($message, 'UTF-8');
        
        // Check if asking about their own crops/enterprises
        $personalKeywords = ['my', 'mine', 'our', 'gange', 'waffe'];
        $isPersonal = false;
        
        foreach ($personalKeywords as $keyword) {
            if (stripos($message, $keyword) !== false) {
                $isPersonal = true;
                break;
            }
        }
        
        if ($isPersonal && !empty($context['enterprises'])) {
            $response = $language === 'en' ? 
                       "Based on your farm profile, here's what I found:\n\n" :
                       "Okusinziira ku farm yo, kino kye nzudde:\n\n";
            
            foreach ($context['enterprises'] as $enterprise) {
                $response .= "**" . ucfirst(str_replace('_', ' ', $enterprise['enterprise_type'])) . "**\n";
                $response .= ($language === 'en' ? "Status: " : "Embeera: ") . 
                            ucfirst($enterprise['status']) . "\n";
                
                if ($enterprise['planting_date']) {
                    $plantingDate = date('M d, Y', strtotime($enterprise['planting_date']));
                    $response .= ($language === 'en' ? "Planted: " : "Yasimbibwa: ") . 
                                $plantingDate . "\n";
                }
                
                if ($enterprise['expected_harvest_date']) {
                    $harvestDate = date('M d, Y', strtotime($enterprise['expected_harvest_date']));
                    $daysUntil = ceil((strtotime($enterprise['expected_harvest_date']) - time()) / 86400);
                    
                    if ($daysUntil > 0) {
                        $response .= ($language === 'en' ? "Harvest in: " : "Okungula mu: ") . 
                                    $daysUntil . ($language === 'en' ? " days" : " ennaku") . "\n";
                    }
                }
                
                $response .= "\n";
            }
            
            // Add relevant advice
            $response .= $this->getEnterpriseAdvice($context['enterprises'], $language);
            
            return $response;
        }
        
        return null;
    }
    
    /**
     * Get enterprise advice
     */
    private function getEnterpriseAdvice($enterprises, $language) {
        $advice = $language === 'en' ? "\n**Recommendations:**\n" : "\n**Amagezi:**\n";
        
        foreach ($enterprises as $enterprise) {
            $type = $enterprise['enterprise_type'];
            $status = $enterprise['status'];
            
            // Check if harvest is near
            if ($enterprise['expected_harvest_date']) {
                $daysUntil = ceil((strtotime($enterprise['expected_harvest_date']) - time()) / 86400);
                
                if ($daysUntil > 0 && $daysUntil <= 14) {
                    $cropName = ucfirst(str_replace('_', ' ', $type));
                    if ($language === 'en') {
                        $advice .= "- Your {$cropName} harvest is approaching in {$daysUntil} days. Start preparing storage and finding buyers.\n";
                    } else {
                        $advice .= "- {$cropName} yaago ekumpi okungulwa mu nnaku {$daysUntil}. Tandika okutegeka okutereka n'okunoonya abagula.\n";
                    }
                }
            }
        }
        
        return $advice;
    }
    
    /**
     * Get history-aware response
     */
    private function getHistoryAwareResponse($message, $history, $language) {
        // Check if user is following up on previous topic
        if (count($history) > 0) {
            $lastConversation = $history[count($history) - 1];
            $lastMessage = mb_strtolower($lastConversation['message'], 'UTF-8');
            $currentMessage = mb_strtolower($message, 'UTF-8');
            
            // Check for follow-up indicators
            $followUpIndicators = ['more', 'also', 'what about', 'and', 'ate', 'n\'ate', 'era'];
            
            foreach ($followUpIndicators as $indicator) {
                if (stripos($currentMessage, $indicator) !== false) {
                    // This might be a follow-up question
                    return $this->generateFollowUpResponse($lastMessage, $currentMessage, $language);
                }
            }
        }
        
        return null;
    }
    
    /**
     * Generate follow-up response
     */
    private function generateFollowUpResponse($previousMessage, $currentMessage, $language) {
        // Extract topic from previous message
        $topics = ['maize', 'beans', 'cassava', 'price', 'plant', 'disease', 
                   'kasooli', 'bikooge', 'muwogo', 'simba', 'bulwadhe'];
        
        $topic = null;
        foreach ($topics as $t) {
            if (stripos($previousMessage, $t) !== false) {
                $topic = $t;
                break;
            }
        }
        
        if ($topic) {
            // Search for additional information about the same topic
            return $this->searchKnowledgeBase($topic . ' ' . $currentMessage, $language, []);
        }
        
        return null;
    }
    
    /**
     * Search knowledge base
     */
    private function searchKnowledgeBase($message, $language, $context) {
        $knowledgeBase = $this->getKnowledgeBase($language);
        
        foreach ($knowledgeBase as $pattern => $response) {
            if (preg_match($pattern, $message)) {
                return $this->personalizeResponse($response, $context, $language);
            }
        }
        
        return null;
    }
    
    /**
     * Get knowledge base
     */
    private function getKnowledgeBase($language) {
        if (self::$knowledgeBase !== null && isset(self::$knowledgeBase[$language])) {
            return self::$knowledgeBase[$language];
        }
        
        if ($language === 'lusoga') {
            $kb = require __DIR__ . '/../config/knowledge-base-lusoga.php';
        } else {
            $kb = require __DIR__ . '/../config/knowledge-base-english.php';
        }
        
        self::$knowledgeBase[$language] = $kb;
        return $kb;
    }
    
    /**
     * Personalize response
     */
    private function personalizeResponse($response, $context, $language) {
        // Add user name if available
        if (!empty($context['user_name'])) {
            $firstName = explode(' ', $context['user_name'])[0];
            if ($language === 'en') {
                $response = str_replace('{{name}}', $firstName, $response);
            }
        }
        
        // Add location context if relevant
        if (!empty($context['location']) && strpos($response, 'Uganda') === false) {
            $suffix = $language === 'lusoga' 
                ? "\n\n*Ebyo bigwanidde " . htmlspecialchars($context['location']) . "*"
                : "\n\n*This applies to the " . htmlspecialchars($context['location']) . " region*";
            $response .= $suffix;
        }
        
        return $response;
    }
    
    /**
     * Learn from response
     */
    private function learnFromResponse($question, $response, $language) {
        try {
            // Check if pattern already exists
            $checkSql = "SELECT id FROM ai_learned_patterns 
                        WHERE question_pattern = ? AND language = ?";
            $existing = $this->db->fetchOne($checkSql, [$question, $language]);
            
            if (!$existing) {
                // Save new learned pattern
                $sql = "INSERT INTO ai_learned_patterns 
                        (question_pattern, response_template, language, source, usage_count, success_rate)
                        VALUES (?, ?, ?, 'openai', 1, 1.0)";
                
                $this->db->execute($sql, [$question, $response, $language]);
                
                // Reload learned patterns
                $this->loadLearnedPatterns();
            }
            
        } catch (\Exception $e) {
            error_log('Error learning from response: ' . $e->getMessage());
        }
    }
    
    /**
     * Get default response
     */
    private function getDefaultResponse($language) {
        if ($language === 'lusoga') {
            return "Nsonyiwa, simanyi bulungi ekyo. 🤔\n\n" .
                   "Ndiyinza okukuyamba mu:\n" .
                   "- **Obulwadhe bw'ebirime** (kasooli, muwogo, bikooge)\n" .
                   "- **Okusimba n'okungula** ebirime\n" .
                   "- **Emiwendo** gy'ebintu mu bbabali\n" .
                   "- **Okuzuukusa ettaka**\n" .
                   "- **Obudde** n'okulima\n" .
                   "- **Ebisolo** (enkoko, ente, embuzi)\n\n" .
                   "Buuza ekirungi era ekirambudde! 😊";
        } else {
            return "I'm here to help with agricultural questions! 😊\n\n" .
                   "I can assist you with:\n" .
                   "- **Crop Diseases & Pests**\n" .
                   "- **Planting Schedules**\n" .
                   "- **Market Prices**\n" .
                   "- **Soil Management**\n" .
                   "- **Weather & Climate**\n" .
                   "- **Livestock Care**\n\n" .
                   "Please ask a specific question about farming! 🌾";
        }
    }
    
    /**
     * Get error response
     */
    private function getErrorResponse($language) {
        if ($language === 'lusoga') {
            return "Nsonyiwa, waliwo ekizibu. Gezaako nate. 🙏";
        } else {
            return "Sorry, I encountered an error. Please try again. 🙏";
        }
    }
    
    /**
     * Save conversation
     */
    private function saveConversation($userId, $sessionId, $message, $response, $language, $source) {
        try {
            $sql = "INSERT INTO ai_conversations 
                    (user_id, session_id, message, response, language, source, created_at)
                    VALUES (?, ?, ?, ?, ?, ?, NOW())";
            
            $this->db->execute($sql, [
                $userId,
                $sessionId,
                $message,
                $response,
                $language,
                $source
            ]);
            
        } catch (\Exception $e) {
            error_log('Error saving AI conversation: ' . $e->getMessage());
        }
    }
    
    /**
     * Update user stats
     */
    private function updateUserStats($userId, $language) {
        try {
            $sql = "UPDATE users SET last_activity = NOW() WHERE id = ?";
            $this->db->execute($sql, [$userId]);
        } catch (\Exception $e) {
            error_log('Error updating user stats: ' . $e->getMessage());
        }
    }
    
    /**
     * Get user sessions
     */
    public function getUserSessions($userId, $limit = 20) {
        try {
            $sql = "SELECT 
                        session_id,
                        MIN(created_at) as started_at,
                        MAX(created_at) as last_message_at,
                        COUNT(*) as message_count,
                        (SELECT message FROM ai_conversations ac2 
                         WHERE ac2.session_id = ac.session_id 
                         ORDER BY created_at ASC LIMIT 1) as first_message
                    FROM ai_conversations ac
                    WHERE user_id = ?
                    GROUP BY session_id
                    ORDER BY last_message_at DESC
                    LIMIT ?";
            
            return $this->db->fetchAll($sql, [$userId, $limit]);
            
        } catch (\Exception $e) {
            error_log('Error fetching user sessions: ' . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Get session messages
     */
    public function getSessionMessages($sessionId) {
        try {
            $sql = "SELECT * FROM ai_conversations 
                    WHERE session_id = ? 
                    ORDER BY created_at ASC";
            
            return $this->db->fetchAll($sql, [$sessionId]);
            
        } catch (\Exception $e) {
            error_log('Error fetching session messages: ' . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Clear history
     */
    public function clearHistory($userId) {
        try {
            $sql = "DELETE FROM ai_conversations WHERE user_id = ?";
            return $this->db->execute($sql, [$userId]);
        } catch (\Exception $e) {
            error_log('Error clearing conversation history: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * Get stats
     */
    public function getStats($userId) {
        try {
            $sql = "SELECT 
                        COUNT(DISTINCT session_id) as total_conversations,
                        COUNT(*) as total_messages,
                        SUM(CASE WHEN language = 'lusoga' THEN 1 ELSE 0 END) as lusoga_count,
                        SUM(CASE WHEN language = 'en' THEN 1 ELSE 0 END) as english_count,
                        SUM(CASE WHEN source = 'openai' THEN 1 ELSE 0 END) as openai_count,
                        SUM(CASE WHEN source = 'rule_based' THEN 1 ELSE 0 END) as rule_based_count,
                        MIN(created_at) as first_conversation,
                        MAX(created_at) as last_conversation
                    FROM ai_conversations 
                    WHERE user_id = ?";
            
            return $this->db->fetchOne($sql, [$userId]);
            
        } catch (\Exception $e) {
            error_log('Error fetching AI stats: ' . $e->getMessage());
            return null;
        }
    }
 /**
     * Quick test method to verify connectivity
     */
    public function testConnectivity() {
        $tests = [
            'internet' => $this->checkInternetConnectivity(),
            'openai_configured' => $this->isOpenAIConfigured(),
            'openai_available' => $this->isOpenAIAvailable(),
            'connection_errors' => self::$connectionErrors,
            'disabled_until' => self::$openaiDisabledUntil ? date('Y-m-d H:i:s', self::$openaiDisabledUntil) : null
        ];
        
        return $tests;
    }
    
    /**
     * Reset OpenAI connection status
     */
    public function resetOpenAIStatus() {
        self::$connectionErrors = 0;
        self::$openaiDisabledUntil = null;
        self::$lastConnectionErrorTime = null;
        return ['success' => true, 'message' => 'OpenAI connection status reset'];
    }

    
}