<?php
/**
 * PDF Generator — Renders the HTML template to PDF via bundled Dompdf.
 *
 * Uses the same HTML that the template preview renders, so the PDF is
 * pixel-for-pixel identical to the on-screen preview.
 * Dompdf (zero server setup, pure PHP) is bundled in lib/dompdf/.
 *
 * @package PB_Invoicing_System
 */

if ( ! defined( 'ABSPATH' ) ) exit;

/* ══════════════════════════════════════════════════════════════════
   Singleton wrapper — maintains the existing PBUAIV_Document interface
   ══════════════════════════════════════════════════════════════════ */
class PBUAIV_PDF_Generator {

    private static ?PBUAIV_PDF_Generator $instance = null;

    public static function instance(): self {
        if ( null === self::$instance ) self::$instance = new self();
        return self::$instance;
    }

    private function __construct() {}

    /**
     * Generate raw PDF bytes from the rendered HTML template.
     *
     * @param  string $html  Rendered HTML from PBUAIV_Document::get_html()
     * @param  array  $data  Compiled document data (used only for paper size option)
     * @return string        Raw PDF bytes
     */
    public function generate( string $html, array $data = [] ): string {
        // Load Dompdf autoloader (vendor/ is bundled in the plugin)
        $autoload = PBUAIV_PLUGIN_DIR . 'lib/dompdf/dompdf/autoload.inc.php';
        if ( ! file_exists( $autoload ) ) {
            return '';
        }
        require_once $autoload;

        // Point font cache to WP uploads dir (always writable)
        $upload   = wp_upload_dir();
        $font_dir = trailingslashit( $upload['basedir'] ) . 'pbuaiv-fonts/';
        wp_mkdir_p( $font_dir );

        $options = new \Dompdf\Options();
        $options->setIsRemoteEnabled( true );       // fetch logo & QR images
        $options->setIsHtml5ParserEnabled( true );  // better HTML5 support
        $options->setDefaultFont( 'helvetica' );
        $options->setFontDir( $font_dir );
        $options->setFontCache( $font_dir );
        // Allow loading files from WP uploads (for locally cached images)
        $options->setChroot( [ ABSPATH, $upload['basedir'] ] );
        $options->setIsPhpEnabled( false );         // security: no PHP in HTML
        $options->setDpi( 96 );

        $dompdf = new \Dompdf\Dompdf( $options );

        // Inject PDF-specific CSS overrides before closing </head>.
        // The on-screen template is designed as a 794px A4 canvas. Dompdf maps
        // CSS pixels to PDF points, so keeping that same canvas and padding is
        // much closer to the preview than stretching everything to 100% width.
        $pdf_css = '<' . 'style>
            @page { size: A4 portrait; margin: 10mm; }
            html, body { margin: 0; padding: 0; background: #fff; }
            body { font-family: helvetica, sans-serif; font-size: 10.5px; color: #1e293b; -webkit-print-color-adjust: exact; print-color-adjust: exact; }
            * { box-sizing: border-box; }

            .inv-page {
                width: 190mm !important;
                max-width: 190mm !important;
                min-height: 277mm !important;
                margin: 0 auto !important;
                padding: 8mm 0 0 !important;
                overflow: hidden !important;
                position: relative !important;
            }

            .inv-header {
                display: table !important;
                width: 100% !important;
                table-layout: fixed !important;
                margin-bottom: 9mm !important;
                padding-bottom: 5mm !important;
                border-bottom-width: 1.1mm !important;
            }
            .inv-logo { display: table-cell !important; width: 48% !important; vertical-align: top !important; }
            .inv-logo img { max-height: 18mm !important; max-width: 55mm !important; }
            .inv-doc-title { display: table-cell !important; width: 52% !important; vertical-align: top !important; text-align: right !important; }
            .inv-doc-title h1 { font-size: 20px !important; line-height: 1.1 !important; }
            .inv-doc-title .inv-type-badge { font-size: 8.5px !important; padding: 1.5px 7px !important; }
            .inv-doc-title .inv-number { font-size: 12px !important; }
            .inv-doc-title .inv-date { font-size: 9.5px !important; }

            .inv-accent-band {
                display: table !important;
                width: 190mm !important;
                table-layout: fixed !important;
                margin: 0 !important;
                padding: 3mm 4mm !important;
                font-size: 9.5px !important;
            }
            .inv-accent-band span { display: table-cell !important; width: 33.333% !important; text-align: center !important; }
            .inv-accent-band span:first-child { text-align: left !important; }
            .inv-accent-band span:last-child { text-align: right !important; }
            .inv-accent-band strong { font-size: 10px !important; }

            .inv-parties {
                display: table !important;
                width: 100% !important;
                table-layout: fixed !important;
                border-collapse: collapse !important;
                border-spacing: 0 !important;
                margin: 7mm 0 !important;
            }
            .inv-party { display: table-cell !important; width: 50% !important; vertical-align: top !important; }
            .inv-party:first-child { padding-right: 7mm !important; }
            .inv-party:last-child { padding-left: 7mm !important; }
            .inv-party__title { font-size: 8.5px !important; padding-bottom: 2.5px !important; margin-bottom: 5px !important; }
            .inv-party__name { font-size: 11.5px !important; margin-bottom: 3px !important; }
            .inv-party__line, .inv-party__trn { font-size: 9.5px !important; }
            .inv-party__trn { padding: 3px 7px !important; margin-top: 4px !important; }

            .inv-items { width: 100% !important; table-layout: fixed !important; border-collapse: collapse !important; margin: 6mm 0 !important; font-size: 9.3px !important; }
            .inv-items th { padding: 6px 5px !important; font-size: 8.2px !important; }
            .inv-items td { padding: 6px 5px !important; }
            .inv-items th, .inv-items td { word-wrap: break-word !important; overflow-wrap: break-word !important; }
            .inv-items .col-num    { width: 5% !important; }
            .inv-items .col-desc   { width: 36% !important; }
            .inv-items .col-qty    { width: 7% !important; }
            .inv-items .col-price  { width: 14% !important; }
            .inv-items .col-vat    { width: 8% !important; }
            .inv-items .col-vatamt { width: 14% !important; }
            .inv-items .col-total  { width: 16% !important; }

            .inv-totals { display: block !important; width: 100% !important; text-align: right !important; margin: 0 0 7mm !important; }
            .inv-totals table { width: 74mm !important; margin-left: auto !important; border-collapse: collapse !important; }
            .inv-totals td { padding: 4px 8px !important; font-size: 10.5px !important; }
            .inv-totals .total-row td { font-size: 12px !important; padding: 8px 10px !important; }

            .inv-vat-summary { padding: 8px 12px !important; margin-bottom: 7mm !important; font-size: 9.5px !important; }
            .inv-vat-summary table { font-size: 9.5px !important; }
            .inv-vat-aed { font-size: 12px !important; }

            .inv-footer {
                display: table !important;
                width: 100% !important;
                table-layout: fixed !important;
                border-top-width: 0.6mm !important;
                padding-top: 5mm !important;
                margin-top: 0 !important;
                page-break-inside: avoid !important;
            }
            .inv-notes { display: table-cell !important; width: 72% !important; vertical-align: bottom !important; font-size: 9px !important; color: #64748b !important; }
            .inv-qr { display: table-cell !important; width: 28% !important; vertical-align: bottom !important; text-align: right !important; }
            .inv-qr-placeholder { width: 26mm !important; height: 26mm !important; margin-left: auto !important; border: 0 !important; display: block !important; }
            .inv-qr-placeholder img { width: 26mm !important; height: 26mm !important; display: block !important; }
            .inv-fta-label { font-size: 8px !important; text-align: right !important; }

            .inv-page > div:last-child { margin-top: 6mm !important; font-size: 8px !important; text-align: center !important; color: #cbd5e1 !important; }
            .inv-watermark { display: none !important; }
            .no-print { display: none !important; }
        </' . 'style>';
        $html = str_replace( '</head>', $pdf_css . '</head>', $html );

        $dompdf->loadHtml( $html, 'UTF-8' );

        $paper = strtolower( get_option( 'pbuaiv_paper_size', 'A4' ) );
        $dompdf->setPaper( $paper, 'portrait' );

        $dompdf->render();
        $output = $dompdf->output();

        // Release Dompdf's large render tree before WooCommerce continues with
        // the rest of the status-change and email request.
        unset( $dompdf, $options );
        if ( function_exists( 'gc_collect_cycles' ) ) {
            gc_collect_cycles();
        }

        return $output;
    }

}
