<?php

declare(strict_types=1);

namespace App\Service;

class PdfCompressorService
{
    public function compressBase64Pdf(string $base64Data): ?array
    {
        // Check if qpdf is available
        exec('which qpdf', $qpdfPath, $returnCode);
        if (0 !== $returnCode) {
            return null;
        }

        // Remove data URI prefix if present
        $originalBase64 = $base64Data;
        if (str_contains($base64Data, ',')) {
            $base64Data = explode(',', $base64Data, 2)[1];
        }

        $pdfContent = base64_decode($base64Data, true);
        if (false === $pdfContent) {
            return null;
        }

        $originalSize = strlen($pdfContent);

        // Create temp files
        $tempInput  = tempnam(sys_get_temp_dir(), 'pdf_in_');
        $tempOutput = tempnam(sys_get_temp_dir(), 'pdf_out_');

        file_put_contents($tempInput, $pdfContent);

        // Compress with qpdf (lossless)
        $command = sprintf(
            'qpdf --linearize --object-streams=generate %s %s 2>&1',
            escapeshellarg($tempInput),
            escapeshellarg($tempOutput)
        );

        exec($command, $cmdOutput, $returnCode);

        if (0 !== $returnCode || !file_exists($tempOutput)) {
            @unlink($tempInput);
            @unlink($tempOutput);

            return null;
        }

        $compressedContent = file_get_contents($tempOutput);
        $compressedSize    = strlen($compressedContent);

        @unlink($tempInput);
        @unlink($tempOutput);

        // Only return compressed version if it's smaller
        if ($compressedSize >= $originalSize) {
            return null;
        }

        // Rebuild with data URI prefix
        $newBase64 = 'data:application/pdf;base64,'.base64_encode($compressedContent);

        return [
            'path'         => $newBase64,
            'size'         => $compressedSize,
            'originalSize' => $originalSize,
            'saved'        => $originalSize - $compressedSize,
        ];
    }
}
