<?php
/**
 * ZATCA QR Code Generator - FIXED VERSION
 * Generates TLV-encoded QR with proper signature handling
 */

require_once __DIR__ . '/chilkat/chilkat.php';
class ZATCAQRGenerator {
    private $config;
    private $cert;
    
    public function __construct($config) {
        $this->config = $config;
        $this->loadCertificate();
    }
    
    private function loadCertificate() {
        $this->cert = new CkCert();
        if (!$this->cert->LoadFromFile($this->config['certificate_path'])) {
            throw new Exception('Failed to load certificate for QR');
        }
    }
    
    /**
     * Generate QR code TLV
     * Uses the invoice hash (DigestValue) directly as base64 string
     */
    public function generateQR($invoiceData, $invoiceHash, $signatureValue) {
        $bdTlv = new CkBinData();
        
        // Tag 1: Seller Name
        $bdTlv->AppendByte(1);
        $bdTlv->AppendCountedString(1, false, $invoiceData['supplier']['name'], 'utf-8');
        
        // Tag 2: VAT Number
        $bdTlv->AppendByte(2);
        $bdTlv->AppendCountedString(1, false, $invoiceData['supplier']['vat_number'], 'utf-8');
        
        // Tag 3: Timestamp (ISO 8601 format with 'Z')
        $datetime = new DateTime($invoiceData['issue_date']);
        $timestamp = $datetime->format('Y-m-d\TH:i:s\Z');
        
        $bdTlv->AppendByte(3);
        $bdTlv->AppendCountedString(1, false, $timestamp, 'utf-8');
        
        // Tag 4: Invoice Total (with VAT)
        $bdTlv->AppendByte(4);
        $bdTlv->AppendCountedString(1, false, 
            number_format($invoiceData['totals']['grand_total'], 2, '.', ''), 'utf-8');
        
        // Tag 5: VAT Total
        $bdTlv->AppendByte(5);
        $bdTlv->AppendCountedString(1, false, 
            number_format($invoiceData['totals']['vat_total'], 2, '.', ''), 'utf-8');
        
        // Tag 6: Invoice Hash (DigestValue as base64 string)
        // CRITICAL: Use the hash as-is (base64 string), not as binary
        $bdTlv->AppendByte(6);
        $bdTlv->AppendCountedString(1, false, $invoiceHash, 'utf-8');
        
        // Tag 7: Digital Signature (SignatureValue as base64 string)
        // CRITICAL: Use the signature as-is (base64 string), not as binary
        $bdTlv->AppendByte(7);
        $bdTlv->AppendCountedString(1, false, $signatureValue, 'utf-8');
        
        // Tag 8: Public Key (certificate public key in DER format)
        $bdPubKey = new CkBinData();
        if (!$this->cert->GetPubKeyDer(true, $bdPubKey)) {
            throw new Exception('Failed to get public key');
        }
        
        $bdTlv->AppendByte(8);
        $bdTlv->AppendByte($bdPubKey->get_NumBytes());
        $bdTlv->AppendBd($bdPubKey);
        
        // Tag 9: Certificate Signature
        $bdCertSig = new CkBinData();
        if (!$this->cert->GetSignature($bdCertSig)) {
            throw new Exception('Failed to get certificate signature');
        }
        
        $bdTlv->AppendByte(9);
        $bdTlv->AppendByte($bdCertSig->get_NumBytes());
        $bdTlv->AppendBd($bdCertSig);
        
        // Return TLV as base64
        return $bdTlv->getEncoded('base64');
    }
}
?>