<?php //Generator
// ==== expects: $parts from assembler (no re-includes here) ====
// keys: wrapper_Start, wrapper_End, headerTemplate, contractHeader, inst, body, footerTemplate, orientation, customImages

$tenantBase = '../../../' . TENANT_URL;
$ENGINES_DIR = $tenantBase . '/engines/pdf_structure';

// Ensure output dir
$reportsDir = $tenantBase . '/output/reports/' . ($_REQUEST['clientnumber'] ?? '');
if (!is_dir($reportsDir)) {
    @mkdir($reportsDir, 0777, true);
}

// QR
require "../../packages/phpqrcode/qrlib.php";
$qrPath = $tenantBase . '/images/repQR.png';
QRcode::png(getCompanyDetails('web') . '/preview.php?repnumber=' . ($_REQUEST['repnumber'] ?? ''), $qrPath, 'L', 4, 2);

// Resolve header/footer templates (they are always NAME.php)
$headerHtml = '';
$footerHtml = '';
if (!empty($parts['headerTemplate'])) {
    $p = $ENGINES_DIR . '/' . $parts['headerTemplate'];
    if (is_file($p)) $headerHtml = file_get_contents($p);
}
if (!empty($parts['footerTemplate'])) {
    $p = $ENGINES_DIR . '/' . $parts['footerTemplate'];
    if (is_file($p)) $footerHtml = file_get_contents($p);
}

// AF images (optional exclude per customImages[form])
$form = $_REQUEST['form'] ?? '';
$excludeImage = 0;
if (!empty($parts['customImages']) && is_array($parts['customImages']) && isset($parts['customImages'][$form])) {
    $excludeImage = (int)$parts['customImages'][$form];
}
for ($i = 1; $i <= 6; $i++) {
    $img = $tenantBase . "/images/company/afl_{$i}.jpg";
    if ($excludeImage === $i) {
        $headerHtml = str_replace("[AF{$i}]", '', $headerHtml);
        continue;
    }
    $headerHtml = str_replace("[AF{$i}]", file_exists($img) ? '<td><img src="' . $img . '" height="40px" /></td>' : '', $headerHtml);
}

// Data for swaps
$sdata = explode("|", getSurveyorDetails($_REQUEST['repnumber'] ?? '', 'REPDATA'));
$rdata = explode("|", getItemReportDetails($_REQUEST['repnumber'] ?? '', 'REPDATA'));

// Surveyor signature to base64
$base64ImageSrc = '';
$signPath = $tenantBase . '/images/signatures/' . ($sdata[2] ?? '') . '.jpg';
if (file_exists($signPath)) $base64ImageSrc = 'data:image/jpeg;base64,' . base64_encode(file_get_contents($signPath));

// Styles (default generic style.php; swap if you later add per-type)
$styleHtml = '';
$stylePath = $ENGINES_DIR . '/style.php';
if (is_file($stylePath)) $styleHtml = file_get_contents($stylePath);

// ---------- BUILD CONTENT FOR SETTER MODE (no <htmlpageheader> tags) ----------
$header = $headerHtml;                               // header fragment
$footer = $footerHtml;                               // footer fragment

// First-page extras (under the header, not inside it)
$firstPageExtras = '';
if (!empty($parts['contractHeader'])) $firstPageExtras .= $parts['contractHeader'];
if (!empty($parts['inst']))           $firstPageExtras .= $parts['inst'];

// Body HTML (wrapper + optional first page extras + body + wrapper end)
$body  = ($parts['wrapper_Start'] ?? '');
$body .= $firstPageExtras;
$body .= ($parts['body'] ?? '');

// === Photos at the end (imageMode=1) ===
if (!empty($_REQUEST['imageMode']) && $_REQUEST['imageMode'] === "1") {
    @file_put_contents(__DIR__ . "/imagePath.txt", "AFTER CALL imageMode=" . $_REQUEST['imageMode'] . '|' . ($cx['itemnumber'] ?? '') . PHP_EOL, FILE_APPEND);

    // Collect up to 6 images named {itemnumber}_1..6.jpg
    $imagePaths = [];
    for ($i = 1; $i <= 6; $i++) {
        $imgPath = '../../../' . TENANT_URL . '/images/report_images/' . ($cx['itemnumber'] ?? '') . '_' . $i . '.jpg';
        if (file_exists($imgPath)) $imagePaths[] = $imgPath;
    }
    $imgCount = count($imagePaths);
    if ($imgCount === 0) return;

    // --- layout (decide columns + target height mm once) ---
    if ($imgCount === 1) {
        $cols = 1;
        $maxH_mm = 230;
        $tableBefore = true;
    } elseif ($imgCount === 2) {
        $cols = 2;
        $maxH_mm = 200;
        $tableBefore = true;
    } elseif ($imgCount === 3) {
        $cols = 3;
        $maxH_mm = 160;
        $tableBefore = true;
    } elseif ($imgCount === 4) {
        $cols = 2;
        $maxH_mm = 120;
        $tableBefore = true;
    } else { // 5-6
        $cols = 3;
        $maxH_mm = 75;
        $tableBefore = true;
    }
    $cellWidth = floor(100 / max(1, $cols));

    // --- fast rounded-corner processor with caching + downscale ---
    if (!function_exists('enrep_process_photo_fast')) {
        function enrep_process_photo_fast(string $src, int $radius = 24, int $maxH_px = 600): string
        {
            if (!file_exists($src)) return $src;

            $tenantBase = '../../../' . TENANT_URL;
            $cacheDir   = $tenantBase . '/images/cache';
            if (!is_dir($cacheDir)) @mkdir($cacheDir, 0777, true);

            $mtime = filemtime($src) ?: 0;
            // include "|square" in cache key so old non-square versions don't collide
            $hash  = md5($src . '|' . $mtime . '|r' . $radius . '|h' . $maxH_px . '|square');
            $dest  = $cacheDir . "/$hash.png";
            if (file_exists($dest)) return $dest;

            // Prefer Imagick
            if (extension_loaded('imagick')) {
                try {
                    $im = new Imagick($src);
                    $im->setImageColorspace(Imagick::COLORSPACE_RGB);
                    $im->setImageAlphaChannel(Imagick::ALPHACHANNEL_SET);

                    // ---- square crop (center) ----
                    $w = $im->getImageWidth();
                    $h = $im->getImageHeight();
                    $side = min($w, $h);
                    $x = (int) floor(($w - $side) / 2);
                    $y = (int) floor(($h - $side) / 2);
                    $im->cropImage($side, $side, $x, $y);
                    $im->setImagePage(0, 0, 0, 0); // reset virtual canvas

                    // ---- resize to target square ----
                    if ($side !== $maxH_px) {
                        $im->resizeImage($maxH_px, $maxH_px, Imagick::FILTER_LANCZOS, 1, true);
                    }

                    // ---- rounded mask ----
                    $w = $im->getImageWidth();
                    $h = $im->getImageHeight();
                    $r = max(2, min($radius, intdiv(min($w, $h), 2)));

                    $mask = new Imagick();
                    $mask->newImage($w, $h, 'transparent', 'png');
                    $draw = new ImagickDraw();
                    $draw->setFillColor('white');
                    $draw->roundRectangle(0, 0, $w - 1, $h - 1, $r, $r);
                    $mask->drawImage($draw);

                    $im->setImageFormat('png');
                    $im->compositeImage($mask, Imagick::COMPOSITE_DSTIN, 0, 0);

                    $im->writeImage($dest);
                    $im->clear();
                    $im->destroy();
                    $mask->clear();
                    $mask->destroy();

                    return $dest;
                } catch (Throwable $e) {
                    // fall through to GD
                }
            }

            // ---- GD fallback ----
            $ext = strtolower(pathinfo($src, PATHINFO_EXTENSION));
            if ($ext === 'png') $srcIm = @imagecreatefrompng($src);
            else $srcIm = @imagecreatefromjpeg($src);
            if (!$srcIm) return $src;

            $sw = imagesx($srcIm);
            $sh = imagesy($srcIm);
            $side = min($sw, $sh);
            $srcX = (int) floor(($sw - $side) / 2);
            $srcY = (int) floor(($sh - $side) / 2);

            // square crop
            $squareIm = imagecreatetruecolor($side, $side);
            imagecopy($squareIm, $srcIm, 0, 0, $srcX, $srcY, $side, $side);
            imagedestroy($srcIm);

            // resize to target square
            $tw = $maxH_px;
            $th = $maxH_px;
            $im = imagecreatetruecolor($tw, $th);
            imagealphablending($im, false);
            imagesavealpha($im, true);
            $transparent = imagecolorallocatealpha($im, 0, 0, 0, 127);
            imagefill($im, 0, 0, $transparent);
            imagecopyresampled($im, $squareIm, 0, 0, 0, 0, $tw, $th, $side, $side);
            imagedestroy($squareIm);

            // rounded mask
            $mask = imagecreatetruecolor($tw, $th);
            imagealphablending($mask, false);
            imagesavealpha($mask, true);
            imagefill($mask, 0, 0, $transparent);
            $white = imagecolorallocatealpha($mask, 255, 255, 255, 0);
            enrep_gd_rounded_rect($mask, 0, 0, $tw - 1, $th - 1, min($radius, intdiv(min($tw, $th), 2)), $white);

            // apply mask (outside -> transparent)
            for ($y = 0; $y < $th; $y++) {
                for ($x = 0; $x < $tw; $x++) {
                    $m = imagecolorsforindex($mask, imagecolorat($mask, $x, $y));
                    if ($m['alpha'] >= 100) {
                        imagesetpixel($im, $x, $y, $transparent);
                    }
                }
            }
            imagedestroy($mask);

            imagepng($im, $dest, 6);
            imagedestroy($im);

            return $dest;
        }


        function enrep_gd_rounded_rect($img, $x1, $y1, $x2, $y2, $radius, $color)
        {
            $w = $x2 - $x1 + 1;
            $h = $y2 - $y1 + 1;
            $r = max(0, min($radius, min($w, $h) >> 1));
            imagefilledrectangle($img, $x1 + $r, $y1, $x2 - $r, $y2, $color);
            imagefilledrectangle($img, $x1, $y1 + $r, $x2, $y2 - $r, $color);
            imagefilledellipse($img, $x1 + $r, $y1 + $r, 2 * $r, 2 * $r, $color);
            imagefilledellipse($img, $x2 - $r, $y1 + $r, 2 * $r, 2 * $r, $color);
            imagefilledellipse($img, $x1 + $r, $y2 - $r, 2 * $r, 2 * $r, $color);
            imagefilledellipse($img, $x2 - $r, $y2 - $r, 2 * $r, 2 * $r, $color);
        }
    }

    // px per mm (approx mPDF CSS pixel ratio)
    $pxPerMm = 96 / 25.4; // ≈ 3.7795
    $maxH_px = (int)round($maxH_mm * $pxPerMm);

    // Process + cache to display paths
    $displayPaths = [];
    foreach ($imagePaths as $p) {
        $displayPaths[] = enrep_process_photo_fast($p, 24, $maxH_px); // radius 24, target height in px
    }

    // Render
    $body .= '<div style="page-break-before: always;"></div>';
    if ($imgCount === 1) {
        $body .= '
            <table width="100%" cellspacing="0" cellpadding="0" style="table-layout:fixed;border-collapse:collapse;page-break-inside:avoid;">
                <tr>
                    <td align="center" style="padding:5mm;">
                       <img src="' . $displayPaths[0] . '" style="max-width:180mm; max-height:' . $maxH_mm . 'mm;">
                    </td>
                </tr>
            </table>';
    } else {
        $body .= '<table width="100%" cellspacing="0" cellpadding="0" style="table-layout:fixed;border-collapse:separate;border-spacing:4mm;page-break-inside:avoid;">';
        for ($i = 0; $i < $imgCount; $i++) {
            if ($i % $cols === 0) $body .= '<tr style="page-break-inside:avoid;">';
            $body .= '
                <td align="center" style="width:' . $cellWidth . '%;vertical-align:top;padding:0;page-break-inside:avoid;">
                    <img src="' . $displayPaths[$i] . '" style="width:100%; height:auto; max-height:' . $maxH_mm . 'mm;">
                </td>';
            if (($i % $cols === $cols - 1) || ($i === $imgCount - 1)) {
                $remaining = ($cols - 1) - ($i % $cols);
                if ($i === $imgCount - 1 && $remaining > 0) {
                    for ($f = 0; $f < $remaining; $f++) {
                        $body .= '<td style="width:' . $cellWidth . '%">&nbsp;</td>';
                    }
                }
                $body .= '</tr>';
            }
        }
        $body .= '</table>';
    }
}

$body .= ($parts['wrapper_End'] ?? '');

// Common replacements (apply to header, footer, and body)
$repl = [
    '[SURVEYOR_NAME]'      => $sdata[0] ?? '',
    '[SURVEYOR_QUAL]'      => $sdata[1] ?? '',
    '[SURVEYOR_SIGNITURE]' => $base64ImageSrc,
    '[GARY_QUAL]'          => 'IEng MSOE MIPlantE MBES',
    '[GARY_SIGNITURE]'     => '2',
    '[REPNO]'              => $rdata[0] ?? '',
    '[EXAM_DATE]'          => $rdata[1] ?? '',
    '[EXAM_PREVDATE]'      => $rdata[2] ?? '',
    '[EXAM_NEXTDATE]'      => $rdata[3] ?? '',
    '[REPORT_DATE]'        => date('d-m-Y'),
    '[REP]'                => $_REQUEST['repnumber'] ?? '',
    '[ITE]'                => $cx['itemnumber'] ?? '',
    '[ADDRESS]'            => getCompanyDetails('addressLong'),
    '[CONTACT]'            => getCompanyDetails('contact'),
    '[TEL]'                => getCompanyDetails('tel'),
    '[REPORT_PATH]'        => getCompanyDetails('web'),
    '[QR]'                 => '<td><img src="' . $qrPath . '" height="40px"></td>',
];

// Logos
$repl['[LGO]'] = file_exists($tenantBase . '/images/company/logo.jpg')
    ? '<img src="' . $tenantBase . '/images/company/logo.jpg" height="70px" />'
    : '';
$clientLogo = $tenantBase . '/images/client/' . ($_REQUEST['clientnumber'] ?? '') . '.jpg';
$repl['[CL1]'] = file_exists($clientLogo) ? '<td align="center"><img src="' . $clientLogo . '" height="70px" /></td>' : '';



// Apply replacements to all pieces
$header = str_replace(array_keys($repl), array_values($repl), $header);
$footer = str_replace(array_keys($repl), array_values($repl), $footer);
$body   = str_replace(array_keys($repl), array_values($repl), $body);



// ---------- FILE DEST ----------
if (($_REQUEST['mode'] ?? '') === "preview") {
    $filestore = $tenantBase . '/output/reports/' . ($_REQUEST['clientnumber'] ?? '') . '/preview.pdf';
} else {
    if (($_REQUEST['mode'] ?? '') === "hse") {
        $filestore = $tenantBase . '/output/reports/' . ($_REQUEST['clientnumber'] ?? '') . '/' . ($_REQUEST['repnumber'] ?? '') . '_' . ($_REQUEST['items'] ?? '') . '_HSE.pdf';
    } else {
        $filestore = $tenantBase . '/output/reports/' . ($_REQUEST['clientnumber'] ?? '') . '/' . ($_REQUEST['repnumber'] ?? '') . '_' . ($_REQUEST['items'] ?? '') . '.pdf';
    }
}

// ---------- mPDF ----------
require_once '../../packages/mpd/vendor/autoload.php';
$orientation = $parts['orientation'] ?? 'P';

$mpdf = new \Mpdf\Mpdf([
    'mode' => 'utf-8',
    'format' => 'A4',
    'orientation' => $orientation,
    'margin_top' => 30,
    'margin_left' => 10,
    'margin_right' => 10,
    'margin_bottom' => 6,
    'setAutoTopMargin' => 'stretch',   // <-- ensure header (with extras) doesn’t squash content
    'setAutoBottomMargin' => 'stretch',
]);

$mpdf->shrink_tables_to_fit = 1;

// Load CSS so it applies to header/footer AND body
if (!empty($styleHtml)) {
    $mpdf->WriteHTML($styleHtml, \Mpdf\HTMLParserMode::HEADER_CSS);
}

// Encode & set header/footer for odd+even
$header = mb_convert_encoding($header, 'UTF-8', 'UTF-8');
$footer = mb_convert_encoding($footer, 'UTF-8', 'UTF-8');
$mpdf->SetHTMLHeader($header, 'O');
$mpdf->SetHTMLHeader($header, 'E');
$mpdf->SetHTMLFooter($footer, 'O');
$mpdf->SetHTMLFooter($footer, 'E');

// Write body
$body = mb_convert_encoding($body, 'UTF-8', 'UTF-8');
$mpdf->WriteHTML($body);

// Output
$mpdf->Output($filestore);