<?php
// functions/pdf_rasterise.php
header('Content-Type: application/json');

function fail($msg, $code=400){ http_response_code($code); echo json_encode(['error'=>$msg]); exit; }
function ok($data){ http_response_code(200); echo json_encode($data); exit; }

$tenant = $_REQUEST['tenant'] ?? '';
$pdfUrl = $_REQUEST['pdf'] ?? '';
if ($tenant === '') fail('Missing tenant');
if ($pdfUrl === '') fail('Missing pdf');

// Normalise input path and strip query
$pathOnly = parse_url($pdfUrl, PHP_URL_PATH) ?: $pdfUrl;
if (!preg_match('~\.pdf$~i', $pathOnly)) fail('Not a .pdf');

// Security
if (strpos($pathOnly, '..') !== false) fail('Invalid path');

// Tenant root (filesystem). Adjust only if your structure differs.
$tenantWebPath = '../../' . $tenant;   // web-style path piece used by your stack
$tenantFsRoot  = $tenantWebPath;
if (!is_dir($tenantFsRoot)) fail('Tenant not found');

// Map requested PDF to filesystem
if (strpos($pathOnly, $tenantWebPath . '/') === 0) {
    $rel = substr($pathOnly, strlen($tenantWebPath) + 1); // drop "/{tenant}/"
} else {
    $rel = ltrim($pathOnly, '/');
}

$pdfFsReal = $tenantFsRoot . '/' . $rel;

// Ensure stays within tenant root
if (strpos(realpath(dirname($pdfFsReal)) ?: '', realpath($tenantFsRoot) ?: '') !== 0) {
    fail('Path escapes tenant root');
}

if (!file_exists($pdfFsReal)) fail('PDF not found: ' . $pdfFsReal);
if (!is_readable($pdfFsReal)) fail('PDF not readable');

$pdfMTime = @filemtime($pdfFsReal) ?: time();

// Cache dir in tenant: "/{tenant}/output/pdf_cache/{hash}/"
$hash = sha1($tenant . '|' . $rel);
$cacheRel = 'output/pdf_cache/' . $hash;
$cacheFs  = $tenantFsRoot . '/' . $cacheRel;
$cacheWeb = $tenantWebPath . '/' . $cacheRel;
if (!is_dir($cacheFs) && !@mkdir($cacheFs, 0775, true)) fail('Cannot create cache dir');

// Check existing cache
clearstatcache(true);
$existing = glob($cacheFs . '/page-*.jpg') ?: [];

// Invalidate if any cached page older than source PDF
$stale = false;
if ($existing) {
    foreach ($existing as $f) {
        $mt = @filemtime($f) ?: 0;
        if ($mt < $pdfMTime) { $stale = true; break; }
    }
    if ($stale) {
        foreach ($existing as $f) { @unlink($f); }
        $existing = [];
    }
}

if (!$existing) {
    if (!class_exists('Imagick')) {
        fail('Rasterisation unavailable: Imagick not installed.');
    }

    try {
        $im = new Imagick();
        $im->setResolution(144, 144);
        $im->setBackgroundColor(new ImagickPixel('white'));

        // Load all pages
        $im->readImage($pdfFsReal);
        if ($im->getNumberImages() < 1) {
            $im->clear(); $im->destroy();
            $im = new Imagick();
            $im->setResolution(144, 144);
            $im->setBackgroundColor(new ImagickPixel('white'));
            $im->readImage('pdf:' . $pdfFsReal);
        }

        if ($im->getNumberImages() < 1) {
            fail('Imagick error: no pages loaded (check Ghostscript delegate)');
        }

        $i = 0;
        foreach ($im as $page) {
            $i++;
            $page->setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE);
            $page->mergeImageLayers(Imagick::LAYERMETHOD_FLATTEN);
            $page->setImageFormat('jpeg');
            $page->setImageCompression(Imagick::COMPRESSION_JPEG);
            $page->setImageCompressionQuality(85);
            $fname = sprintf('%s/page-%03d.jpg', $cacheFs, $i);
            $page->writeImage($fname);
            @touch($fname, $pdfMTime); // stamp to source mtime for stable cache-busting
            @chmod($fname, 0644);
            $page->clear();
            $page->destroy();
        }
        $im->clear(); $im->destroy();

        clearstatcache(true);
        $existing = glob($cacheFs . '/page-*.jpg') ?: [];
        if (!$existing) fail('Imagick produced no pages');
    } catch (Throwable $e) {
        fail('Imagick error: '.$e->getMessage());
    }

    // small settle window
    if (!$existing) {
        for ($j=0; $j<10; $j++) {
            usleep(100000);
            clearstatcache(true);
            $existing = glob($cacheFs . '/page-*.jpg') ?: [];
            if ($existing) break;
        }
    }
}

natcasesort($existing);
$pages = [];
foreach ($existing as $f) {
    $pages[] = $cacheRel . '/' . basename($f) . '?v=' . $pdfMTime; // add cache-buster for browser freshness
}

$filename = basename($pathOnly);

// Download URL: tenant-relative original with cache-buster
$downloadRel = $rel . '?v=' . $pdfMTime;

ok([
    'pageCount'   => count($pages),
    'pages'       => array_values($pages),
    'downloadUrl' => $downloadRel,
    'filename'    => $filename ?: 'document.pdf'
]);