<?php
/**
 * WhatsApp Bot Service
 * Handles WhatsApp Business API integration for member interactions
 * Kenyan Pension & Life Insurance Management System
 */

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

class WhatsAppBotService {
    private $conn;
    private $apiUrl;
    private $apiKey;
    private $phoneNumberId;
    private $accessToken;
    private $aiChatbot;
    
    public function __construct($db_connection) {
        $this->conn = $db_connection;
        
        // Get WhatsApp settings from system_settings
        $settings = $this->conn->query("SELECT setting_key, setting_value FROM system_settings 
                                       WHERE setting_key IN ('whatsapp_api_url', 'whatsapp_api_key', 
                                       'whatsapp_phone_number_id', 'whatsapp_access_token')")->fetch_all(MYSQLI_ASSOC);
        
        $settingsMap = [];
        foreach ($settings as $setting) {
            $settingsMap[$setting['setting_key']] = $setting['setting_value'];
        }
        
        $this->apiUrl = $settingsMap['whatsapp_api_url'] ?? 'https://graph.facebook.com/v18.0';
        $this->apiKey = $settingsMap['whatsapp_api_key'] ?? '';
        $this->phoneNumberId = $settingsMap['whatsapp_phone_number_id'] ?? '';
        $this->accessToken = $settingsMap['whatsapp_access_token'] ?? '';
        
        $this->aiChatbot = new AIChatbotService($db_connection);
    }
    
    /**
     * Process incoming WhatsApp message
     */
    public function processMessage($from, $message) {
        // Get member by phone number
        $member = $this->getMemberByPhone($from);
        
        if (!$member) {
            return $this->sendMessage($from, "Sorry, your phone number is not registered in our system. Please contact support.");
        }
        
        // Parse command
        $command = strtoupper(trim($message));
        $parts = explode(' ', $command);
        $action = $parts[0];
        
        switch ($action) {
            case 'BALANCE':
            case 'BAL':
                return $this->getBalance($from, $member);
                
            case 'STATEMENT':
            case 'STMT':
                return $this->getStatement($from, $member);
                
            case 'CONTRIBUTIONS':
            case 'CONT':
                return $this->getContributions($from, $member);
                
            case 'WITHDRAWALS':
            case 'WITHDRAWAL':
                return $this->getWithdrawals($from, $member);
                
            case 'POLICIES':
            case 'POLICY':
                return $this->getPolicies($from, $member);
                
            case 'HELP':
                return $this->sendHelp($from);
                
            default:
                // Try AI chatbot for natural language queries
                return $this->handleAIQuery($from, $member, $message);
        }
    }
    
    /**
     * Get member account balance
     */
    private function getBalance($from, $member) {
        $sql = "SELECT ma.*, ps.scheme_name 
                FROM member_accounts ma
                LEFT JOIN members m ON ma.member_id = m.member_id
                LEFT JOIN pension_schemes ps ON m.scheme_id = ps.scheme_id
                WHERE ma.member_id = ?";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $member['member_id']);
        $stmt->execute();
        $account = $stmt->get_result()->fetch_assoc();
        
        if ($account) {
            $message = "📊 *Account Balance*\n\n";
            $message .= "Scheme: {$account['scheme_name']}\n";
            $message .= "Accrued Benefits: KES " . number_format($account['accrued_benefits'], 2) . "\n";
            $message .= "Available Balance: KES " . number_format($account['available_balance'], 2) . "\n";
            $message .= "Employee Contributions: KES " . number_format($account['total_employee_contributions'], 2) . "\n";
            $message .= "Employer Contributions: KES " . number_format($account['total_employer_contributions'], 2) . "\n";
            $message .= "Investment Returns: KES " . number_format($account['allocated_investment_returns'], 2);
        } else {
            $message = "Account not found. Please contact support.";
        }
        
        return $this->sendMessage($from, $message);
    }
    
    /**
     * Get member statement summary
     */
    private function getStatement($from, $member) {
        $sql = "SELECT 
                   COUNT(*) as total_contributions,
                   SUM(contribution_amount) as total_contributed
                FROM contributions 
                WHERE member_id = ? AND status = 'PROCESSED'";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $member['member_id']);
        $stmt->execute();
        $stats = $stmt->get_result()->fetch_assoc();
        
        $message = "📄 *Account Statement Summary*\n\n";
        $message .= "Member: {$member['member_number']}\n";
        $message .= "Total Contributions: {$stats['total_contributions']}\n";
        $message .= "Total Contributed: KES " . number_format($stats['total_contributed'] ?? 0, 2) . "\n\n";
        $message .= "For detailed statement, please login to your portal or reply *FULL* for full statement.";
        
        return $this->sendMessage($from, $message);
    }
    
    /**
     * Get recent contributions
     */
    private function getContributions($from, $member) {
        $sql = "SELECT contribution_period, contribution_type, contribution_amount, status
                FROM contributions 
                WHERE member_id = ? 
                ORDER BY contribution_period DESC 
                LIMIT 5";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $member['member_id']);
        $stmt->execute();
        $contributions = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        
        $message = "💰 *Recent Contributions*\n\n";
        
        if (empty($contributions)) {
            $message .= "No contributions found.";
        } else {
            foreach ($contributions as $cont) {
                $message .= date('M Y', strtotime($cont['contribution_period'])) . ": ";
                $message .= "KES " . number_format($cont['contribution_amount'], 2) . " ({$cont['contribution_type']})\n";
            }
        }
        
        return $this->sendMessage($from, $message);
    }
    
    /**
     * Get recent withdrawals
     */
    private function getWithdrawals($from, $member) {
        $sql = "SELECT withdrawal_type, requested_amount, calculated_amount, status, requested_date
                FROM withdrawal_requests 
                WHERE member_id = ? 
                ORDER BY requested_date DESC 
                LIMIT 5";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $member['member_id']);
        $stmt->execute();
        $withdrawals = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        
        $message = "💸 *Recent Withdrawals*\n\n";
        
        if (empty($withdrawals)) {
            $message .= "No withdrawals found.";
        } else {
            foreach ($withdrawals as $withdrawal) {
                $message .= date('d M Y', strtotime($withdrawal['requested_date'])) . ": ";
                $message .= "KES " . number_format($withdrawal['calculated_amount'] ?? $withdrawal['requested_amount'], 2);
                $message .= " ({$withdrawal['withdrawal_type']}) - {$withdrawal['status']}\n";
            }
        }
        
        return $this->sendMessage($from, $message);
    }
    
    /**
     * Get member policies
     */
    private function getPolicies($from, $member) {
        $sql = "SELECT lp.policy_number, lip.product_name, lp.sum_assured, lp.policy_status
                FROM life_policies lp
                LEFT JOIN life_insurance_products lip ON lp.product_id = lip.product_id
                WHERE lp.member_id = ?";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("i", $member['member_id']);
        $stmt->execute();
        $policies = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        
        $message = "🛡️ *Your Policies*\n\n";
        
        if (empty($policies)) {
            $message .= "No active policies found.";
        } else {
            foreach ($policies as $policy) {
                $message .= "Policy: {$policy['policy_number']}\n";
                $message .= "Product: {$policy['product_name']}\n";
                $message .= "Sum Assured: KES " . number_format($policy['sum_assured'], 2) . "\n";
                $message .= "Status: {$policy['policy_status']}\n\n";
            }
        }
        
        return $this->sendMessage($from, $message);
    }
    
    /**
     * Send help message
     */
    private function sendHelp($from) {
        $message = "📱 *Pension & Insurance Bot*\n\n";
        $message .= "Available commands:\n\n";
        $message .= "*BALANCE* - Check account balance\n";
        $message .= "*STATEMENT* - Get account statement\n";
        $message .= "*CONTRIBUTIONS* - View recent contributions\n";
        $message .= "*WITHDRAWALS* - View withdrawal history\n";
        $message .= "*POLICIES* - View life insurance policies\n";
        $message .= "*HELP* - Show this help message\n\n";
        $message .= "You can also ask questions in natural language!";
        
        return $this->sendMessage($from, $message);
    }
    
    /**
     * Handle AI-powered natural language queries
     */
    private function handleAIQuery($from, $member, $query) {
        $result = $this->aiChatbot->getWithdrawalCalculationHelp($member['member_id'], $query);
        
        if ($result['success']) {
            $message = $result['response'];
        } else {
            $message = "I'm sorry, I couldn't process your query. Please try using one of the commands (type *HELP* for list) or contact support.";
        }
        
        return $this->sendMessage($from, $message);
    }
    
    /**
     * Get member by phone number
     */
    private function getMemberByPhone($phone) {
        // Normalize phone number (remove +, spaces, etc.)
        $phone = preg_replace('/[^0-9]/', '', $phone);
        
        $sql = "SELECT m.* FROM members m 
                WHERE REPLACE(REPLACE(REPLACE(m.phone_number, '+', ''), ' ', ''), '-', '') = ?
                AND m.is_active = 1";
        
        $stmt = $this->conn->prepare($sql);
        $stmt->bind_param("s", $phone);
        $stmt->execute();
        $result = $stmt->get_result();
        
        return $result->fetch_assoc();
    }
    
    /**
     * Send WhatsApp message
     */
    public function sendMessage($to, $message) {
        if (empty($this->accessToken) || empty($this->phoneNumberId)) {
            return ['success' => false, 'message' => 'WhatsApp not configured'];
        }
        
        $url = "{$this->apiUrl}/{$this->phoneNumberId}/messages";
        
        $data = [
            'messaging_product' => 'whatsapp',
            'to' => $to,
            'type' => 'text',
            'text' => [
                'body' => $message
            ]
        ];
        
        $ch = curl_init($url);
        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->accessToken}"
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode === 200) {
            return ['success' => true, 'message' => 'Message sent'];
        } else {
            return ['success' => false, 'message' => 'Failed to send message', 'response' => $response];
        }
    }
}
