<?php
/**
 * bKash Payment Gateway Integration Class
 * 
 * This class handles direct integration with the bKash payment gateway
 * for accepting payments from students
 */

require_once dirname(__DIR__) . '/config/database.php';

class bKashPayment {
    private $app_key;
    private $app_secret;
    private $username;
    private $password;
    private $base_url;
    private $callback_url;
    private $enabled;
    private $sandbox_mode;
    
    public function __construct() {
        $this->loadConfig();
    }
    
    /**
     * Load configuration from database
     */
    private function loadConfig() {
        global $pdo;
        
        try {
            $stmt = $pdo->query("SELECT setting_key, setting_value FROM settings WHERE setting_key LIKE 'bkash_%'");
            $settings = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
            
            $this->enabled = isset($settings['bkash_enabled']) && $settings['bkash_enabled'] == '1';
            $this->app_key = $settings['bkash_app_key'] ?? '';
            $this->app_secret = $settings['bkash_app_secret'] ?? '';
            $this->username = $settings['bkash_username'] ?? '';
            $this->password = $settings['bkash_password'] ?? '';
            $this->sandbox_mode = isset($settings['bkash_sandbox_mode']) && $settings['bkash_sandbox_mode'] == '1';
            
            // Set base URL based on sandbox mode
            if ($this->sandbox_mode) {
                $this->base_url = 'https://tokenized.sandbox.bka.sh/v1.2.0-beta/tokenized';
            } else {
                $this->base_url = 'https://tokenized.pay.bka.sh/v1.2.0-beta/tokenized';
            }
            
            // Set callback URL
            $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
            $this->callback_url = 'http://' . $host . '/fees/bkash_callback.php';
            
        } catch (Exception $e) {
            $this->enabled = false;
            $this->app_key = '';
            $this->app_secret = '';
            $this->username = '';
            $this->password = '';
            $this->base_url = '';
            $this->sandbox_mode = true;
        }
    }
    
    /**
     * Check if the payment gateway is enabled and properly configured
     */
    public function isEnabled() {
        return $this->enabled && 
               !empty($this->app_key) && 
               !empty($this->app_secret) && 
               !empty($this->username) && 
               !empty($this->password);
    }
    
    /**
     * Get configuration status
     */
    public function getConfigStatus() {
        return [
            'enabled' => $this->enabled,
            'app_key_set' => !empty($this->app_key),
            'app_secret_set' => !empty($this->app_secret),
            'username_set' => !empty($this->username),
            'password_set' => !empty($this->password),
            'sandbox_mode' => $this->sandbox_mode,
            'base_url' => $this->base_url
        ];
    }
    
    /**
     * Get access token from bKash
     */
    private function getAccessToken() {
        if (!$this->isEnabled()) {
            throw new Exception("bKash payment gateway is not enabled or properly configured");
        }
        
        $url = $this->base_url . '/checkout/token/grant';
        
        $data = [
            'app_key' => $this->app_key,
            'app_secret' => $this->app_secret
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Accept: application/json'
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception("cURL Error: " . $error);
        }
        
        if ($httpCode !== 200) {
            throw new Exception("Token request failed with HTTP code: " . $httpCode);
        }
        
        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("Invalid JSON response: " . $response);
        }
        
        if (!isset($result['id_token'])) {
            throw new Exception("Access token not found in response: " . $response);
        }
        
        return $result['id_token'];
    }
    
    /**
     * Create a payment request
     */
    public function createPayment($amount, $student_info, $intent = 'sale') {
        if (!$this->isEnabled()) {
            throw new Exception("bKash payment gateway is not enabled or properly configured");
        }
        
        // Get access token
        $token = $this->getAccessToken();
        
        // Generate unique merchant invoice number
        $merchantInvoiceNumber = 'INV_' . time() . '_' . uniqid();
        
        $url = $this->base_url . '/checkout/payment/create';
        
        $data = [
            'amount' => number_format($amount, 2, '.', ''),
            'currency' => 'BDT',
            'intent' => $intent,
            'merchantInvoiceNumber' => $merchantInvoiceNumber,
            'callbackURL' => $this->callback_url
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Accept: application/json',
            'Authorization: ' . $token,
            'X-APP-Key: ' . $this->app_key
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception("cURL Error: " . $error);
        }
        
        if ($httpCode !== 200) {
            throw new Exception("Payment creation failed with HTTP code: " . $httpCode);
        }
        
        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("Invalid JSON response: " . $response);
        }
        
        // Store payment info in database for later verification
        $this->storePaymentInfo($merchantInvoiceNumber, $amount, $student_info, $result);
        
        return [
            'merchantInvoiceNumber' => $merchantInvoiceNumber,
            'paymentUrl' => $result['bkashURL'] ?? '',
            'response' => $result
        ];
    }
    
    /**
     * Store payment information in database
     */
    private function storePaymentInfo($merchantInvoiceNumber, $amount, $student_info, $response) {
        global $pdo;
        
        try {
            $stmt = $pdo->prepare("
                INSERT INTO bkash_payment_requests 
                (merchant_invoice_number, amount, student_id, student_name, student_phone, response_data, created_at) 
                VALUES (?, ?, ?, ?, ?, ?, NOW())
            ");
            $stmt->execute([
                $merchantInvoiceNumber,
                $amount,
                $student_info['student_id'] ?? '',
                $student_info['name'] ?? '',
                $student_info['phone'] ?? '',
                json_encode($response)
            ]);
        } catch (Exception $e) {
            error_log("Failed to store bKash payment info: " . $e->getMessage());
        }
    }
    
    /**
     * Verify payment status
     */
    public function verifyPayment($merchantInvoiceNumber) {
        if (!$this->isEnabled()) {
            throw new Exception("bKash payment gateway is not enabled or properly configured");
        }
        
        // Get access token
        $token = $this->getAccessToken();
        
        $url = $this->base_url . '/checkout/payment/search/' . urlencode($merchantInvoiceNumber);
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Accept: application/json',
            'Authorization: ' . $token,
            'X-APP-Key: ' . $this->app_key
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception("cURL Error: " . $error);
        }
        
        if ($httpCode !== 200) {
            throw new Exception("Payment verification failed with HTTP code: " . $httpCode);
        }
        
        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("Invalid JSON response: " . $response);
        }
        
        return $result;
    }
    
    /**
     * Execute a payment
     */
    public function executePayment($paymentId) {
        if (!$this->isEnabled()) {
            throw new Exception("bKash payment gateway is not enabled or properly configured");
        }
        
        // Get access token
        $token = $this->getAccessToken();
        
        $url = $this->base_url . '/checkout/payment/execute/' . urlencode($paymentId);
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Accept: application/json',
            'Authorization: ' . $token,
            'X-APP-Key: ' . $this->app_key
        ]);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error) {
            throw new Exception("cURL Error: " . $error);
        }
        
        if ($httpCode !== 200) {
            throw new Exception("Payment execution failed with HTTP code: " . $httpCode);
        }
        
        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new Exception("Invalid JSON response: " . $response);
        }
        
        return $result;
    }
}

/**
 * Get bKash configuration
 */
function get_bkash_config() {
    global $pdo;
    
    try {
        $stmt = $pdo->query("SELECT setting_key, setting_value FROM settings WHERE setting_key LIKE 'bkash_%'");
        $settings = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
        
        // Check if we're running from command line (no HTTP_HOST)
        $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
        
        return [
            'enabled' => isset($settings['bkash_enabled']) && $settings['bkash_enabled'] == '1',
            'app_key' => $settings['bkash_app_key'] ?? '',
            'app_secret' => $settings['bkash_app_secret'] ?? '',
            'username' => $settings['bkash_username'] ?? '',
            'password' => $settings['bkash_password'] ?? '',
            'sandbox_mode' => isset($settings['bkash_sandbox_mode']) && $settings['bkash_sandbox_mode'] == '1',
            'callback_url' => 'http://' . $host . '/fees/bkash_callback.php'
        ];
    } catch (Exception $e) {
        return [
            'enabled' => false,
            'app_key' => '',
            'app_secret' => '',
            'username' => '',
            'password' => '',
            'sandbox_mode' => true,
            'callback_url' => ''
        ];
    }
}

/**
 * Create bKash payment requests table
 */
function create_bkash_tables() {
    global $pdo;
    
    try {
        // Create payment requests table
        $sql = "
        CREATE TABLE IF NOT EXISTS bkash_payment_requests (
            id INT AUTO_INCREMENT PRIMARY KEY,
            merchant_invoice_number VARCHAR(100) NOT NULL UNIQUE,
            amount DECIMAL(10,2) NOT NULL,
            student_id VARCHAR(50),
            student_name VARCHAR(100),
            student_phone VARCHAR(20),
            response_data TEXT,
            status ENUM('pending', 'completed', 'failed', 'cancelled') DEFAULT 'pending',
            transaction_id VARCHAR(100),
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            
            INDEX idx_merchant_invoice (merchant_invoice_number),
            INDEX idx_student_id (student_id),
            INDEX idx_status (status),
            INDEX idx_created_at (created_at)
        )";
        
        $pdo->exec($sql);
        
        // Create payment transactions table
        $sql = "
        CREATE TABLE IF NOT EXISTS bkash_transactions (
            id INT AUTO_INCREMENT PRIMARY KEY,
            merchant_invoice_number VARCHAR(100) NOT NULL,
            transaction_id VARCHAR(100),
            amount DECIMAL(10,2) NOT NULL,
            status VARCHAR(50),
            student_id VARCHAR(50),
            response_data TEXT,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
            updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            
            INDEX idx_transaction_id (transaction_id),
            INDEX idx_merchant_invoice (merchant_invoice_number),
            INDEX idx_student_id (student_id),
            INDEX idx_status (status)
        )";
        
        $pdo->exec($sql);
        
        return true;
    } catch (Exception $e) {
        error_log("Error creating bKash tables: " . $e->getMessage());
        return false;
    }
}
?>