<?php
/**
 * AI Chatbot Service
 * Handles AI-powered chatbot interactions for withdrawal calculations and guidance
 * Kenyan Pension & Life Insurance Management System
 */

require_once __DIR__ . '/../includes/dbconn.php';

class AIChatbotService {
    private $conn;
    private $apiKey;
    private $apiUrl = 'https://api.openai.com/v1/chat/completions';
    private $model = 'gpt-4'; // Can be changed to gpt-3.5-turbo for cost savings
    
    public function __construct($db_connection) {
        $this->conn = $db_connection;
        // Get API key from system settings or environment
        $this->apiKey = getenv('OPENAI_API_KEY');
        if (empty($this->apiKey)) {
            $settings = $this->conn->query("SELECT setting_value FROM system_settings WHERE setting_key = 'openai_api_key'")->fetch_assoc();
            $this->apiKey = $settings['setting_value'] ?? null;
        }
    }
    
    /**
     * Get AI response for withdrawal calculation questions
     */
    public function getWithdrawalCalculationHelp($member_id = null, $question = '', $context = []) {
        if (empty($this->apiKey)) {
            return [
                'success' => false,
                'message' => 'AI service not configured. Please contact administrator.'
            ];
        }
        
        // Build context about Kenyan pension system
        $systemContext = $this->buildSystemContext($member_id, $context);
        
        // Build the prompt
        $messages = [
            [
                'role' => 'system',
                'content' => $systemContext
            ],
            [
                'role' => 'user',
                'content' => $question
            ]
        ];
        
        try {
            $response = $this->callOpenAI($messages);
            return [
                'success' => true,
                'response' => $response,
                'timestamp' => date('Y-m-d H:i:s')
            ];
        } catch (Exception $e) {
            return [
                'success' => false,
                'message' => 'AI service error: ' . $e->getMessage()
            ];
        }
    }
    
    /**
     * Check withdrawal eligibility using AI (with database validation)
     */
    public function checkWithdrawalEligibility($member_id, $withdrawal_type) {
        // First, get actual eligibility from database
        $sql = "CALL sp_validate_withdrawal_eligibility(?, ?, CURDATE(), @is_eligible, @eligible_amount, @rejection_reason)";
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("is", $member_id, $withdrawal_type);
        $stmt->execute();
        $stmt->close();
        
        $result = $this->conn->query("SELECT @is_eligible as is_eligible, @eligible_amount as eligible_amount, @rejection_reason as rejection_reason");
        $eligibility = $result->fetch_assoc();
        
        // Get member and scheme details for AI context
        $member = $this->conn->query("SELECT m.*, ps.scheme_name, ps.scheme_type, ps.retirement_age, 
                                     ps.early_exit_max_cash_percentage, ma.accrued_benefits, ma.available_balance
                                     FROM members m
                                     LEFT JOIN pension_schemes ps ON m.scheme_id = ps.scheme_id
                                     LEFT JOIN member_accounts ma ON m.member_id = ma.member_id
                                     WHERE m.member_id = $member_id")->fetch_assoc();
        
        if (!$member) {
            return ['success' => false, 'message' => 'Member not found'];
        }
        
        // Calculate age
        $age = date_diff(date_create($member['date_of_birth']), date_create('today'))->y;
        
        // Build AI explanation
        $question = "Explain why I " . ($eligibility['is_eligible'] ? 'am eligible' : 'am not eligible') . 
                   " for a $withdrawal_type withdrawal. My age is $age, retirement age is {$member['retirement_age']}, " .
                   "accrued benefits are KES " . number_format($member['accrued_benefits'], 2) . 
                   ", and available balance is KES " . number_format($member['available_balance'], 2) . 
                   ". Scheme type: {$member['scheme_type']}.";
        
        if (!$eligibility['is_eligible']) {
            $question .= " Rejection reason: " . ($eligibility['rejection_reason'] ?? 'Not specified');
        }
        
        $aiResponse = $this->getWithdrawalCalculationHelp($member_id, $question, [
            'member' => $member,
            'eligibility' => $eligibility
        ]);
        
        return [
            'success' => true,
            'is_eligible' => (bool)$eligibility['is_eligible'],
            'eligible_amount' => $eligibility['eligible_amount'],
            'rejection_reason' => $eligibility['rejection_reason'],
            'ai_explanation' => $aiResponse['response'] ?? null,
            'member_data' => [
                'age' => $age,
                'retirement_age' => $member['retirement_age'],
                'accrued_benefits' => $member['accrued_benefits'],
                'available_balance' => $member['available_balance']
            ]
        ];
    }
    
    /**
     * Explain withdrawal calculation formula
     */
    public function explainCalculation($member_id, $withdrawal_type) {
        $member = $this->conn->query("SELECT m.*, ps.*, ma.*
                                     FROM members m
                                     LEFT JOIN pension_schemes ps ON m.scheme_id = ps.scheme_id
                                     LEFT JOIN member_accounts ma ON m.member_id = ma.member_id
                                     WHERE m.member_id = $member_id")->fetch_assoc();
        
        $question = "Explain how my $withdrawal_type withdrawal amount will be calculated. " .
                   "My scheme is {$member['scheme_type']}, " .
                   "accrued benefits: KES " . number_format($member['accrued_benefits'], 2) . ", " .
                   "available balance: KES " . number_format($member['available_balance'], 2) . ". " .
                   "For early exit, max cash percentage is {$member['early_exit_max_cash_percentage']}%. " .
                   "Please explain the calculation step by step in simple terms.";
        
        return $this->getWithdrawalCalculationHelp($member_id, $question, ['member' => $member]);
    }
    
    /**
     * Build system context for AI
     */
    private function buildSystemContext($member_id = null, $context = []) {
        $contextText = "You are an AI assistant for a Kenyan Pension & Life Insurance Management System. ";
        $contextText .= "You help users understand pension withdrawal calculations and eligibility.\n\n";
        
        $contextText .= "KENYAN PENSION RULES:\n";
        $contextText .= "- Occupational & Umbrella schemes: Maximum 50% of accrued benefits as cash for early exit\n";
        $contextText .= "- Individual Pension Plans (IPP): Up to 100% of accrued benefits for early exit\n";
        $contextText .= "- Retirement: Partial commutation allowed (scheme-defined percentage)\n";
        $contextText .= "- Disability/Emigration: 100% of vested accrued benefits\n";
        $contextText .= "- Accrued Benefits = Employee Contributions + Employer Contributions + Investment Returns\n";
        $contextText .= "- Available Balance = Accrued Benefits - Total Withdrawn\n\n";
        
        $contextText .= "CALCULATION FORMULAS:\n";
        $contextText .= "1. Accrued Benefits = Total Employee Contributions + Total Employer Contributions + Allocated Investment Returns\n";
        $contextText .= "2. Early Exit Cash = min(Requested Amount, Available Balance × Max Cash Percentage)\n";
        $contextText .= "3. Retirement Commutation = min(Requested Amount, Available Balance × Commutation Percentage)\n";
        $contextText .= "4. Disability/Emigration = min(Requested Amount, Available Balance)\n\n";
        
        $contextText .= "IMPORTANT:\n";
        $contextText .= "- Always use KES (Kenyan Shillings) as currency\n";
        $contextText .= "- Explain calculations in simple, clear terms\n";
        $contextText .= "- Reference Kenyan RBA regulations when relevant\n";
        $contextText .= "- Be helpful and educational\n";
        $contextText .= "- If you don't know something, say so rather than guessing\n\n";
        
        if ($member_id && !empty($context['member'])) {
            $member = $context['member'];
            $age = date_diff(date_create($member['date_of_birth']), date_create('today'))->y;
            
            $contextText .= "MEMBER CONTEXT:\n";
            $contextText .= "- Age: $age years\n";
            $contextText .= "- Retirement Age: {$member['retirement_age']} years\n";
            $contextText .= "- Scheme Type: {$member['scheme_type']}\n";
            $contextText .= "- Employment Status: {$member['employment_status']}\n";
            $contextText .= "- Accrued Benefits: KES " . number_format($member['accrued_benefits'], 2) . "\n";
            $contextText .= "- Available Balance: KES " . number_format($member['available_balance'], 2) . "\n\n";
        }
        
        return $contextText;
    }
    
    /**
     * Call OpenAI API
     */
    private function callOpenAI($messages) {
        $ch = curl_init($this->apiUrl);
        
        $data = [
            'model' => $this->model,
            'messages' => $messages,
            'temperature' => 0.7,
            'max_tokens' => 500
        ];
        
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $this->apiKey
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode !== 200) {
            throw new Exception('OpenAI API error: ' . $response);
        }
        
        $result = json_decode($response, true);
        
        if (!isset($result['choices'][0]['message']['content'])) {
            throw new Exception('Invalid response from OpenAI API');
        }
        
        return $result['choices'][0]['message']['content'];
    }
    
    /**
     * Log AI interaction for audit
     */
    public function logInteraction($user_id, $member_id, $question, $response, $context = []) {
        $sql = "INSERT INTO audit_logs (
                   event_type, event_category, user_id, member_id,
                   event_description, performed_by, ip_address
               ) VALUES (?, ?, ?, ?, ?, ?, ?)";
        
        $event_description = "AI Chatbot: Q: " . substr($question, 0, 200) . " | A: " . substr($response, 0, 200);
        $performed_by = $_SESSION['username'] ?? 'AI_SYSTEM';
        $ip_address = $_SERVER['REMOTE_ADDR'] ?? null;
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("ssiisss",
            'AI_CHATBOT_QUERY',
            'AI_INTERACTION',
            $user_id,
            $member_id,
            $event_description,
            $performed_by,
            $ip_address
        );
        $stmt->execute();
    }
}
