<?php
/**
 * Merge PDF + XML into PDF/A-3 Factur-X document.
 *
 * Uses horstoeko/zugferd ZugferdDocumentPdfMerger to:
 * - Convert PDF to PDF/A-3b
 * - Embed XML as "factur-x.xml" attachment
 * - Add Factur-X XMP metadata
 * - Embed ICC profile
 *
 * @package FacturX_For_WooCommerce
 */

defined( 'ABSPATH' ) || exit;

use horstoeko\zugferd\ZugferdDocumentPdfMerger;

class GOFACTOX_FacturX_Merger {

    /**
     * Merge a PDF and XML into a Factur-X PDF/A-3 document.
     *
     * @param string $pdf_path Path to the source PDF.
     * @param string $xml      The Factur-X XML content.
     * @param string $output_path Path for the output PDF/A-3 file.
     * @return bool True on success.
     * @throws \Exception On merge failure.
     */
    public static function merge( string $pdf_path, string $xml, string $output_path ): bool {
        if ( ! file_exists( $pdf_path ) ) {
            throw new \RuntimeException( 'Source PDF not found: ' . esc_html( $pdf_path ) );
        }

        $merger = new ZugferdDocumentPdfMerger( $xml, $pdf_path );
        $merger->generateDocument();
        $merger->saveDocument( $output_path );

        return file_exists( $output_path );
    }

    /**
     * Generate a complete Factur-X invoice or credit note (XML + PDF + merge).
     *
     * @param array               $data    Document data from GOFACTOX_Invoice::get_invoice_data() or get_credit_note_data().
     * @param \WC_Abstract_Order  $source  The WooCommerce order or refund the document is built from.
     * @return string Path to the final PDF/A-3 file.
     */
    public static function generate_invoice( array $data, \WC_Abstract_Order $source ): string {
        $format = get_option( 'gofactox_output_format', 'facturx' );

        // Step 1: Generate XML.
        $xml = GOFACTOX_XML_Generator::generate( $data, $format );

        // facturx + facturx-comfort produce a full PDF/A-3 with embedded XML.
        // cii / ubl skip PDF generation and only save the XML file.
        $is_pdf_format = in_array( $format, [ 'facturx', 'facturx-comfort' ], true );
        if ( ! $is_pdf_format ) {
            return GOFACTOX_XML_Generator::generate_to_file( $data, $format );
        }

        // Step 2: Generate PDF from template.
        $pdf_path = GOFACTOX_PDF_Generator::generate( $data );

        // Step 3: Merge into PDF/A-3.
        $output_path = self::get_output_path( $data );
        self::merge( $pdf_path, $xml, $output_path );

        // Clean up intermediate PDF.
        if ( file_exists( $pdf_path ) && $pdf_path !== $output_path ) {
            wp_delete_file( $pdf_path );
        }

        // Update the underlying CPT post (invoice or credit note) with the final file path.
        $is_credit_note = ! empty( $data['is_credit_note'] );
        $meta_key       = $is_credit_note ? '_gofactox_credit_note_id' : '_gofactox_invoice_id';
        $post_id        = (int) $source->get_meta( $meta_key );
        if ( $post_id ) {
            GOFACTOX_Invoice::set_pdf_path( $post_id, $output_path );
        }

        return $output_path;
    }

    /**
     * Get the output file path for the merged PDF.
     */
    private static function get_output_path( array $data ): string {
        $upload_dir = wp_upload_dir();
        $date       = $data['invoice_date'];
        $year       = substr( $date, 0, 4 );
        $month      = substr( $date, 5, 2 );
        $dir        = $upload_dir['basedir'] . '/wfx-invoices/' . $year . '/' . $month;

        wp_mkdir_p( $dir );

        // Add short hash to prevent URL enumeration.
        $hash     = substr( wp_hash( $data['invoice_number'] . $data['order_id'] ), 0, 8 );
        $filename = sanitize_file_name( $data['invoice_number'] ) . '-' . $hash . '.pdf';

        /**
         * Filter the final PDF filename (without the directory prefix).
         *
         * @param string $filename Default filename.
         * @param array  $data     Invoice/credit note data.
         */
        $filename = apply_filters( 'gofactox_pdf_filename', $filename, $data );

        return $dir . '/' . $filename;
    }
}
