<?php
/**
 * Proforma Invoice PDF — ERP-grade professional layout (v3)
 */
require_once __DIR__ . '/config.php';
session_start();
if (empty($_SESSION['user_id'])) {
    http_response_code(401);
    header('Content-Type: text/plain');
    exit('Login required');
}
$id = (int)($_GET['id'] ?? 0);
if ($id <= 0) { http_response_code(400); exit('id required'); }

try {
    $pdo = new PDO(
        'mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4',
        DB_USER, DB_PASS,
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]
    );
} catch (Exception $e) {
    http_response_code(500);
    exit('DB error');
}

$stmt = $pdo->prepare("SELECT * FROM proforma_invoices WHERE id = ?");
$stmt->execute([$id]);
$inv = $stmt->fetch();
if (!$inv) { http_response_code(404); exit('Not found'); }

/* Refresh buyer fields from Client Master (latest data wins when available) */
try {
    $buyerName = trim((string)($inv['buyer_name'] ?? ''));
    $client = null;
    if ($buyerName !== '') {
        $cs = $pdo->prepare("SELECT * FROM clients WHERE LOWER(TRIM(name)) COLLATE utf8mb4_unicode_ci = LOWER(TRIM(?)) COLLATE utf8mb4_unicode_ci LIMIT 1");
        $cs->execute([$buyerName]);
        $client = $cs->fetch();
    }
    // Optional: client_id column on proforma
    if (!$client && !empty($inv['client_id'])) {
        $cs = $pdo->prepare("SELECT * FROM clients WHERE id = ? LIMIT 1");
        $cs->execute([(int)$inv['client_id']]);
        $client = $cs->fetch();
    }
    if ($client) {
        if (!empty($client['name'])) $inv['buyer_name'] = $client['name'];
        if (!empty($client['name_ar'])) $inv['buyer_name_ar'] = $client['name_ar'];
        if (!empty($client['cr_number'])) $inv['buyer_cr'] = $client['cr_number'];
        if (!empty($client['vat_number'])) $inv['buyer_vat'] = $client['vat_number'];
        $addrParts = array_filter([trim((string)($client['address'] ?? '')), trim((string)($client['city'] ?? ''))]);
        if ($addrParts) $inv['buyer_address'] = implode(', ', $addrParts);
        $contactParts = [];
        if (!empty($client['contact_person'])) $contactParts[] = $client['contact_person'];
        if (!empty($client['phone'])) $contactParts[] = $client['phone'];
        if ($contactParts) $inv['buyer_contact'] = implode(' · ', $contactParts);
        elseif (!empty($client['email']) && empty($inv['buyer_contact'])) $inv['buyer_contact'] = $client['email'];
    }
} catch (Throwable $e) { /* clients table may differ */ }

$items = $pdo->prepare("SELECT * FROM proforma_items WHERE invoice_id = ? ORDER BY sort_order ASC, id ASC");
$items->execute([$id]);
$lines = $items->fetchAll();
$sub = 0.0;
foreach ($lines as $L) $sub += (float)$L['amount'];
$vatRate = (float)($inv['vat_rate'] ?? 15);
$vatAmt = round($sub * $vatRate / 100, 2);

$grand = round($sub + $vatAmt, 2);

/* ===== TEMPLATE THEMES (ERP grade) ===== */
$tpl = strtolower(trim($inv['template'] ?? 'classic'));
if (!in_array($tpl, ['classic','executive','modern','corporate','elegant'], true)) $tpl = 'classic';
$themes = [
  'classic' => [
    'name' => 'Classic Navy',
    'navy' => [12, 24, 48], 'navy2' => [20, 35, 65], 'accent' => [0, 150, 170], 'accent2' => [0, 120, 140],
    'muted' => [90, 105, 125], 'line' => [220, 228, 236], 'soft' => [246, 249, 252], 'ink' => [20, 28, 40],
    'words_bg' => [232, 248, 250], 'buyer_hdr' => [0, 150, 170], 'seller_hdr' => [12, 24, 48],
  ],
  'executive' => [
    'name' => 'Executive Gold',
    'navy' => [28, 25, 23], 'navy2' => [41, 37, 36], 'accent' => [180, 140, 50], 'accent2' => [146, 110, 30],
    'muted' => [110, 100, 90], 'line' => [228, 220, 210], 'soft' => [250, 248, 244], 'ink' => [28, 25, 23],
    'words_bg' => [255, 250, 235], 'buyer_hdr' => [180, 140, 50], 'seller_hdr' => [28, 25, 23],
  ],
  'modern' => [
    'name' => 'Modern Minimal',
    'navy' => [15, 23, 42], 'navy2' => [30, 41, 59], 'accent' => [37, 99, 235], 'accent2' => [29, 78, 216],
    'muted' => [100, 116, 139], 'line' => [226, 232, 240], 'soft' => [248, 250, 252], 'ink' => [15, 23, 42],
    'words_bg' => [239, 246, 255], 'buyer_hdr' => [37, 99, 235], 'seller_hdr' => [15, 23, 42],
  ],
  'corporate' => [
    'name' => 'Corporate Green',
    'navy' => [6, 40, 30], 'navy2' => [10, 55, 42], 'accent' => [16, 145, 100], 'accent2' => [12, 120, 85],
    'muted' => [80, 100, 95], 'line' => [210, 228, 220], 'soft' => [240, 250, 245], 'ink' => [10, 35, 28],
    'words_bg' => [236, 253, 245], 'buyer_hdr' => [16, 145, 100], 'seller_hdr' => [6, 40, 30],
  ],
  'elegant' => [
    'name' => 'Elegant Indigo',
    'navy' => [30, 27, 75], 'navy2' => [49, 46, 129], 'accent' => [99, 102, 241], 'accent2' => [79, 70, 229],
    'muted' => [100, 100, 130], 'line' => [224, 224, 240], 'soft' => [245, 245, 255], 'ink' => [30, 27, 75],
    'words_bg' => [238, 242, 255], 'buyer_hdr' => [99, 102, 241], 'seller_hdr' => [30, 27, 75],
  ],
];
$th = $themes[$tpl];

class SimplePDF {
    private $pages = [];
    private $page = '';
    public $pageW = 595.28;
    public $pageH = 841.89;
    private $fontSize = 10;
    private $font = 'F1';
    private $images = [];

    public function __construct() { $this->addPage(); }
    public function addPage() {
        if ($this->page !== '') $this->pages[] = $this->page;
        $this->page = "1 1 1 rg\n0 0 0 RG\n0.5 w\n";
    }
    private function esc($s) {
        return str_replace([chr(92), '(', ')'], [chr(92).chr(92), chr(92).'(', chr(92).')'], (string)$s);
    }
    public function setFontSize($s) { $this->fontSize = $s; }
    public function setFont($bold = false) { $this->font = $bold ? 'F2' : 'F1'; }
    public function textWidth($str) {
        static $W = null;
        if ($W === null) {
            $W = array_fill(0, 256, 0.556);
            foreach ([
                32=>0.278,33=>0.278,34=>0.355,35=>0.556,36=>0.556,37=>0.889,38=>0.667,39=>0.191,
                40=>0.333,41=>0.333,42=>0.389,43=>0.584,44=>0.278,45=>0.333,46=>0.278,47=>0.278,
                48=>0.556,49=>0.556,50=>0.556,51=>0.556,52=>0.556,53=>0.556,54=>0.556,55=>0.556,
                56=>0.556,57=>0.556,58=>0.278,59=>0.278,60=>0.584,61=>0.584,62=>0.584,63=>0.556,
                64=>1.015,65=>0.667,66=>0.667,67=>0.722,68=>0.722,69=>0.667,70=>0.611,71=>0.778,
                72=>0.722,73=>0.278,74=>0.500,75=>0.667,76=>0.556,77=>0.833,78=>0.722,79=>0.778,
                80=>0.667,81=>0.778,82=>0.722,83=>0.667,84=>0.611,85=>0.722,86=>0.667,87=>0.944,
                88=>0.667,89=>0.667,90=>0.611,91=>0.278,92=>0.278,93=>0.278,94=>0.469,95=>0.556,
                96=>0.333,97=>0.556,98=>0.556,99=>0.500,100=>0.556,101=>0.556,102=>0.278,103=>0.556,
                104=>0.556,105=>0.222,106=>0.222,107=>0.500,108=>0.222,109=>0.833,110=>0.556,111=>0.556,
                112=>0.556,113=>0.556,114=>0.333,115=>0.500,116=>0.278,117=>0.556,118=>0.500,119=>0.722,
                120=>0.500,121=>0.500,122=>0.500,123=>0.334,124=>0.260,125=>0.334,126=>0.584,
            ] as $k=>$v) $W[$k] = $v;
        }
        $sum = 0.0;
        $s = (string)$str;
        for ($i = 0, $n = strlen($s); $i < $n; $i++) $sum += $W[ord($s[$i])] ?? 0.556;
        if ($this->font === 'F2') $sum *= 1.04;
        return $sum * $this->fontSize;
    }
    public function text($x, $y, $str) {
        $this->page .= sprintf("BT /%s %.2f Tf %.2f %.2f Td (%s) Tj ET\n", $this->font, $this->fontSize, $x, $this->pageH - $y, $this->esc($str));
    }
    public function textRight($xr, $y, $str) {
        $this->text($xr - $this->textWidth($str), $y, $str);
    }
    public function line($x1, $y1, $x2, $y2) {
        $this->page .= sprintf("%.2f %.2f m %.2f %.2f l S\n", $x1, $this->pageH - $y1, $x2, $this->pageH - $y2);
    }
    public function rect($x, $y, $w, $h, $fill = false) {
        $this->page .= sprintf("%.2f %.2f %.2f %.2f re %s\n", $x, $this->pageH - $y - $h, $w, $h, $fill ? 'f' : 'S');
    }
    public function filledRect($x, $y, $w, $h, $r, $g, $b) {
        $this->page .= sprintf("%.3f %.3f %.3f rg\n", $r/255, $g/255, $b/255);
        $this->rect($x, $y, $w, $h, true);
        $this->page .= "0 0 0 rg\n";
    }
    public function setColor($r, $g, $b) {
        $this->page .= sprintf("%.3f %.3f %.3f rg\n", $r/255, $g/255, $b/255);
    }
    public function setStroke($r, $g, $b) {
        $this->page .= sprintf("%.3f %.3f %.3f RG\n", $r/255, $g/255, $b/255);
    }
    public function setLineWidth($w) {
        $this->page .= sprintf("%.2f w\n", $w);
    }
    public function addJpegFile($name, $path) {
        if (!is_file($path)) return false;
        return $this->addJpegData($name, file_get_contents($path));
    }
    public function addJpegData($name, $data) {
        if (!$data || strlen($data) < 50) return false;
        $w = 0; $h = 0; $i = 2; $len = strlen($data);
        while ($i < $len - 8) {
            if (ord($data[$i]) !== 0xFF) { $i++; continue; }
            $marker = ord($data[$i + 1]);
            if ($marker === 0xC0 || $marker === 0xC1 || $marker === 0xC2) {
                $h = (ord($data[$i + 5]) << 8) + ord($data[$i + 6]);
                $w = (ord($data[$i + 7]) << 8) + ord($data[$i + 8]);
                break;
            }
            if ($marker === 0xD9 || $marker === 0xDA) break;
            $seg = (ord($data[$i + 2]) << 8) + ord($data[$i + 3]);
            $i += 2 + $seg;
        }
        if ($w < 1 || $h < 1) return false;
        $this->images[$name] = ['data' => $data, 'w' => $w, 'h' => $h];
        return true;
    }
    public function image($name, $x, $y, $dw, $dh = 0) {
        if (!isset($this->images[$name])) return;
        $img = $this->images[$name];
        if ($dh <= 0) $dh = $dw * $img['h'] / $img['w'];
        $pdfY = $this->pageH - $y - $dh;
        $this->page .= sprintf("q %.2f 0 0 %.2f %.2f %.2f cm /%s Do Q\n", $dw, $dh, $x, $pdfY, $name);
    }
    public function output($filename) {
        if ($this->page !== '') $this->pages[] = $this->page;
        $out = "%PDF-1.4\n";
        $offsets = [];
        $n = count($this->pages);
        $pageObjStart = 3;
        $fontObj = $pageObjStart + $n * 2;
        $imgStart = $fontObj + 2;
        $imgNames = array_keys($this->images);
        $imgObjs = [];
        foreach ($imgNames as $idx => $name) $imgObjs[$name] = $imgStart + $idx;

        $offsets[1] = strlen($out);
        $out .= "1 0 obj<< /Type /Catalog /Pages 2 0 R >>endobj\n";
        $kids = [];
        for ($i = 0; $i < $n; $i++) $kids[] = ($pageObjStart + $i * 2) . ' 0 R';
        $offsets[2] = strlen($out);
        $out .= "2 0 obj<< /Type /Pages /Kids [" . implode(' ', $kids) . "] /Count $n >>endobj\n";
        $xobj = '';
        foreach ($imgObjs as $name => $oid) $xobj .= "/$name $oid 0 R ";

        for ($i = 0; $i < $n; $i++) {
            $pageObj = $pageObjStart + $i * 2;
            $contentObj = $pageObj + 1;
            $stream = $this->pages[$i];
            $offsets[$pageObj] = strlen($out);
            $boldObj = $fontObj + 1;
            $res = "/Font << /F1 $fontObj 0 R /F2 $boldObj 0 R >>";
            if ($xobj !== '') $res .= " /XObject << $xobj >>";
            $out .= "$pageObj 0 obj<< /Type /Page /Parent 2 0 R /MediaBox [0 0 {$this->pageW} {$this->pageH}] /Contents $contentObj 0 R /Resources << $res >> >>endobj\n";
            $offsets[$contentObj] = strlen($out);
            $out .= "$contentObj 0 obj<< /Length " . strlen($stream) . " >>stream\n{$stream}endstream\nendobj\n";
        }
        $offsets[$fontObj] = strlen($out);
        $out .= "$fontObj 0 obj<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>endobj\n";
        $boldObj = $fontObj + 1;
        $offsets[$boldObj] = strlen($out);
        $out .= "$boldObj 0 obj<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica-Bold >>endobj\n";
        foreach ($imgObjs as $name => $oid) {
            $img = $this->images[$name];
            $data = $img['data'];
            $offsets[$oid] = strlen($out);
            $out .= "$oid 0 obj<< /Type /XObject /Subtype /Image /Width {$img['w']} /Height {$img['h']} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length " . strlen($data) . " >>stream\n";
            $out .= $data . "\nendstream\nendobj\n";
        }
        $maxObj = $fontObj + 1;
        if ($imgObjs) $maxObj = max($maxObj, max($imgObjs));
        $count = $maxObj + 1;
        $xref = strlen($out);
        $out .= "xref\n0 $count\n0000000000 65535 f \n";
        for ($i = 1; $i < $count; $i++) $out .= sprintf("%010d 00000 n \n", $offsets[$i] ?? 0);
        $out .= "trailer<< /Size $count /Root 1 0 R >>\nstartxref\n$xref\n%%EOF";
        header('Content-Type: application/pdf');
        header('Content-Disposition: attachment; filename="' . $filename . '"');
        header('Cache-Control: private, max-age=0, must-revalidate');
        echo $out;
        exit;
    }
}



function contains_arabic($s) {
    return (bool)preg_match('/[\x{0600}-\x{06FF}\x{0750}-\x{077F}\x{08A0}-\x{08FF}]/u', (string)$s);
}

function reshape_arabic($text) {
    $text = (string)$text;
    if ($text === '' || !contains_arabic($text)) return $text;
    static $forms = null;
    if ($forms === null) {
        $forms = [
            0x0621 => [0xFE80,0xFE80,0xFE80,0xFE80],
            0x0622 => [0xFE81,0xFE82,0xFE81,0xFE82],
            0x0623 => [0xFE83,0xFE84,0xFE83,0xFE84],
            0x0624 => [0xFE85,0xFE86,0xFE85,0xFE86],
            0x0625 => [0xFE87,0xFE88,0xFE87,0xFE88],
            0x0626 => [0xFE89,0xFE8A,0xFE8B,0xFE8C],
            0x0627 => [0xFE8D,0xFE8E,0xFE8D,0xFE8E],
            0x0628 => [0xFE8F,0xFE90,0xFE91,0xFE92],
            0x0629 => [0xFE93,0xFE94,0xFE93,0xFE94],
            0x062A => [0xFE95,0xFE96,0xFE97,0xFE98],
            0x062B => [0xFE99,0xFE9A,0xFE9B,0xFE9C],
            0x062C => [0xFE9D,0xFE9E,0xFE9F,0xFEA0],
            0x062D => [0xFEA1,0xFEA2,0xFEA3,0xFEA4],
            0x062E => [0xFEA5,0xFEA6,0xFEA7,0xFEA8],
            0x062F => [0xFEA9,0xFEAA,0xFEA9,0xFEAA],
            0x0630 => [0xFEAB,0xFEAC,0xFEAB,0xFEAC],
            0x0631 => [0xFEAD,0xFEAE,0xFEAD,0xFEAE],
            0x0632 => [0xFEAF,0xFEB0,0xFEAF,0xFEB0],
            0x0633 => [0xFEB1,0xFEB2,0xFEB3,0xFEB4],
            0x0634 => [0xFEB5,0xFEB6,0xFEB7,0xFEB8],
            0x0635 => [0xFEB9,0xFEBA,0xFEBB,0xFEBC],
            0x0636 => [0xFEBD,0xFEBE,0xFEBF,0xFEC0],
            0x0637 => [0xFEC1,0xFEC2,0xFEC3,0xFEC4],
            0x0638 => [0xFEC5,0xFEC6,0xFEC7,0xFEC8],
            0x0639 => [0xFEC9,0xFECA,0xFECB,0xFECC],
            0x063A => [0xFECD,0xFECE,0xFECF,0xFED0],
            0x0641 => [0xFED1,0xFED2,0xFED3,0xFED4],
            0x0642 => [0xFED5,0xFED6,0xFED7,0xFED8],
            0x0643 => [0xFED9,0xFEDA,0xFEDB,0xFEDC],
            0x0644 => [0xFEDD,0xFEDE,0xFEDF,0xFEE0],
            0x0645 => [0xFEE1,0xFEE2,0xFEE3,0xFEE4],
            0x0646 => [0xFEE5,0xFEE6,0xFEE7,0xFEE8],
            0x0647 => [0xFEE9,0xFEEA,0xFEEB,0xFEEC],
            0x0648 => [0xFEED,0xFEEE,0xFEED,0xFEEE],
            0x0649 => [0xFEEF,0xFEF0,0xFEEF,0xFEF0],
            0x064A => [0xFEF1,0xFEF2,0xFEF3,0xFEF4],
            0x0640 => [0x0640,0x0640,0x0640,0x0640],
        ];
    }
    static $nonConnect = [0x0621,0x0622,0x0623,0x0624,0x0625,0x0627,0x0629,0x062F,0x0630,0x0631,0x0632,0x0648,0x0649];
    $chars = preg_split('//u', $text, -1, PREG_SPLIT_NO_EMPTY);
    $codes = [];
    foreach ($chars as $ch) {
        $u = unpack('N', mb_convert_encoding($ch, 'UCS-4BE', 'UTF-8'));
        $codes[] = $u[1];
    }
    $n = count($codes);
    $out = [];
    for ($i = 0; $i < $n; $i++) {
        $c = $codes[$i];
        if (!isset($forms[$c])) { $out[] = $chars[$i]; continue; }
        $prev = $i > 0 ? $codes[$i - 1] : null;
        $next = $i < $n - 1 ? $codes[$i + 1] : null;
        $prevConnects = $prev !== null && isset($forms[$prev]) && !in_array($prev, $nonConnect, true);
        $nextConnects = $next !== null && isset($forms[$next]);
        if ($prevConnects && $nextConnects) $form = 3;
        elseif ($prevConnects) $form = 1;
        elseif ($nextConnects) $form = 2;
        else $form = 0;
        $cp = $forms[$c][$form];
        $out[] = mb_convert_encoding(pack('N', $cp), 'UTF-8', 'UCS-4BE');
    }
    return implode('', array_reverse($out));
}

function arabic_text_jpeg($text, $fontSizePx = 28, $maxWidthPx = 520) {
    $text = trim((string)$text);
    if ($text === '') return null;

    $fontCandidates = [
        // Traditional Arabic (Windows package: trado = regular, tradbdo = bold)
        __DIR__ . '/assets/fonts/trado.ttf',
        dirname(__FILE__) . '/assets/fonts/trado.ttf',
        __DIR__ . '/assets/fonts/resa.ttf',
        __DIR__ . '/assets/fonts/tradbdo.ttf',
        __DIR__ . '/assets/fonts/tradbdo.TTF',
        // Fallbacks
        __DIR__ . '/assets/fonts/Harmattan-Regular.ttf',
        __DIR__ . '/assets/fonts/NotoSansArabic-Regular.ttf',
    ];
    $font = null;
    foreach ($fontCandidates as $f) {
        if ($f && is_readable($f)) { $font = $f; break; }
    }

    $draw = (function_exists('contains_arabic') && contains_arabic($text) && function_exists('reshape_arabic'))
        ? reshape_arabic($text) : $text;

    // Prefer GD + FreeType
    if ($font && function_exists('imagecreatetruecolor') && function_exists('imagettftext')) {
        $bbox = @imagettfbbox($fontSizePx, 0, $font, $draw);
        if ($bbox) {
            $w = abs($bbox[2] - $bbox[0]) + 20;
            $h = abs($bbox[1] - $bbox[7]) + 14;
            if ($w > $maxWidthPx) {
                $fontSizePx = max(12, (int)floor($fontSizePx * $maxWidthPx / $w));
                $bbox = @imagettfbbox($fontSizePx, 0, $font, $draw);
                $w = abs($bbox[2] - $bbox[0]) + 20;
                $h = abs($bbox[1] - $bbox[7]) + 14;
            }
            $im = imagecreatetruecolor(max(1,(int)$w), max(1,(int)$h));
            if ($im) {
                $bg = imagecolorallocate($im, 255, 255, 255);
                $fg = imagecolorallocate($im, 40, 55, 75);
                imagefilledrectangle($im, 0, 0, (int)$w, (int)$h, $bg);
                $x = (int)(10 - min($bbox[0], $bbox[6]));
                $y = (int)($h - 8);
                @imagettftext($im, $fontSizePx, 0, $x, $y, $fg, $font, $draw);
                ob_start();
                imagejpeg($im, null, 95);
                $jpeg = ob_get_clean();
                imagedestroy($im);
                if ($jpeg && strlen($jpeg) > 50) {
                    return ['data' => $jpeg, 'w' => (int)$w, 'h' => (int)$h];
                }
            }
        }
    }

    // Imagick fallback (many shared hosts have this)
    if ($font && class_exists('Imagick') && class_exists('ImagickDraw')) {
        try {
            $drawObj = new ImagickDraw();
            $drawObj->setFont($font);
            $drawObj->setFontSize($fontSizePx);
            $drawObj->setFillColor('#28374b');
            $im = new Imagick();
            $metrics = $im->queryFontMetrics($drawObj, $draw);
            $w = (int)ceil(($metrics['textWidth'] ?? 100) + 20);
            $h = (int)ceil(($metrics['textHeight'] ?? 28) + 14);
            if ($w > $maxWidthPx) {
                $fontSizePx = max(12, (int)floor($fontSizePx * $maxWidthPx / max(1,$w)));
                $drawObj->setFontSize($fontSizePx);
                $metrics = $im->queryFontMetrics($drawObj, $draw);
                $w = (int)ceil(($metrics['textWidth'] ?? 100) + 20);
                $h = (int)ceil(($metrics['textHeight'] ?? 28) + 14);
            }
            $im->newImage(max(1,$w), max(1,$h), new ImagickPixel('white'));
            $im->setImageFormat('jpeg');
            $im->annotateImage($drawObj, 10, (int)($h * 0.75), 0, $draw);
            $jpeg = $im->getImageBlob();
            $im->clear();
            $im->destroy();
            if ($jpeg && strlen($jpeg) > 50) {
                return ['data' => $jpeg, 'w' => $w, 'h' => $h];
            }
        } catch (Throwable $e) { /* ignore */ }
    }

    return null;
}


function zatca_tlv_byte($tag, $value) {
    $value = (string)$value;
    $len = strlen($value);
    if ($len > 255) $value = substr($value, 0, 255);
    return chr((int)$tag) . chr(strlen($value)) . $value;
}

function proforma_qr_payload($sellerName, $vatNo, $timestamp, $totalWithVat, $vatTotal) {
    $tlv = zatca_tlv_byte(1, $sellerName)
         . zatca_tlv_byte(2, $vatNo)
         . zatca_tlv_byte(3, $timestamp)
         . zatca_tlv_byte(4, number_format((float)$totalWithVat, 2, '.', ''))
         . zatca_tlv_byte(5, number_format((float)$vatTotal, 2, '.', ''));
    return base64_encode($tlv);
}

/**
 * Decode + validate Base64 TLV QR payload.
 * Returns ['valid'=>bool, 'errors'=>[], 'fields'=>[1=>...,2=>...]]
 */
function validate_proforma_qr($base64, $expected = null) {
    $result = ['valid' => false, 'errors' => [], 'fields' => []];
    $base64 = trim((string)$base64);
    if ($base64 === '') {
        $result['errors'][] = 'Empty QR payload';
        return $result;
    }
    $bin = base64_decode($base64, true);
    if ($bin === false || $bin === '') {
        $result['errors'][] = 'Invalid Base64 encoding';
        return $result;
    }
    $len = strlen($bin);
    $pos = 0;
    $fields = [];
    while ($pos + 2 <= $len) {
        $tag = ord($bin[$pos]);
        $tlen = ord($bin[$pos + 1]);
        $pos += 2;
        if ($pos + $tlen > $len) {
            $result['errors'][] = "Truncated TLV for tag $tag";
            return $result;
        }
        $fields[$tag] = substr($bin, $pos, $tlen);
        $pos += $tlen;
    }
    if ($pos !== $len) {
        $result['errors'][] = 'Trailing bytes after TLV';
    }
    // Required ZATCA Phase-1 tags
    foreach ([1, 2, 3, 4, 5] as $req) {
        if (!isset($fields[$req]) || $fields[$req] === '') {
            $result['errors'][] = "Missing required tag $req";
        }
    }
    if (isset($fields[2]) && !preg_match('/^[0-9]{10,15}$/', $fields[2])) {
        $result['errors'][] = 'VAT number format invalid (tag 2)';
    }
    if (isset($fields[3]) && strtotime($fields[3]) === false) {
        $result['errors'][] = 'Timestamp format invalid (tag 3)';
    }
    if (isset($fields[4]) && !is_numeric($fields[4])) {
        $result['errors'][] = 'Invoice total must be numeric (tag 4)';
    }
    if (isset($fields[5]) && !is_numeric($fields[5])) {
        $result['errors'][] = 'VAT amount must be numeric (tag 5)';
    }
    // Optional expected match (from invoice record)
    if (is_array($expected) && empty($result['errors'])) {
        if (isset($expected['seller_vat']) && isset($fields[2]) && $fields[2] !== $expected['seller_vat']) {
            $result['errors'][] = 'VAT number does not match invoice';
        }
        if (isset($expected['grand_total']) && isset($fields[4])) {
            if (abs((float)$fields[4] - (float)$expected['grand_total']) > 0.009) {
                $result['errors'][] = 'Grand total does not match invoice';
            }
        }
        if (isset($expected['vat_amount']) && isset($fields[5])) {
            if (abs((float)$fields[5] - (float)$expected['vat_amount']) > 0.009) {
                $result['errors'][] = 'VAT amount does not match invoice';
            }
        }
    }
    $result['fields'] = [
        'seller_name' => $fields[1] ?? null,
        'seller_vat'  => $fields[2] ?? null,
        'timestamp'   => $fields[3] ?? null,
        'grand_total' => $fields[4] ?? null,
        'vat_amount'  => $fields[5] ?? null,
        'raw_tags'    => $fields,
    ];
    $result['valid'] = empty($result['errors']);
    return $result;
}

function build_qr_jpeg($data, $size = 180) {
    $url = 'https://api.qrserver.com/v1/create-qr-code/?size=' . (int)$size . 'x' . (int)$size . '&ecc=M&margin=1&data=' . rawurlencode($data);
    $ctx = stream_context_create(['http' => ['timeout' => 8], 'ssl' => ['verify_peer' => true]]);
    $png = @file_get_contents($url, false, $ctx);
    if (!$png || !function_exists('imagecreatefromstring')) return null;
    $im = @imagecreatefromstring($png);
    if (!$im) return null;
    $w = imagesx($im); $h = imagesy($im);
    $bg = imagecreatetruecolor($w, $h);
    $white = imagecolorallocate($bg, 255, 255, 255);
    imagefill($bg, 0, 0, $white);
    imagecopy($bg, $im, 0, 0, 0, 0, $w, $h);
    ob_start();
    imagejpeg($bg, null, 92);
    $jpg = ob_get_clean();
    imagedestroy($im);
    imagedestroy($bg);
    return $jpg ?: null;
}


function number_to_words_en($num) {
    $num = round((float)$num, 2);
    $ones = ['', 'One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten',
        'Eleven', 'Twelve', 'Thirteen', 'Fourteen', 'Fifteen', 'Sixteen', 'Seventeen', 'Eighteen', 'Nineteen'];
    $tens = ['', '', 'Twenty', 'Thirty', 'Forty', 'Fifty', 'Sixty', 'Seventy', 'Eighty', 'Ninety'];
    $int = (int)floor($num);
    $halalas = (int)round(($num - $int) * 100);
    if ($int === 0 && $halalas === 0) return 'Zero';
    $words = '';
    $toWords = function ($n) use (&$toWords, $ones, $tens) {
        if ($n < 20) return $ones[$n];
        if ($n < 100) return $tens[(int)($n / 10)] . ($n % 10 ? ' ' . $ones[$n % 10] : '');
        if ($n < 1000) return $ones[(int)($n / 100)] . ' Hundred' . ($n % 100 ? ' ' . $toWords($n % 100) : '');
        if ($n < 1000000) {
            return $toWords((int)($n / 1000)) . ' Thousand' . ($n % 1000 ? ' ' . $toWords($n % 1000) : '');
        }
        if ($n < 1000000000) {
            return $toWords((int)($n / 1000000)) . ' Million' . ($n % 1000000 ? ' ' . $toWords($n % 1000000) : '');
        }
        return (string)$n;
    };
    $words = $toWords($int);
    if ($halalas > 0) {
        $words .= ' and ' . $toWords($halalas) . ' Halala' . ($halalas !== 1 ? 's' : '');
    }
    return trim($words);
}
function sar_amount_in_words($amount) {
    return 'Saudi Riyals ' . number_to_words_en($amount) . ' Only';
}

function money($n) { return number_format((float)$n, 2); }
function wrap_lines($text, $maxChars) {
    $text = trim(preg_replace('/\s+/', ' ', (string)$text));
    if ($text === '') return [];
    $words = explode(' ', $text);
    $lines = []; $cur = '';
    foreach ($words as $w) {
        $trial = $cur === '' ? $w : ($cur . ' ' . $w);
        if (strlen($trial) <= $maxChars) $cur = $trial;
        else { if ($cur !== '') $lines[] = $cur; $cur = $w; }
    }
    if ($cur !== '') $lines[] = $cur;
    return $lines;
}

$sellerNameQr = $inv['seller_name'] ?: 'IYAADTEC SOLUTIONS LLC';
$sellerVatQr = preg_replace('/\s+/', '', $inv['seller_vat'] ?: '313104808500003');
$tsQr = date('c', strtotime(($inv['invoice_date'] ?: date('Y-m-d')) . ' 12:00:00'));
$qrPayload = proforma_qr_payload($sellerNameQr, $sellerVatQr, $tsQr, $grand, $vatAmt);
$qrCheck = validate_proforma_qr($qrPayload, [
    'seller_vat' => $sellerVatQr,
    'grand_total' => $grand,
    'vat_amount' => $vatAmt,
]);
$qrJpeg = null;
$hasQr = false;
if ($qrCheck['valid']) {
    $qrJpeg = build_qr_jpeg($qrPayload, 200);
    $pdf = new SimplePDF();
    $hasQr = $qrJpeg ? $pdf->addJpegData('QR', $qrJpeg) : false;
} else {
    $pdf = new SimplePDF();
}
if (!isset($pdf) || !($pdf instanceof SimplePDF)) {
    $pdf = new SimplePDF();
}
$L = 36;
$R = 36;
$pageW = $pdf->pageW;
$pageH = $pdf->pageH;
$contentW = $pageW - $L - $R;

// Palette from selected template
$navy   = $th['navy'];
$navy2  = $th['navy2'];
$teal   = $th['accent'];
$teal2  = $th['accent2'];
$muted  = $th['muted'];
$lineC  = $th['line'];
$soft   = $th['soft'];
$white  = [255, 255, 255];
$ink    = $th['ink'];
$buyerHdr = $th['buyer_hdr'];
$sellerHdr = $th['seller_hdr'];
$wordsBg = $th['words_bg'];

$hasLogo = false; // logo disabled on proforma PDF

$d = $inv['invoice_date'];
try { $dFmt = date('d F Y', strtotime($d)); } catch (Exception $e) { $dFmt = $d; }
$invNo = $inv['invoice_no'];
$sellerName = $inv['seller_name'] ?: 'IYAADTEC SOLUTIONS LLC';

// ========== HEADER BY TEMPLATE (structurally different) ==========
$contentTop = 102;

if ($tpl === 'classic') {
    // Full navy band + teal underline + frame
    $pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
    $pdf->setLineWidth(1.2);
    $pdf->rect(18, 18, $pageW - 36, $pageH - 36, false);
    $pdf->filledRect(18, 18, $pageW - 36, 70, $navy[0], $navy[1], $navy[2]);
    $pdf->filledRect(18, 88, $pageW - 36, 4, $teal[0], $teal[1], $teal[2]);
    if ($hasLogo) {
        $pdf->filledRect($L + 4, 28, 62, 44, 255, 255, 255);
        $pdf->image('Logo', $L + 6, 30, 58, 40);
        $tx = $L + 72;
    } else { $tx = $L; }
    $pdf->setFont(true); $pdf->setFontSize(18); $pdf->setColor(255,255,255);
    $pdf->text($tx, 46, 'PROFORMA INVOICE'); $pdf->setFont(false);
    $pdf->setFontSize(8); $pdf->setColor(160, 185, 210);
    $pdf->text($tx, 62, 'IYAADTEC SOLUTIONS LLC');
    $metaX = $pageW - $R - 150;
    $pdf->filledRect($metaX, 28, 150, 48, $navy2[0], $navy2[1], $navy2[2]);
    $pdf->setStroke($teal[0], $teal[1], $teal[2]); $pdf->setLineWidth(1.5);
    $pdf->line($metaX, 28, $metaX, 76);
    $pdf->setFontSize(7); $pdf->setColor(140, 170, 195);
    $pdf->text($metaX + 12, 40, 'PROFORMA INVOICE #');
    $pdf->setFont(true); $pdf->setFontSize(14); $pdf->setColor(255,255,255);
    $pdf->text($metaX + 12, 56, $invNo); $pdf->setFont(false);
    $pdf->setFontSize(8); $pdf->setColor(120, 200, 210);
    $pdf->text($metaX + 12, 70, $dFmt);
    $contentTop = 102;

} elseif ($tpl === 'executive') {
    // Left gold sidebar + light content, title on white
    $pdf->filledRect(0, 0, 28, $pageH, $teal[0], $teal[1], $teal[2]);
    $pdf->filledRect(28, 0, 4, $pageH, $navy[0], $navy[1], $navy[2]);
    $L = 48;
    if ($hasLogo) { $pdf->image('Logo', $L, 28, 56, 38); $tx = $L + 66; }
    else { $tx = $L; }
    $pdf->setFont(true); $pdf->setFontSize(20); $pdf->setColor($navy[0], $navy[1], $navy[2]);
    $pdf->text($tx, 48, 'PROFORMA INVOICE'); $pdf->setFont(false);
    $pdf->setFontSize(8); $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->text($tx, 62, 'IYAADTEC SOLUTIONS LLC');
    $pdf->setStroke($teal[0], $teal[1], $teal[2]); $pdf->setLineWidth(2);
    $pdf->line($L, 78, $pageW - $R, 78);
    $pdf->setFontSize(8); $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->textRight($pageW - $R, 40, 'Proforma Invoice #');
    $pdf->setFont(true); $pdf->setFontSize(14); $pdf->setColor($navy[0], $navy[1], $navy[2]);
    $pdf->textRight($pageW - $R, 56, $invNo); $pdf->setFont(false);
    $pdf->setFontSize(9); $pdf->setColor($teal[0], $teal[1], $teal[2]);
    $pdf->textRight($pageW - $R, 70, $dFmt);
    $contentTop = 96;
    $contentW = $pageW - $L - $R;

} elseif ($tpl === 'modern') {
    // Minimal: thin top accent, no heavy bars, open layout
    $pdf->filledRect(0, 0, $pageW, 6, $teal[0], $teal[1], $teal[2]);
    if ($hasLogo) { $pdf->image('Logo', $L, 22, 50, 34); $tx = $L + 58; }
    else { $tx = $L; }
    $pdf->setFont(true); $pdf->setFontSize(16); $pdf->setColor($navy[0], $navy[1], $navy[2]);
    $pdf->text($tx, 40, 'PROFORMA INVOICE'); $pdf->setFont(false);
    $pdf->setFontSize(8); $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->text($tx, 54, 'IYAADTEC SOLUTIONS LLC');
    $pdf->setStroke($lineC[0], $lineC[1], $lineC[2]); $pdf->setLineWidth(0.6);
    $pdf->line($L, 68, $pageW - $R, 68);
    // Meta as text right, no box
    $pdf->setFontSize(8); $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->textRight($pageW - $R, 32, 'No. ' . $invNo);
    $pdf->setFontSize(9); $pdf->setColor($navy[0], $navy[1], $navy[2]);
    $pdf->textRight($pageW - $R, 46, $dFmt);
    $contentTop = 82;

} elseif ($tpl === 'corporate') {
    // Wide green header, centered title
    $pdf->filledRect(0, 0, $pageW, 88, $navy[0], $navy[1], $navy[2]);
    $pdf->filledRect(0, 88, $pageW, 5, $teal[0], $teal[1], $teal[2]);
    if ($hasLogo) {
        $pdf->filledRect(($pageW/2) - 80, 14, 40, 28, 255, 255, 255);
        $pdf->image('Logo', ($pageW/2) - 78, 15, 36, 26);
    }
    $pdf->setFont(true); $pdf->setFontSize(18); $pdf->setColor(255,255,255);
    $title = 'PROFORMA INVOICE';
    $tw = $pdf->textWidth($title);
    $pdf->text(($pageW - $tw) / 2, 58, $title); $pdf->setFont(false);
    $pdf->setFontSize(8); $pdf->setColor(180, 220, 200);
    $sub = 'IYAADTEC SOLUTIONS LLC';
    $pdf->setFontSize(8);
    $sw = $pdf->textWidth($sub);
    $pdf->text(($pageW - $sw) / 2, 72, $sub);
    // Meta strip below header
    $pdf->filledRect($L, 100, $contentW, 26, $soft[0], $soft[1], $soft[2]);
    $pdf->setFontSize(8); $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->text($L + 12, 116, 'Proforma #  ' . $invNo);
    $pdf->textRight($pageW - $R - 12, 116, $dFmt);
    $contentTop = 138;

} else { // elegant
    // Double border, indigo accents, title with underline ornament
    $pdf->setStroke($navy[0], $navy[1], $navy[2]); $pdf->setLineWidth(1.8);
    $pdf->rect(22, 22, $pageW - 44, $pageH - 44, false);
    $pdf->setStroke($teal[0], $teal[1], $teal[2]); $pdf->setLineWidth(0.7);
    $pdf->rect(28, 28, $pageW - 56, $pageH - 56, false);
    if ($hasLogo) { $pdf->image('Logo', $L, 40, 52, 36); $tx = $L + 60; }
    else { $tx = $L; }
    $pdf->setFont(true); $pdf->setFontSize(17); $pdf->setColor($navy[0], $navy[1], $navy[2]);
    $pdf->text($tx, 54, 'PROFORMA INVOICE'); $pdf->setFont(false);
    $pdf->setStroke($teal[0], $teal[1], $teal[2]); $pdf->setLineWidth(1.2);
    $pdf->line($tx, 62, $tx + 160, 62);
    $pdf->setFontSize(8); $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->text($tx, 74, 'IYAADTEC SOLUTIONS LLC');
    // Rounded-style meta (rectangle) top right
    $metaX = $pageW - $R - 140;
    $pdf->filledRect($metaX, 40, 140, 50, $soft[0], $soft[1], $soft[2]);
    $pdf->setStroke($teal[0], $teal[1], $teal[2]); $pdf->setLineWidth(1);
    $pdf->rect($metaX, 40, 140, 50, false);
    $pdf->setFontSize(7); $pdf->setColor($teal[0], $teal[1], $teal[2]);
    $pdf->text($metaX + 12, 52, 'PROFORMA INVOICE #');
    $pdf->setFont(true); $pdf->setFontSize(13); $pdf->setColor($navy[0], $navy[1], $navy[2]);
    $pdf->text($metaX + 12, 68, $invNo); $pdf->setFont(false);
    $pdf->setFontSize(8); $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->text($metaX + 12, 82, $dFmt);
    $contentTop = 110;
}


// ========== INFO STRIP ==========
$y = $contentTop;
$pdf->filledRect($L, $y, $contentW, 28, $soft[0], $soft[1], $soft[2]);
$pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
$pdf->setLineWidth(0.5);
$pdf->rect($L, $y, $contentW, 28, false);

$pdf->setFontSize(7);
$pdf->setColor($muted[0], $muted[1], $muted[2]);
$pdf->text($L + 12, $y + 12, 'DOCUMENT TYPE');
$pdf->setFont(true); $pdf->setFontSize(9); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$pdf->text($L + 12, $y + 23, 'Proforma Invoice'); $pdf->setFont(false);

$pdf->setFontSize(7); $pdf->setColor($muted[0], $muted[1], $muted[2]);
$pdf->text($L + 160, $y + 12, 'CURRENCY');
$pdf->setFont(true); $pdf->setFontSize(9); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$pdf->text($L + 160, $y + 23, 'SAR (Saudi Riyal)'); $pdf->setFont(false);

$pdf->setFontSize(7); $pdf->setColor($muted[0], $muted[1], $muted[2]);
$pdf->text($L + 320, $y + 12, 'VAT RATE');
$pdf->setFont(true); $pdf->setFontSize(9); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$pdf->text($L + 320, $y + 23, rtrim(rtrim(number_format($vatRate, 2), '0'), '.') . '%'); $pdf->setFont(false);

$pdf->setFontSize(7); $pdf->setColor($muted[0], $muted[1], $muted[2]);
$pdf->text($L + 420, $y + 12, 'ITEMS');
$pdf->setFont(true); $pdf->setFontSize(9); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$pdf->text($L + 420, $y + 23, (string)count($lines)); $pdf->setFont(false);

// ========== BUYER / SELLER ==========
$y = 144;
$gap = 12;
$cardW = ($contentW - $gap) / 2;
$cardH = 132;

// Buyer card
$pdf->filledRect($L, $y, $cardW, $cardH, 255, 255, 255);
$pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
$pdf->setLineWidth(0.8);
$pdf->rect($L, $y, $cardW, $cardH, false);
$pdf->filledRect($L, $y, $cardW, 22, $buyerHdr[0], $buyerHdr[1], $buyerHdr[2]);
$pdf->setFont(true); $pdf->setFontSize(9); $pdf->setColor(255,255,255);
$pdf->text($L + 12, $y + 15, 'BUYER'); $pdf->setFont(false);

// Seller card
$rx = $L + $cardW + $gap;
$pdf->filledRect($rx, $y, $cardW, $cardH, 255, 255, 255);
$pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
$pdf->rect($rx, $y, $cardW, $cardH, false);
$pdf->filledRect($rx, $y, $cardW, 22, $sellerHdr[0], $sellerHdr[1], $sellerHdr[2]);
$pdf->setFont(true); $pdf->setFontSize(9); $pdf->setColor(255,255,255);
$pdf->text($rx + 12, $y + 15, 'SELLER'); $pdf->setFont(false);

// Names
$pdf->setFont(true); $pdf->setFontSize(11); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$pdf->text($L + 12, $y + 40, substr($inv['buyer_name'] ?? '—', 0, 32));
$pdf->text($rx + 12, $y + 40, substr($sellerName, 0, 30));
$pdf->setFont(false);

$pdf->setFontSize(9);
$pdf->setColor(50, 65, 85);
$by = $y + 56;
$sy = $y + 56;

$buyerLines = [];
$buyerArabicImg = null;
$buyerArabicName = trim((string)($inv['buyer_name_ar'] ?? ''));
// Never send Arabic through Helvetica text() — render as image
if ($buyerArabicName !== '') {
    if (function_exists('arabic_text_jpeg')) {
        $buyerArabicImg = arabic_text_jpeg($buyerArabicName, 32, 560);
    }
}
if (!empty($inv['buyer_cr'])) $buyerLines[] = 'CR No:  ' . $inv['buyer_cr'];
if (!empty($inv['buyer_vat'])) $buyerLines[] = 'VAT No: ' . $inv['buyer_vat'];
if (!empty($inv['buyer_address'])) foreach (wrap_lines($inv['buyer_address'], 36) as $ln) $buyerLines[] = $ln;
if (!empty($inv['buyer_contact'])) $buyerLines[] = $inv['buyer_contact'];

$sellerLines = [];
if (!empty($inv['seller_cr'])) $sellerLines[] = 'CR No:  ' . $inv['seller_cr'];
if (!empty($inv['seller_vat'])) $sellerLines[] = 'VAT No: ' . $inv['seller_vat'];
$addr = $inv['seller_address'] ?: 'Building No. 5079, King Saud Road, Ar Rabie District, Dammam 32241, Kingdom of Saudi Arabia';
foreach (wrap_lines($addr, 34) as $ln) $sellerLines[] = $ln;

$buyerY = $by;
if (!empty($buyerArabicImg) && is_array($buyerArabicImg)) {
    $imgName = 'BUYERAR';
    if ($pdf->addJpegData($imgName, $buyerArabicImg['data'])) {
        $maxW = $cardW - 24;
        $dw = $maxW;
        $dh = $dw * $buyerArabicImg['h'] / max(1, $buyerArabicImg['w']);
        if ($dh > 16) { $dh = 16; $dw = $dh * $buyerArabicImg['w'] / max(1, $buyerArabicImg['h']); }
        $pdf->image($imgName, $L + 12, $buyerY - 10, $dw, $dh);
        $buyerY += max(14, $dh + 2);
    }
}
for ($i = 0; $i < 5; $i++) {
    if (isset($buyerLines[$i])) $pdf->text($L + 12, $buyerY + $i * 12.5, substr($buyerLines[$i], 0, 38));
    if (isset($sellerLines[$i])) $pdf->text($rx + 12, $sy + $i * 12.5, substr($sellerLines[$i], 0, 36));
}

// ========== LINE ITEMS TABLE ==========
$y = $y + $cardH + 20;

$pdf->setFont(true); $pdf->setFontSize(8); $pdf->setColor($muted[0], $muted[1], $muted[2]);
$pdf->text($L, $y, 'LINE ITEMS'); $pdf->setFont(false);
$pdf->setStroke($teal[0], $teal[1], $teal[2]);
$pdf->setLineWidth(1.5);
$pdf->line($L + 58, $y - 2, $L + $contentW, $y - 2);
$y += 10;

$rowH = 26;
$colNo = 36;
$colAmt = 108;
$colDesc = $contentW - $colNo - $colAmt;

// Header
$pdf->filledRect($L, $y, $contentW, $rowH, $navy[0], $navy[1], $navy[2]);
$pdf->filledRect($L, $y, 3, $rowH, $teal[0], $teal[1], $teal[2]);
$pdf->setFont(true); $pdf->setFontSize(8); $pdf->setColor(255,255,255);
$pdf->text($L + 10, $y + 17, '#');
$pdf->text($L + $colNo + 8, $y + 17, 'DESCRIPTION OF SERVICES / ITEMS');
$pdf->textRight($L + $contentW - 12, $y + 17, 'AMOUNT (SAR)');
$pdf->setFont(false);
$y += $rowH;

$pdf->setFontSize(10);
foreach ($lines as $i => $line) {
    if ($y > 640) {
        $pdf->addPage();
        $pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
        $pdf->setLineWidth(1.2);
        $pdf->rect(18, 18, $pageW - 36, $pageH - 36, false);
        $y = 40;
        $pdf->filledRect($L, $y, $contentW, $rowH, $navy[0], $navy[1], $navy[2]);
        $pdf->setFont(true); $pdf->setFontSize(8); $pdf->setColor(255,255,255);
        $pdf->text($L + 10, $y + 17, '#');
        $pdf->text($L + $colNo + 8, $y + 17, 'DESCRIPTION OF SERVICES / ITEMS');
        $pdf->textRight($L + $contentW - 12, $y + 17, 'AMOUNT (SAR)');
        $pdf->setFont(false);
        $y += $rowH;
        $pdf->setFontSize(10);
    }
    if ($i % 2 === 1) $pdf->filledRect($L, $y, $contentW, $rowH, $soft[0], $soft[1], $soft[2]);
    $pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
    $pdf->setLineWidth(0.4);
    $pdf->line($L, $y + $rowH, $L + $contentW, $y + $rowH);

    $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->text($L + 10, $y + 17, str_pad((string)($i + 1), 2, '0', STR_PAD_LEFT));
    $pdf->setColor($ink[0], $ink[1], $ink[2]);
    $pdf->text($L + $colNo + 8, $y + 17, substr($line['description'] ?? '', 0, 54));
    $pdf->setFont(true);
    $pdf->textRight($L + $contentW - 12, $y + 17, money($line['amount']));
    $pdf->setFont(false);
    $y += $rowH;
}

// ========== TOTALS ==========
$y += 14;
$boxW = 240;
$boxX = $L + $contentW - $boxW;

$pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
$pdf->setLineWidth(0.8);
$pdf->rect($boxX, $y, $boxW, 86, false);

// Subtotal
$pdf->setFontSize(9);
$pdf->setColor($muted[0], $muted[1], $muted[2]);
$pdf->text($boxX + 14, $y + 18, 'Subtotal');
$pdf->setFont(true); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$pdf->textRight($boxX + $boxW - 14, $y + 18, 'SAR  ' . money($sub));
$pdf->setFont(false);
$pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
$pdf->setLineWidth(0.4);
$pdf->line($boxX + 10, $y + 26, $boxX + $boxW - 10, $y + 26);

// VAT
$pdf->setColor($muted[0], $muted[1], $muted[2]);
$pdf->text($boxX + 14, $y + 40, 'VAT (' . rtrim(rtrim(number_format($vatRate, 2), '0'), '.') . '%)');
$pdf->setFont(true); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$pdf->textRight($boxX + $boxW - 14, $y + 40, 'SAR  ' . money($vatAmt));
$pdf->setFont(false);

// Grand total
$pdf->filledRect($boxX, $y + 50, $boxW, 36, $navy[0], $navy[1], $navy[2]);
$pdf->filledRect($boxX, $y + 50, 5, 36, $teal[0], $teal[1], $teal[2]);
$pdf->setFontSize(8);
$pdf->setColor(140, 200, 210);
$pdf->text($boxX + 14, $y + 64, 'GRAND TOTAL');
$pdf->setFont(true);
$pdf->setFontSize(13);
$pdf->setColor(255, 255, 255);
$pdf->textRight($boxX + $boxW - 14, $y + 72, 'SAR  ' . money($grand));
$pdf->setFont(false);

$y += 104;

// ========== AMOUNT IN WORDS ==========
$customWords = trim($inv['amount_words'] ?? '');
// Never show numeric amount in words line — always convert to English words
// (use custom only if it has no digits)
if ($customWords !== '' && !preg_match('/\d/', $customWords)) {
    $words = $customWords;
} else {
    $words = sar_amount_in_words($grand);
}


$pdf->filledRect($L, $y, $contentW, 46, $wordsBg[0], $wordsBg[1], $wordsBg[2]);
$pdf->setStroke($teal[0], $teal[1], $teal[2]);
$pdf->setLineWidth(3);
$pdf->line($L, $y, $L, $y + 46);
$pdf->setLineWidth(0.6);
$pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
$pdf->rect($L, $y, $contentW, 46, false);

$pdf->setFont(true); $pdf->setFontSize(7); $pdf->setColor($teal2[0], $teal2[1], $teal2[2]);
$pdf->text($L + 14, $y + 14, 'AMOUNT IN WORDS'); $pdf->setFont(false);
$pdf->setFontSize(10); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$wlines = wrap_lines($words, 90);
foreach ($wlines as $wi => $wl) {
    if ($wi > 1) break;
    $pdf->text($L + 14, $y + 28 + $wi * 12, $wl);
}

// ========== NOTES / SIGNATURE ROW ==========
$y += 60;
if (!empty($inv['notes'])) {
    $pdf->setFont(true); $pdf->setFontSize(7); $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->text($L, $y, 'NOTES'); $pdf->setFont(false);
    $pdf->setFontSize(9); $pdf->setColor($ink[0], $ink[1], $ink[2]);
    foreach (wrap_lines($inv['notes'], 70) as $wi => $wl) {
        if ($wi > 2) break;
        $pdf->text($L, $y + 14 + $wi * 12, $wl);
    }
}

// QR + Signature row
$sigX = $L + $contentW - 180;
if ($hasQr) {
    // QR block left of signature
    $qrSize = 72;
    $qrX = $L;
    $qrY = $y;
    $pdf->filledRect($qrX, $qrY, $qrSize + 16, $qrSize + 28, 255, 255, 255);
    $pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
    $pdf->setLineWidth(0.6);
    $pdf->rect($qrX, $qrY, $qrSize + 16, $qrSize + 28, false);
    $pdf->image('QR', $qrX + 8, $qrY + 6, $qrSize, $qrSize);
    $pdf->setFontSize(6);
    $pdf->setColor($muted[0], $muted[1], $muted[2]);
    $pdf->text($qrX + 8, $qrY + $qrSize + 18, 'QR Code');
}

$pdf->setStroke($lineC[0], $lineC[1], $lineC[2]);
$pdf->setLineWidth(0.5);
$pdf->line($sigX, $y + 40, $sigX + 160, $y + 40);
$pdf->setFontSize(7); $pdf->setColor($muted[0], $muted[1], $muted[2]);
$pdf->text($sigX, $y + 52, 'Authorized Signature');
$pdf->setFontSize(8); $pdf->setColor($ink[0], $ink[1], $ink[2]);
$pdf->text($sigX, $y + 64, 'IYAADTEC SOLUTIONS LLC');

// ========== FOOTER ==========
$pdf->filledRect(18, $pageH - 42, $pageW - 36, 24, $navy[0], $navy[1], $navy[2]);
$pdf->filledRect(18, $pageH - 42, $pageW - 36, 2, $teal[0], $teal[1], $teal[2]);
$pdf->setFontSize(7);
$pdf->setColor(150, 175, 200);
$pdf->text($L, $pageH - 27, 'IYAADTEC SOLUTIONS LLC');
$pdf->textRight($pageW - $R, $pageH - 27, 'Page 1 of 1');

$safe = preg_replace('/[^a-zA-Z0-9_-]/', '_', $invNo);
$pdf->output('Proforma_' . $safe . '.pdf');
