<?php
/**
 * ============================================================================
 * AIAssistant.php - Pure PHP AI Assistant Class
 * ============================================================================
 * This class handles AI conversations using OpenAI API with intelligent
 * fallback to rule-based responses. Supports English and Lusoga languages.
 */

namespace App;

class AIAssistant {
    private $db;
    private $openaiApiKey;
    private $model;
    private $maxTokens = 500;
    private $temperature = 0.7;
    private $timeout = 30;
    
    // Knowledge base cache
    private static $knowledgeBase = null;
    
    public function __construct() {
        $this->db = Database::getInstance();
        $this->openaiApiKey = $_ENV['OPENAI_API_KEY'] ?? '';
        $this->model = $_ENV['OPENAI_MODEL'] ?? 'gpt-4-turbo-preview';
    }
    
    /**
     * Main method to get AI response
     * 
     * @param string $message User's message
     * @param int $userId User ID
     * @param array $context User context (location, crops, etc.)
     * @return array Response with message, language, and metadata
     */
    public function getResponse($message, $userId, $context = []) {
        try {
            // Validate input
            if (empty($message)) {
                throw new \Exception('Message cannot be empty');
            }
            
            if (strlen($message) > 1000) {
                throw new \Exception('Message too long. Maximum 1000 characters.');
            }
            
            // Detect language
            $language = $this->detectLanguage($message);
            
            // Try OpenAI first if API key is configured
            if ($this->isOpenAIConfigured()) {
                try {
                    $response = $this->getOpenAIResponse($message, $language, $context);
                    
                    // Save conversation
                    $this->saveConversation($userId, $message, $response, $language, 'openai');
                    
                    return [
                        'success' => true,
                        'response' => $response,
                        'language' => $language,
                        'source' => 'openai',
                        'timestamp' => date('Y-m-d H:i:s')
                    ];
                    
                } catch (\Exception $e) {
                    // Log OpenAI error and fall through to rule-based
                    error_log('OpenAI Error: ' . $e->getMessage());
                }
            }
            
            // Fallback to rule-based system
            $response = $this->getRuleBasedResponse($message, $language, $context);
            
            // Save conversation
            $this->saveConversation($userId, $message, $response, $language, 'rule_based');
            
            return [
                'success' => true,
                'response' => $response,
                'language' => $language,
                'source' => 'rule_based',
                'timestamp' => date('Y-m-d H:i:s')
            ];
            
        } 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',
                'timestamp' => date('Y-m-d H:i:s')
            ];
        }
    }
    
    /**
     * Check if OpenAI is properly configured
     */
    private function isOpenAIConfigured() {
        return !empty($this->openaiApiKey) && 
               $this->openaiApiKey !== 'your_openai_api_key' &&
               strpos($this->openaiApiKey, 'sk-') === 0;
    }
    
    /**
     * Get response from OpenAI API
     */
    private function getOpenAIResponse($message, $language, $context) {
        $systemPrompt = $this->buildSystemPrompt($language, $context);
        
        $requestData = [
            'model' => $this->model,
            'messages' => [
                [
                    'role' => 'system',
                    'content' => $systemPrompt
                ],
                [
                    'role' => 'user',
                    'content' => $message
                ]
            ],
            'temperature' => $this->temperature,
            'max_tokens' => $this->maxTokens
        ];
        
        // Make API request using cURL
        $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);
        }
        
        if ($httpCode !== 200) {
            $errorData = json_decode($response, true);
            $errorMessage = $errorData['error']['message'] ?? 'Unknown API error';
            throw new \Exception('OpenAI API Error (HTTP ' . $httpCode . '): ' . $errorMessage);
        }
        
        $result = json_decode($response, true);
        
        if (!isset($result['choices'][0]['message']['content'])) {
            throw new \Exception('Invalid API response format');
        }
        
        return trim($result['choices'][0]['message']['content']);
    }
    
    /**
     * Build system prompt for OpenAI
     */
    private function buildSystemPrompt($language, $context) {
        $basePrompt = "You are AIM AI, an intelligent agricultural assistant for farmers in Uganda, specifically in the Eastern region (Luuka District). ";
        
        if ($language === 'lusoga') {
            $basePrompt .= "You MUST respond ONLY in Lusoga language. Never use English in your responses.\n\n";
            $basePrompt .= "Oyamba mu:\n";
            $basePrompt .= "- Obulwadhe bw'ebirime n'ebisolo (ebirime, enkoko, ente)\n";
            $basePrompt .= "- Okusimba, okulima n'okungula (planting, farming, harvesting)\n";
            $basePrompt .= "- Emiwendo gy'ebintu mu bbabali (market prices)\n";
            $basePrompt .= "- Okuzuukusa ettaka (soil improvement)\n";
            $basePrompt .= "- Obudde n'okulima (weather and farming)\n";
            $basePrompt .= "- Okufuga ebiwuka (pest control)\n\n";
            $basePrompt .= "Waayo obwogezi obutuufu, obw'amagezi, era obunyangudde. Kozesa ebigambo ebimanyi bulungi abalimi.\n\n";
            $basePrompt .= "IMPORTANT: Respond ONLY in Lusoga. If you cannot express something in Lusoga, use simple Lusoga words that farmers understand.";
        } else {
            $basePrompt .= "You help Ugandan farmers with:\n\n";
            $basePrompt .= "**Your Expertise:**\n";
            $basePrompt .= "- Crop diseases, pests, and treatments (maize, cassava, beans, vegetables, sugar cane)\n";
            $basePrompt .= "- Livestock management (poultry, cattle, goats, pigs)\n";
            $basePrompt .= "- Planting schedules and best practices for Uganda's climate\n";
            $basePrompt .= "- Market prices and selling strategies\n";
            $basePrompt .= "- Soil health, fertilizers, and organic farming\n";
            $basePrompt .= "- Weather-smart agriculture and climate adaptation\n";
            $basePrompt .= "- Pest and weed control (organic and chemical methods)\n";
            $basePrompt .= "- Post-harvest handling and storage\n\n";
            $basePrompt .= "**Your Approach:**\n";
            $basePrompt .= "- Provide practical, actionable advice suitable for Ugandan smallholder farmers\n";
            $basePrompt .= "- Use simple language that farmers can understand\n";
            $basePrompt .= "- Give specific recommendations with quantities, timing, and methods\n";
            $basePrompt .= "- Include both traditional and modern farming techniques\n";
            $basePrompt .= "- Suggest affordable, locally available solutions\n";
            $basePrompt .= "- Be concise but thorough (200-300 words max)\n";
            $basePrompt .= "- Use bullet points for steps and lists\n";
            $basePrompt .= "- Include Ugandan Shillings (UGX) for costs when relevant\n\n";
            $basePrompt .= "**Format Guidelines:**\n";
            $basePrompt .= "- Use **bold** for important terms\n";
            $basePrompt .= "- Use numbered lists for steps\n";
            $basePrompt .= "- Use bullet points for options/varieties\n";
            $basePrompt .= "- Include emojis sparingly for engagement (🌱🌾💰🐔)\n";
        }
        
        // Add user context
        if (!empty($context['location'])) {
            $basePrompt .= "\n\n**User Location:** " . $context['location'];
        }
        
        if (!empty($context['current_crops'])) {
            $crops = implode(', ', $context['current_crops']);
            $basePrompt .= "\n**User's Current Crops:** " . $crops;
        }
        
        if (!empty($context['user_type'])) {
            $basePrompt .= "\n**User Type:** " . ucfirst($context['user_type']);
        }
        
        return $basePrompt;
    }
    
    /**
     * Detect language (English or Lusoga)
     */
    private function detectLanguage($message) {
        $lusogaPatterns = [
            // Common Lusoga words
            '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',
            // Greetings
            'wasuze', 'osiibiile', 'oli otya', 'webale', 'mwebale',
            // Questions
            'ditya', 'ndiyinza', 'osobola', 'kyenkana',
            // Common verbs
            'okuva', 'okugenda', 'okula', 'okwogera', 'okulaba',
            // Pronouns
            'nze', 'gwe', 'ye', 'ffe', 'mmwe', 'bo'
        ];
        
        $messageLower = mb_strtolower($message, 'UTF-8');
        
        // Count Lusoga word matches
        $matches = 0;
        foreach ($lusogaPatterns as $pattern) {
            if (mb_strpos($messageLower, $pattern) !== false) {
                $matches++;
            }
        }
        
        // If 2 or more Lusoga words found, consider it Lusoga
        return $matches >= 2 ? 'lusoga' : 'en';
    }
    
    /**
     * Get rule-based response (fallback when OpenAI unavailable)
     */
    private function getRuleBasedResponse($message, $language, $context) {
        $knowledgeBase = $this->getKnowledgeBase($language);
        $messageLower = mb_strtolower($message, 'UTF-8');
        
        // Try to match patterns
        foreach ($knowledgeBase as $pattern => $response) {
            if (preg_match($pattern, $messageLower)) {
                return $this->personalizeResponse($response, $context, $language);
            }
        }
        
        // No match found - return default response
        return $this->getDefaultResponse($language);
    }
    
    /**
     * Load knowledge base
     */
    private function getKnowledgeBase($language) {
        // Cache knowledge base to avoid repeated loading
        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 with user context
     */
    private function personalizeResponse($response, $context, $language) {
        // Add location information 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;
    }
    
    /**
     * Get default response when no pattern matches
     */
    private function getDefaultResponse($language) {
        if ($language === 'lusoga') {
            return "Nsonyiwa, simanyi bulungi ekyo. 🤔\n\n" .
                   "Ndiyinza okukuyamba mu:\n" .
                   "- **Obulwadhe bw'ebirime** (maize, muwogo, bikooge)\n" .
                   "- **Okusimba n'okungula** ebirime\n" .
                   "- **Emiwendo** gy'ebintu mu bbabali\n" .
                   "- **Okuzuukusa ettaka** n'okulongoosa\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** (identification and treatment)\n" .
                   "- **Planting Schedules** (best times and methods)\n" .
                   "- **Market Prices** (current rates and trends)\n" .
                   "- **Soil Management** (fertilizers and improvement)\n" .
                   "- **Weather & Climate** (farming advice)\n" .
                   "- **Livestock Care** (poultry, cattle, goats)\n\n" .
                   "Please ask a specific question about farming, and I'll be happy to help! 🌾";
        }
    }
    
    /**
     * Get error response
     */
    private function getErrorResponse($language) {
        if ($language === 'lusoga') {
            return "Nsonyiwa, waliwo ekizibu. Gezaako nate oluvannyuma. 🙏";
        } else {
            return "I'm sorry, I encountered an error. Please try again in a moment. 🙏";
        }
    }
    
    /**
     * Save conversation to database
     */
    private function saveConversation($userId, $message, $response, $language, $source) {
        try {
            // Generate session ID if not exists
            if (!isset($_SESSION['ai_session_id'])) {
                $_SESSION['ai_session_id'] = uniqid('ai_session_', true);
            }
            
            $sql = "INSERT INTO ai_conversations 
                    (user_id, session_id, message, response, language, source, created_at)
                    VALUES (?, ?, ?, ?, ?, ?, NOW())";
            
            $this->db->execute($sql, [
                $userId,
                $_SESSION['ai_session_id'],
                $message,
                $response,
                $language,
                $source
            ]);
            
        } catch (\Exception $e) {
            error_log('Error saving AI conversation: ' . $e->getMessage());
            // Don't throw - saving is not critical
        }
    }
    
    /**
     * Get conversation history
     */
    public function getConversationHistory($userId, $limit = 20) {
        try {
            $sql = "SELECT * FROM ai_conversations 
                    WHERE user_id = ? 
                    ORDER BY created_at DESC 
                    LIMIT ?";
            
            return $this->db->fetchAll($sql, [$userId, $limit]);
            
        } catch (\Exception $e) {
            error_log('Error fetching conversation history: ' . $e->getMessage());
            return [];
        }
    }
    
    /**
     * Clear conversation history for a user
     */
    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 conversation statistics
     */
    public function getStats($userId) {
        try {
            $sql = "SELECT 
                        COUNT(*) as total_conversations,
                        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;
        }
    }
}