<?php
/**
 * eTIMS Integration Helper Class - CORRECTED VERSION
 * Based on actual Postman collection endpoints
 * File: includes/EtimsIntegration.php
 */

class EtimsIntegration {
    private $conn;
    private $base_url;
    private $api_key;
    private $business_pin;
    private $branch_id;
    private $environment;
    private $enabled;
    private $mock_mode;
    
    /**
     * Constructor - Initialize eTIMS with database connection
     */
    public function __construct($conn) {
        $this->conn = $conn;
        $this->loadSettings();
    }
    
    /**
     * Load eTIMS settings from database
     */
    private function loadSettings() {
        $sql = "SELECT setting_key, setting_value FROM system_settings WHERE category = 'etims'";
        $result = $this->conn->query($sql);
        
        $settings = [];
        while ($row = $result->fetch_assoc()) {
            $settings[$row['setting_key']] = $row['setting_value'];
        }
        
        $this->enabled = ($settings['etims_enabled'] ?? '0') === '1';
        $this->mock_mode = ($settings['etims_mock_mode'] ?? '0') === '1';
        $this->environment = $settings['etims_environment'] ?? 'sandbox';
        $this->api_key = $settings['etims_api_key'] ?? '';
        $this->business_pin = $settings['etims_tin'] ?? 'P052077586R';
        $this->branch_id = $settings['etims_branch_code'] ?? '00';
        
        // Set base URL based on environment
        if ($this->environment === 'sandbox') {
            $this->base_url = 'http://62.169.23.132:4122';
            // Override with sandbox credentials if empty
            if (empty($this->api_key)) {
                $this->api_key = 'etims-fc-2025-secure-api-key-9ffhksorghjlys';
            }
            if (empty($this->business_pin)) {
                $this->business_pin = 'P052077586R';
            }
        } else {
            $this->base_url = 'https://etims.kra.go.ke'; // Update with production URL
        }
    }
    
    /**
     * Check if eTIMS is enabled
     */
    public function isEnabled() {
        return $this->enabled;
    }
    
    /**
     * Check if mock mode is enabled
     */
    public function isMockMode() {
        return $this->mock_mode;
    }
    
    /**
     * Make API request to eTIMS
     */
    private function makeRequest($endpoint, $data = []) {
        // Check mock mode first
        if ($this->mock_mode) {
            return $this->getMockResponse($endpoint, $data);
        }
        
        if (!$this->enabled) {
            return [
                'success' => false,
                'message' => 'eTIMS integration is not enabled'
            ];
        }
        
        $url = $this->base_url . $endpoint;
        
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($data),
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'X-API-Key: ' . $this->api_key  // CORRECTED: Use X-API-Key header
            ],
            CURLOPT_TIMEOUT => 30,
            CURLOPT_SSL_VERIFYPEER => ($this->environment === 'production'),
            CURLOPT_SSL_VERIFYHOST => ($this->environment === 'production') ? 2 : 0
        ]);
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curl_error = curl_error($ch);
        curl_close($ch);
        
        // Log API request
        $this->logApiRequest($endpoint, $data, $response, $http_code);
        
        if ($curl_error) {
            return [
                'success' => false,
                'message' => 'Connection error: ' . $curl_error
            ];
        }
        
        if ($http_code !== 200) {
            return [
                'success' => false,
                'message' => 'HTTP Error ' . $http_code,
                'http_code' => $http_code
            ];
        }
        
        $result = json_decode($response, true);
        
        if ($result === null) {
            return [
                'success' => false,
                'message' => 'Invalid JSON response'
            ];
        }
        
        return [
            'success' => isset($result['success']) ? $result['success'] : true,
            'message' => $result['message'] ?? 'Success',
            'data' => $result
        ];
    }
    
    /**
     * Check API Health
     */
    public function checkHealth() {
        if ($this->mock_mode) {
            return [
                'success' => true,
                'message' => 'Health check passed (MOCK MODE)',
                'data' => ['status' => 'healthy']
            ];
        }
        
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $this->base_url . '/health',
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_SSL_VERIFYPEER => false
        ]);
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        if ($error || $http_code !== 200) {
            return [
                'success' => false,
                'message' => $error ?: 'Health check failed',
                'http_code' => $http_code
            ];
        }
        
        return [
            'success' => true,
            'message' => 'Health check passed',
            'data' => json_decode($response, true)
        ];
    }
    
    /**
     * Register Items (Services/Products)
     */
    public function registerItems($items) {
        $data = [
            'businessPin' => $this->business_pin,
            'branchId' => $this->branch_id,
            'Items' => count($items),
            'ItemsList' => []
        ];
        
        foreach ($items as $item) {
            $data['ItemsList'][] = [
                'itemName' => $item['item_name'],
                'ClassCode' => $item['class_code'] ?? '50101502',
                'itemCd' => $item['item_code'],
                'ItemType' => $item['item_type'] ?? '2', // 1=Goods, 2=Service
                'UnitOfQuantity' => $item['unit_quantity'] ?? 'U',
                'PackagingUnit' => $item['packaging_unit'] ?? 'NT',
                'SellingPrice' => floatval($item['price']),
                'TaxationType' => $item['tax_type'] ?? 'B',
                'OpeningStock' => intval($item['opening_stock'] ?? 0)
            ];
        }
        
        return $this->makeRequest('/api/items/register-json', $data);
    }
    
    /**
     * Submit Sales Invoice
     */
    public function submitInvoice($invoice_data) {
        $data = [
            'businessPin' => $this->business_pin,
            'branchId' => $this->branch_id,
            'invoiceNumber' => intval($invoice_data['invoice_number']),
            'traderInvoiceNo' => $invoice_data['trader_invoice_no'] ?? $invoice_data['invoice_number'],
            'customer' => [
                'name' => $invoice_data['customer_name'],
                'pin' => $invoice_data['customer_pin'] ?? '',
                'mobile' => $invoice_data['customer_mobile'] ?? '',
                'address' => $invoice_data['customer_address'] ?? ''
            ],
            'items' => [],
            'paymentInfo' => [
                'amountPaid' => floatval($invoice_data['amount_paid']),
                'changeGiven' => floatval($invoice_data['change_given'] ?? 0),
                'paymentModes' => $invoice_data['payment_modes'] ?? [
                    [
                        'mode' => 'Cash',
                        'amount' => floatval($invoice_data['amount_paid'])
                    ]
                ]
            ],
            'remark' => $invoice_data['remark'] ?? 'Tax Invoice'
        ];
        
        // Add items
        foreach ($invoice_data['items'] as $item) {
            $data['items'][] = [
                'itemCode' => $item['item_code'],
                'itemClassCode' => $item['item_class_code'] ?? '50101502',
                'itemName' => $item['item_name'],
                'quantity' => floatval($item['quantity']),
                'price' => floatval($item['unit_price']),
                'taxType' => $item['tax_type'] ?? 'B'
            ];
        }
        
        return $this->makeRequest('/api/invoice/process', $data);
    }
    
    /**
     * Submit Credit Note
     */
    public function submitCreditNote($credit_note_data) {
        $data = [
            'businessPin' => $this->business_pin,
            'branchId' => $this->branch_id,
            'originalInvoiceNumber' => intval($credit_note_data['original_invoice_number']),
            'creditNoteNumber' => intval($credit_note_data['credit_note_number']),
            'traderInvoiceNo' => $credit_note_data['trader_invoice_no'] ?? 'CN-' . $credit_note_data['credit_note_number'],
            'customer' => [
                'name' => $credit_note_data['customer_name'],
                'pin' => $credit_note_data['customer_pin'] ?? '',
                'mobile' => $credit_note_data['customer_mobile'] ?? '',
                'address' => $credit_note_data['customer_address'] ?? ''
            ],
            'items' => [],
            'reason' => $credit_note_data['reason'] ?? 'Refund'
        ];
        
        // Add items
        foreach ($credit_note_data['items'] as $item) {
            $data['items'][] = [
                'itemCode' => $item['item_code'],
                'itemClassCode' => $item['item_class_code'] ?? '50101502',
                'itemName' => $item['item_name'],
                'quantity' => floatval($item['quantity']),
                'price' => floatval($item['unit_price']),
                'taxType' => $item['tax_type'] ?? 'B'
            ];
        }
        
        return $this->makeRequest('/api/credit-note/process', $data);
    }
    
    /**
     * Get mock response for development
     */
    private function getMockResponse($endpoint, $data) {
        switch ($endpoint) {
            case '/health':
                return [
                    'success' => true,
                    'message' => 'Health check passed (MOCK MODE)',
                    'data' => ['status' => 'healthy', 'timestamp' => date('c')]
                ];
                
            case '/api/items/register-json':
                $registered_items = [];
                foreach ($data['ItemsList'] ?? [] as $item) {
                    $registered_items[] = [
                        'itemCode' => $item['itemCd'],
                        'itemName' => $item['itemName'],
                        'status' => 'registered'
                    ];
                }
                return [
                    'success' => true,
                    'message' => count($registered_items) . ' items registered successfully (MOCK MODE)',
                    'data' => [
                        'registeredItems' => $registered_items,
                        'timestamp' => date('c')
                    ]
                ];
                
            case '/api/invoice/process':
                $receipt_signature = strtoupper(bin2hex(random_bytes(32)));
                $cu_serial = 'CU-' . date('Ymd') . '-' . rand(10000, 99999);
                
                return [
                    'success' => true,
                    'message' => 'Invoice processed successfully (MOCK MODE)',
                    'data' => [
                        'invoiceNumber' => $data['invoiceNumber'],
                        'traderInvoiceNo' => $data['traderInvoiceNo'],
                        'cuSerial' => $cu_serial,
                        'receiptSignature' => $receipt_signature,
                        'receiptDate' => date('Y-m-d H:i:s'),
                        'qrCode' => 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==',
                        'totalAmount' => $data['paymentInfo']['amountPaid']
                    ]
                ];
                
            case '/api/credit-note/process':
                $receipt_signature = strtoupper(bin2hex(random_bytes(32)));
                
                return [
                    'success' => true,
                    'message' => 'Credit note processed successfully (MOCK MODE)',
                    'data' => [
                        'creditNoteNumber' => $data['creditNoteNumber'],
                        'originalInvoiceNumber' => $data['originalInvoiceNumber'],
                        'receiptSignature' => $receipt_signature,
                        'receiptDate' => date('Y-m-d H:i:s')
                    ]
                ];
                
            default:
                return [
                    'success' => true,
                    'message' => 'Mock response (MOCK MODE)',
                    'data' => []
                ];
        }
    }
    
    /**
     * Log API request to database
     */
    private function logApiRequest($endpoint, $request_data, $response, $http_code) {
        $sql = "INSERT INTO etims_api_log (
            endpoint, 
            request_data, 
            response_data, 
            http_code,
            success,
            created_at
        ) VALUES (?, ?, ?, ?, ?, NOW())";
        
        $stmt = $this->conn->prepare($sql);
        $request_json = json_encode($request_data);
        $response_json = substr($response, 0, 5000); // Limit response size
        $success = ($http_code == 200) ? 1 : 0;
        
        $stmt->bind_param("sssii", 
            $endpoint, 
            $request_json, 
            $response_json, 
            $http_code,
            $success
        );
        
        $stmt->execute();
        $stmt->close();
    }
    
    /**
     * Calculate tax amounts based on total amount
     */
    public static function calculateTax($total_amount, $tax_type = 'B') {
        $result = [
            'taxable_amount' => 0,
            'tax_amount' => 0,
            'total_amount' => $total_amount
        ];
        
        switch ($tax_type) {
            case 'A': // VAT 16%
                $result['taxable_amount'] = $total_amount / 1.16;
                $result['tax_amount'] = $result['taxable_amount'] * 0.16;
                break;
            case 'B': // VAT 8%
                $result['taxable_amount'] = $total_amount / 1.08;
                $result['tax_amount'] = $result['taxable_amount'] * 0.08;
                break;
            case 'C': // Exempt
            case 'D': // Zero-rated
                $result['taxable_amount'] = $total_amount;
                $result['tax_amount'] = 0;
                break;
        }
        
        return $result;
    }
}

/**
 * Example Usage:
 * 
 * // Initialize
 * require_once 'includes/EtimsIntegration.php';
 * $etims = new EtimsIntegration($conn);
 * 
 * // Check health
 * $health = $etims->checkHealth();
 * if ($health['success']) {
 *     echo "eTIMS is online!";
 * }
 * 
 * // Register a service
 * $items = [[
 *     'item_name' => 'ENT Consultation',
 *     'item_code' => 'ENT-000001',
 *     'class_code' => '50101502',
 *     'price' => 3000.00,
 *     'tax_type' => 'B'
 * ]];
 * $result = $etims->registerItems($items);
 * 
 * // Submit invoice
 * $invoice = [
 *     'invoice_number' => 5001,
 *     'trader_invoice_no' => 'INV-2025-001',
 *     'customer_name' => 'John Doe',
 *     'customer_pin' => 'A001234567X',
 *     'customer_mobile' => '254712345678',
 *     'amount_paid' => 3240,
 *     'items' => [[
 *         'item_code' => 'ENT-000001',
 *         'item_name' => 'ENT Consultation',
 *         'quantity' => 1,
 *         'unit_price' => 3240,
 *         'tax_type' => 'B'
 *     ]]
 * ];
 * $result = $etims->submitInvoice($invoice);
 */
?>