<?php
/**
 * ZATCA Invoice Processor - FINAL WORKING VERSION
 * Properly handles API response parsing
 */

error_reporting(E_ALL);
ini_set('display_errors', 1);

require_once __DIR__ . '/chilkat/chilkat.php';
require_once 'config.php';
require_once 'ubl_generator.php';
require_once 'signer.php';
require_once 'qr_generator.php';
require_once 'api_client.php';

class ZATCAInvoiceProcessor {
    private $config;
    private $ublGenerator;
    private $signer;
    private $qrGenerator;
    private $apiClient;
    
    public function __construct() {
        $this->config = require 'config.php';
        $this->ublGenerator = new UBLGenerator($this->config);
        $this->signer = new ZATCASigner($this->config);
        $this->qrGenerator = new ZATCAQRGenerator($this->config);
        $this->apiClient = new ZATCAAPIClient($this->config);
    }
    
    /**
     * Process complete invoice workflow
     */
    public function processInvoice($invoiceData) {
        try {
            $invoiceNumber = $invoiceData['invoice_number'];
            
            // Step 1: Generate UUID
            $uuid = $this->generateUUID();
            $invoiceData['uuid'] = $uuid;
            
            // Step 2: Get PIH (Previous Invoice Hash)
            $pih = $this->getPreviousInvoiceHash($invoiceData);
            $invoiceData['pih'] = $pih;
            
            echo "=== ZATCA Invoice Processing ===\n";
            echo "Invoice Number: $invoiceNumber\n";
            echo "UUID: $uuid\n";
            echo "PIH: $pih\n\n";
            
            // Step 3: Generate base UBL XML
            echo "Step 1: Generating base UBL XML...\n";
            $baseXml = $this->ublGenerator->generateUBL($invoiceData);
            
            // Step 4: Sign the XML
            echo "Step 2: Signing XML...\n";
            $signResult = $this->signer->signXML($baseXml);
            $signedXml = $signResult['signed_xml'];
            
            // Step 5: Extract invoice hash from signature
            echo "Step 3: Extracting invoice hash from signature...\n";
            $invoiceHash = $this->signer->extractDigestValue($signedXml);
            echo "Invoice Hash (DigestValue): $invoiceHash\n";
            
            // Step 6: Extract signature value for QR
            $signatureValue = $this->signer->extractSignatureValue($signedXml);
            
            // Step 7: Generate QR code
            echo "Step 4: Generating QR code...\n";
            $qrCode = $this->qrGenerator->generateQR($invoiceData, $invoiceHash, $signatureValue);
            
            // Step 8: Insert QR into signed XML
            echo "Step 5: Adding QR code to XML...\n";
            $finalXml = $this->insertQRIntoXML($signedXml, $qrCode);
            
            // Step 9: Save files
            echo "Step 6: Saving files...\n";
            $folder = $this->saveInvoiceFiles($invoiceNumber, [
                'base_xml' => $baseXml,
                'signed_xml' => $signedXml,
                'final_xml' => $finalXml,
                'invoice_hash' => $invoiceHash,
                'qr_code' => $qrCode,
                'uuid' => $uuid,
                'pih' => $pih
            ]);
            
            // Step 10: Report to ZATCA
            echo "Step 7: Reporting to ZATCA...\n";
            
            try {
                $result = $this->apiClient->reportInvoice($finalXml, $invoiceHash, $uuid);
                
                // FIXED: Check if result is valid before accessing
                if (!is_array($result)) {
                    throw new Exception("Invalid API response format");
                }
                
                // Step 11: Handle response
                $success = isset($result['success']) ? $result['success'] : false;
                $httpCode = isset($result['http_code']) ? $result['http_code'] : 0;
                $status = isset($result['status']) ? $result['status'] : 'UNKNOWN';
                $reportingStatus = isset($result['reporting_status']) ? $result['reporting_status'] : 'NOT_REPORTED';
                
                if ($success) {
                    echo "\n✅ SUCCESS: Invoice reported successfully!\n";
                    echo "Reporting Status: {$reportingStatus}\n";
                    echo "HTTP Code: {$httpCode}\n";
                    
                    // Display warnings if any
                    if (!empty($result['warnings']) && is_array($result['warnings'])) {
                        echo "\n⚠️ Warnings:\n";
                        foreach ($result['warnings'] as $warning) {
                            if (is_array($warning)) {
                                $code = $warning['code'] ?? 'N/A';
                                $message = $warning['message'] ?? 'No message';
                                echo "   [$code] $message\n";
                            }
                        }
                    }
                    
                    // Save hash for next invoice (as PIH)
                    $this->saveLastInvoiceHash($invoiceHash);
                    
                    return [
                        'success' => true,
                        'invoice_number' => $invoiceNumber,
                        'uuid' => $uuid,
                        'hash' => $invoiceHash,
                        'folder' => $folder,
                        'result' => $result
                    ];
                    
                } else {
                    echo "\n❌ ERROR: Invoice reporting failed!\n";
                    echo "HTTP Code: {$httpCode}\n";
                    echo "Status: {$status}\n";
                    
                    // Display errors if any
                    if (!empty($result['errors']) && is_array($result['errors'])) {
                        echo "\nErrors:\n";
                        foreach ($result['errors'] as $error) {
                            if (is_array($error)) {
                                $code = $error['code'] ?? 'N/A';
                                $message = $error['message'] ?? 'No message';
                                echo "   [$code] $message\n";
                            }
                        }
                    }
                    
                    return [
                        'success' => false,
                        'invoice_number' => $invoiceNumber,
                        'uuid' => $uuid,
                        'hash' => $invoiceHash,
                        'folder' => $folder,
                        'result' => $result
                    ];
                }
                
            } catch (Exception $e) {
                
            }
            
        } catch (Exception $e) {
            
        }
    }
    
    /**
     * Insert QR code into signed XML without breaking signature
     */
    private function insertQRIntoXML($signedXml, $qrCode) {
        // Create QR document reference XML
        $qrXml = '<cac:AdditionalDocumentReference>' .
                 '<cbc:ID>QR</cbc:ID>' .
                 '<cac:Attachment>' .
                 '<cbc:EmbeddedDocumentBinaryObject mimeCode="text/plain">' . $qrCode . '</cbc:EmbeddedDocumentBinaryObject>' .
                 '</cac:Attachment>' .
                 '</cac:AdditionalDocumentReference>';
        
        // Insert before <cac:Signature>
        $finalXml = str_replace('<cac:Signature>', $qrXml . '<cac:Signature>', $signedXml);
        
        return $finalXml;
    }
    
    /**
     * Generate UUID v4
     */
    private function generateUUID() {
        $data = openssl_random_pseudo_bytes(16);
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
    }
    
    /**
     * Get previous invoice hash (PIH)
     */
    private function getPreviousInvoiceHash($invoiceData) {
        $hashFile = __DIR__ . '/data/last_invoice_hash.txt';
        
        if (file_exists($hashFile)) {
            return trim(file_get_contents($hashFile));
        }
        
        // Use default from config
        return isset($this->config['pih_default']) ? 
               $this->config['pih_default'] : 
               'NWZlY2ViNjZmZmM4NmYzOGQ5NTI3ODZjNmQ2OTZjNzljMmRiYzIzOWRkNGU5MWI0NjcyOWQ3M2EyN2ZiNTdlOQ==';
    }
    
    /**
     * Save last invoice hash for next invoice
     */
    private function saveLastInvoiceHash($hash) {
        $dataDir = __DIR__ . '/data';
        if (!is_dir($dataDir)) {
            mkdir($dataDir, 0777, true);
        }
        
        file_put_contents($dataDir . '/last_invoice_hash.txt', $hash);
    }
    
    /**
     * Save invoice files
     */
    private function saveInvoiceFiles($invoiceNumber, $files) {
        $folder = __DIR__ . "/invoices/$invoiceNumber";
        
        if (!is_dir($folder)) {
            mkdir($folder, 0777, true);
        }
        
        file_put_contents("$folder/1_base.xml", $files['base_xml']);
        file_put_contents("$folder/2_signed.xml", $files['signed_xml']);
        file_put_contents("$folder/3_final.xml", $files['final_xml']);
        file_put_contents("$folder/hash.txt", $files['invoice_hash']);
        file_put_contents("$folder/qr_code.txt", $files['qr_code']);
        file_put_contents("$folder/uuid.txt", $files['uuid']);
        file_put_contents("$folder/pih.txt", $files['pih']);
        
        return $folder;
    }
}
?>