<?php
/**
 * Government Invoice API
 * فوترة بلس - POS System
 * 
 * Sends invoices to the government tax authority API
 * Enhanced with detailed logging and error handling
 */

// CRITICAL: Disable error display to prevent JSON corruption
ini_set('display_errors', 0);
error_reporting(E_ALL);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/government-invoice-errors.log');

require_once 'db.php';
require_once 'auth.php';

// Check if CURL is available
if (!function_exists('curl_init')) {
    error_log("CRITICAL: CURL extension is not installed on this server");
    jsonResponse(false, 'CURL extension is not installed on this server. Please contact your hosting provider.', [
        'error_code' => 'CURL_NOT_INSTALLED'
    ], 500);
}

// Check request method
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    jsonResponse(false, 'Method not allowed', null, 405);
}

$input = getJsonInput();

// Log incoming request
error_log("=== Government Invoice Request Started ===");
error_log("Request Time: " . date('Y-m-d H:i:s'));
error_log("Input Keys: " . implode(', ', array_keys($input)));

// Validate required fields
$requiredFields = ['xml_base64', 'invoice_number', 'seller_id'];
$missingFields = [];
foreach ($requiredFields as $field) {
    if (empty($input[$field])) {
        $missingFields[] = $field;
    }
}

if (!empty($missingFields)) {
    error_log("Missing required fields: " . implode(', ', $missingFields));
    jsonResponse(false, "Missing required fields: " . implode(', ', $missingFields), [
        'error_code' => 'MISSING_FIELDS',
        'missing_fields' => $missingFields
    ], 400);
}

$xmlBase64 = $input['xml_base64'];
$invoiceNumber = $input['invoice_number'];
$sellerId = $input['seller_id'];

error_log("Invoice Number: $invoiceNumber");
error_log("Seller ID: $sellerId");
error_log("XML Base64 Length: " . strlen($xmlBase64));

try {
    // Get seller credentials
    $stmt = $pdo->prepare("SELECT * FROM sellers WHERE id = ? LIMIT 1");
    $stmt->execute([$sellerId]);
    $seller = $stmt->fetch();
    
    if (!$seller) {
        error_log("ERROR: Seller not found with ID: $sellerId");
        jsonResponse(false, 'Seller not found', [
            'error_code' => 'SELLER_NOT_FOUND',
            'seller_id' => $sellerId
        ], 404);
    }
    
    error_log("Seller Found: " . $seller['seller_name']);
    
    // Check if seller has API credentials
    $clientId = $seller['client_id'] ?? '';
    $secretKey = $seller['secret_key'] ?? '';
    
    error_log("Has Client ID: " . (!empty($clientId) ? 'Yes (' . substr($clientId, 0, 8) . '...)' : 'No'));
    error_log("Has Secret Key: " . (!empty($secretKey) ? 'Yes (' . substr($secretKey, 0, 8) . '...)' : 'No'));
    
    // Check for test/placeholder credentials
    $testPatterns = ['test', 'demo', 'sample', 'placeholder', 'xxx', '000', 'your-'];
    $isTestCredentials = false;
    foreach ($testPatterns as $pattern) {
        if (stripos($clientId, $pattern) !== false || stripos($secretKey, $pattern) !== false) {
            $isTestCredentials = true;
            break;
        }
    }
    
    // If no credentials or test credentials, return detailed error
    if (empty($clientId) || empty($secretKey)) {
        error_log("ERROR: Missing API credentials for seller");
        jsonResponse(false, 'بيانات الاعتماد الحكومية غير مكتملة. يرجى إدخال Client ID و Secret Key في إعدادات البائع.', [
            'error_code' => 'MISSING_CREDENTIALS',
            'has_client_id' => !empty($clientId),
            'has_secret_key' => !empty($secretKey),
            'seller_name' => $seller['seller_name']
        ], 400);
    }
    
    if ($isTestCredentials) {
        error_log("WARNING: Test/placeholder credentials detected");
        jsonResponse(false, 'بيانات الاعتماد الحكومية غير صالحة (تبدو كبيانات تجريبية). يرجى إدخال بيانات الاعتماد الحقيقية.', [
            'error_code' => 'TEST_CREDENTIALS',
            'message' => 'Credentials appear to be test/placeholder values'
        ], 400);
    }
    
    // Validate XML content
    $decodedXml = base64_decode($xmlBase64);
    if ($decodedXml === false) {
        error_log("ERROR: Invalid base64 encoding for XML");
        jsonResponse(false, 'XML encoding is invalid', [
            'error_code' => 'INVALID_XML_ENCODING'
        ], 400);
    }
    
    // Check for placeholder values in XML
    if (strpos($decodedXml, '{{') !== false || strpos($decodedXml, '}}') !== false) {
        error_log("ERROR: XML contains unreplaced template variables");
        jsonResponse(false, 'XML contains unreplaced template variables. Please check invoice data.', [
            'error_code' => 'TEMPLATE_VARIABLES_FOUND'
        ], 400);
    }
    
    error_log("XML validation passed");
    
    // Real API call to government system
    $apiUrl = 'https://backend.jofotara.gov.jo/core/invoices/';
    
    $requestData = [
        'invoice' => $xmlBase64
    ];
    
    error_log("=== Sending to Government API ===");
    error_log("API URL: $apiUrl");
    
    $ch = curl_init($apiUrl);
    
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($requestData),
        CURLOPT_HTTPHEADER => [
            'Content-Type: application/json',
            'Accept: application/json',
            'Accept-Encoding: gzip, deflate',  // Removed 'br' (Brotli) - PHP may not handle it
            'Connection: keep-alive',
            'Client-Id: ' . $clientId,
            'Secret-Key: ' . $secretKey
        ],
        CURLOPT_TIMEOUT => 60,
        CURLOPT_CONNECTTIMEOUT => 30,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_ENCODING => '',  // Auto-decompress gzip, deflate responses
        CURLOPT_VERBOSE => true
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    $curlErrno = curl_errno($ch);
    $curlInfo = curl_getinfo($ch);
    curl_close($ch);
    
    error_log("=== Government API Response ===");
    error_log("HTTP Code: $httpCode");
    error_log("CURL Error Number: $curlErrno");
    error_log("CURL Error: $curlError");
    error_log("Total Time: " . $curlInfo['total_time'] . " seconds");
    error_log("Response Length: " . strlen($response));
    error_log("Response (first 1000 chars): " . substr($response, 0, 1000));
    
    // Manual gzip decompression fallback
    // Check if response is gzip compressed (starts with gzip magic bytes 0x1f 0x8b)
    if (!empty($response) && strlen($response) > 2) {
        $firstByte = ord($response[0]);
        $secondByte = ord($response[1]);
        
        // Check for gzip magic bytes
        if ($firstByte === 0x1f && $secondByte === 0x8b) {
            error_log("Response appears gzip compressed (magic bytes detected) - attempting decompression");
            $decompressed = @gzdecode($response);
            if ($decompressed !== false) {
                error_log("Successfully decompressed gzip response");
                $response = $decompressed;
            } else {
                error_log("gzdecode failed, trying gzinflate");
                $decompressed = @gzinflate(substr($response, 10, -8)); // Skip gzip header/footer
                if ($decompressed !== false) {
                    error_log("Successfully decompressed using gzinflate");
                    $response = $decompressed;
                }
            }
        }
        // Check if response starts with 'H' or other non-JSON characters (possible compressed data)
        elseif (json_decode($response) === null && !in_array($response[0], ['{', '[', '"'])) {
            error_log("Response is not valid JSON and doesn't start with JSON characters - trying decompression");
            
            // Try gzdecode first
            $decompressed = @gzdecode($response);
            if ($decompressed !== false && json_decode($decompressed) !== null) {
                error_log("Successfully decompressed using gzdecode fallback");
                $response = $decompressed;
            } else {
                // Try gzinflate
                $decompressed = @gzinflate($response);
                if ($decompressed !== false && json_decode($decompressed) !== null) {
                    error_log("Successfully decompressed using gzinflate fallback");
                    $response = $decompressed;
                } else {
                    // Try zlib inflate
                    $decompressed = @gzuncompress($response);
                    if ($decompressed !== false && json_decode($decompressed) !== null) {
                        error_log("Successfully decompressed using gzuncompress fallback");
                        $response = $decompressed;
                    }
                }
            }
        }
    }
    
    error_log("Final Response Length after decompression: " . strlen($response));
    error_log("Final Response (first 500 chars): " . substr($response, 0, 500));
    
    if ($curlError) {
        error_log("CURL ERROR: ($curlErrno) $curlError");
        
        $errorMessage = 'خطأ في الاتصال بالخادم الحكومي: ';
        switch ($curlErrno) {
            case CURLE_COULDNT_CONNECT:
                $errorMessage .= 'لا يمكن الاتصال بالخادم';
                break;
            case CURLE_OPERATION_TIMEDOUT:
                $errorMessage .= 'انتهت مهلة الاتصال';
                break;
            case CURLE_SSL_CONNECT_ERROR:
                $errorMessage .= 'خطأ في شهادة SSL';
                break;
            default:
                $errorMessage .= $curlError;
        }
        
        jsonResponse(false, $errorMessage, [
            'error_code' => 'CURL_ERROR',
            'curl_errno' => $curlErrno,
            'curl_error' => $curlError,
            'total_time' => $curlInfo['total_time']
        ], 500);
    }
    
    // Check for HTTP 403 Forbidden (invalid credentials)
    if ($httpCode === 403) {
        error_log("ERROR: HTTP 403 Forbidden - Invalid credentials");
        jsonResponse(false, 'بيانات الاعتماد الحكومية غير صحيحة (Client ID أو Secret Key)', [
            'error_code' => 'INVALID_CREDENTIALS',
            'http_code' => 403,
            'message' => 'HTTP 403 Forbidden - Government API rejected credentials'
        ], 403);
    }
    
    // Check for HTTP 401 Unauthorized
    if ($httpCode === 401) {
        error_log("ERROR: HTTP 401 Unauthorized - Authentication failed");
        jsonResponse(false, 'فشل التحقق من بيانات الاعتماد الحكومية', [
            'error_code' => 'UNAUTHORIZED',
            'http_code' => 401,
            'message' => 'HTTP 401 Unauthorized - Authentication failed'
        ], 401);
    }
    
    // Check for HTTP 500 Internal Server Error
    if ($httpCode === 500) {
        error_log("ERROR: HTTP 500 Internal Server Error from Government API");
        error_log("Response content: " . substr($response, 0, 1000));
        
        // Try to parse any error message from response
        $errorDetails = '';
        $parsedResponse = json_decode($response, true);
        if ($parsedResponse && isset($parsedResponse['message'])) {
            $errorDetails = $parsedResponse['message'];
        } elseif ($parsedResponse && isset($parsedResponse['error'])) {
            $errorDetails = $parsedResponse['error'];
        }
        
        jsonResponse(false, 'خطأ داخلي في الخادم الحكومي (500). ' . ($errorDetails ?: 'قد يكون بسبب بيانات اعتماد غير صالحة أو مشكلة في بيانات الفاتورة.'), [
            'error_code' => 'GOVERNMENT_SERVER_ERROR',
            'http_code' => 500,
            'message' => 'الخادم الحكومي واجه خطأ داخلي. تحقق من بيانات الاعتماد وصيغة XML.',
            'raw_response' => substr($response, 0, 500),
            'error_details' => $errorDetails
        ], 500);
    }
    
    $responseData = json_decode($response, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        error_log("ERROR: Invalid JSON response from government API");
        error_log("JSON Error: " . json_last_error_msg());
        error_log("Raw response: " . $response);
        
        // Check if it's an HTML error page
        $isHtml = strpos($response, '<!DOCTYPE') !== false || strpos($response, '<html') !== false;
        
        if ($isHtml) {
            error_log("Response is HTML error page, not JSON");
            $errorMessage = 'الخادم الحكومي أرجع صفحة خطأ HTML - تحقق من بيانات الاعتماد أو حالة الخادم';
        } else {
            $errorMessage = 'استجابة غير صالحة من الخادم الحكومي';
        }
        
        jsonResponse(false, $errorMessage, [
            'error_code' => 'INVALID_JSON_RESPONSE',
            'http_code' => $httpCode,
            'is_html' => $isHtml,
            'json_error' => json_last_error_msg(),
            'raw_response' => substr($response, 0, 500)
        ], 500);
    }
    
    error_log("Parsed Response: " . json_encode($responseData));
    
    if ($httpCode === 200 || $httpCode === 201) {
        // Success - extract data from government API response
        // Government API returns: EINV_QR, EINV_INV_UUID, EINV_STATUS, EINV_SINGED_INVOICE, EINV_RESULTS
        $qrCode = $responseData['EINV_QR'] ?? $responseData['qrCode'] ?? $responseData['QRCode'] ?? '';
        $uuid = $responseData['EINV_INV_UUID'] ?? $responseData['uuid'] ?? $responseData['UUID'] ?? generateUUID();
        $signedInvoice = $responseData['EINV_SINGED_INVOICE'] ?? '';
        $invoiceStatus = $responseData['EINV_STATUS'] ?? 'SUBMITTED';
        $invoiceNumber_gov = $responseData['EINV_NUM'] ?? $invoiceNumber;
        
        // Check EINV_RESULTS for validation status
        $validationStatus = 'PASS';
        $validationErrors = [];
        if (isset($responseData['EINV_RESULTS'])) {
            $validationStatus = $responseData['EINV_RESULTS']['status'] ?? 'UNKNOWN';
            if (isset($responseData['EINV_RESULTS']['ERRORS']) && !empty($responseData['EINV_RESULTS']['ERRORS'])) {
                $validationErrors = $responseData['EINV_RESULTS']['ERRORS'];
            }
        }
        
        error_log("SUCCESS: Invoice sent successfully");
        error_log("EINV_STATUS: $invoiceStatus");
        error_log("EINV_QR Length: " . strlen($qrCode));
        error_log("EINV_INV_UUID: $uuid");
        error_log("EINV_NUM: $invoiceNumber_gov");
        error_log("Validation Status: $validationStatus");
        error_log("Has Signed Invoice: " . (!empty($signedInvoice) ? 'Yes' : 'No'));
        
        // Determine status message based on EINV_STATUS
        $statusMessage = 'مرسلة';
        $successMessage = 'تم إرسال الفاتورة بنجاح';
        if ($invoiceStatus === 'ALREADY_SUBMITTED') {
            $successMessage = 'الفاتورة مرسلة مسبقاً';
        }
        
        $stmt = $pdo->prepare("
            UPDATE invoices 
            SET qr_code = ?, 
                status = ?,
                sent_at = ?,
                api_response = ?,
                updated_at = ?
            WHERE invoice_number = ? AND seller_id = ?
        ");
        $stmt->execute([
            $qrCode,
            $statusMessage,
            getCurrentTimestamp(),
            json_encode($responseData),
            getCurrentTimestamp(),
            $invoiceNumber,
            $sellerId
        ]);
        
        $rowsAffected = $stmt->rowCount();
        error_log("Database updated. Rows affected: $rowsAffected");
        
        jsonResponse(true, $successMessage, [
            'success' => true,
            'invoice_number' => $invoiceNumber,
            'qr_code' => $qrCode,
            'uuid' => $uuid,
            'einv_status' => $invoiceStatus,
            'validation_status' => $validationStatus,
            'api_response' => $responseData
        ]);
    } else {
        // Error from government API
        error_log("ERROR: Government API returned error");
        error_log("HTTP Code: $httpCode");
        error_log("Response: " . json_encode($responseData));
        
        // Extract error message from response
        $errorMessage = 'خطأ من الخادم الحكومي';
        if (isset($responseData['message'])) {
            $errorMessage = $responseData['message'];
        } elseif (isset($responseData['error'])) {
            $errorMessage = $responseData['error'];
        } elseif (isset($responseData['errors']) && is_array($responseData['errors'])) {
            $errorMessage = implode(', ', $responseData['errors']);
        }
        
        jsonResponse(false, $errorMessage, [
            'error_code' => 'GOVERNMENT_API_ERROR',
            'http_code' => $httpCode,
            'response' => $responseData
        ], 400);
    }
    
} catch (PDOException $e) {
    error_log("DATABASE ERROR: " . $e->getMessage());
    jsonResponse(false, 'خطأ في قاعدة البيانات: ' . $e->getMessage(), [
        'error_code' => 'DATABASE_ERROR'
    ], 500);
} catch (Exception $e) {
    error_log("GENERAL ERROR: " . $e->getMessage());
    error_log("Stack Trace: " . $e->getTraceAsString());
    jsonResponse(false, 'خطأ في معالجة الفاتورة: ' . $e->getMessage(), [
        'error_code' => 'GENERAL_ERROR',
        'exception' => $e->getMessage()
    ], 500);
}
?>
