<?php
/**
 * SEPA EPC QR code generator (European Payments Council Standard 069).
 *
 * Produces a payload that, when scanned with a SEPA-compatible mobile banking app,
 * pre-fills a wire transfer with the seller's IBAN, the invoice amount, and the
 * invoice number as remittance information.
 *
 * Reference: https://www.europeanpaymentscouncil.eu/document-library/guidance-documents/quick-response-code-guidelines-enable-data-capture-initiation
 *
 * @package FacturX_For_WooCommerce
 */

defined( 'ABSPATH' ) || exit;

use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\Writer\PngWriter;

class GOFACTOX_Sepa_QR {

    /**
     * Build the EPC QR payload for an invoice.
     *
     * @param array $invoice Invoice data from GOFACTOX_Invoice::get_invoice_data().
     * @return string The newline-separated EPC payload, or '' if seller has no IBAN.
     */
    public static function build_payload( array $invoice ): string {
        $seller = $invoice['seller'] ?? [];
        $iban   = preg_replace( '/\s+/', '', (string) ( $seller['iban'] ?? '' ) );
        if ( $iban === '' ) {
            return '';
        }

        // EPC SEPA QR only supports EUR (SEPA = Single Euro Payments Area).
        // Skipping for non-EUR invoices avoids misleading customers with a QR that
        // would pre-fill a wire transfer in the wrong currency.
        $currency = strtoupper( (string) ( $invoice['currency'] ?? 'EUR' ) );
        if ( $currency !== 'EUR' ) {
            return '';
        }

        $bic    = preg_replace( '/\s+/', '', (string) ( $seller['bic'] ?? '' ) );
        $name   = mb_substr( (string) ( $seller['company_name'] ?? '' ), 0, 70 );
        $amount = number_format( (float) ( $invoice['total_ttc'] ?? 0 ), 2, '.', '' );
        $ref    = mb_substr( (string) ( $invoice['invoice_number'] ?? '' ), 0, 35 );

        // EPC payload structure (one line per element):
        //  1. Service tag
        //  2. Version (002 = with BIC optional)
        //  3. Character set (1 = UTF-8)
        //  4. Function (SCT = SEPA Credit Transfer)
        //  5. BIC (optional)
        //  6. Beneficiary name (max 70 chars)
        //  7. Beneficiary IBAN
        //  8. Amount in EUR (EUR<amount> with dot decimal)
        //  9. Purpose code (optional, 4 chars max)
        // 10. Structured reference or Remittance info (unstructured, max 35/140)
        // 11. Originator info (optional)
        $lines = [
            'BCD',
            '002',
            '1',
            'SCT',
            $bic,
            $name,
            $iban,
            'EUR' . $amount,
            '',
            $ref,
            '',
        ];

        return implode( "\n", $lines );
    }

    /**
     * Generate the QR code PNG and return its absolute filesystem path.
     *
     * Caches the file under uploads/wfx-invoices/qr/<hash>.png so the same payload
     * isn't re-encoded for every regeneration.
     *
     * @return string Path to the PNG file, or '' on failure.
     */
    public static function generate_png( array $invoice ): string {
        // QR SEPA is a Pro feature: industry standard (WPOvernight, WebToffee gate it).
        if ( ! class_exists( 'GOFACTOX_License' ) || ! GOFACTOX_License::is_pro() ) {
            return '';
        }

        $payload = self::build_payload( $invoice );
        if ( $payload === '' ) {
            return '';
        }

        // Endroid is loaded via the plugin's vendor autoloader.
        if ( ! class_exists( Builder::class ) ) {
            return '';
        }

        $upload_dir = wp_upload_dir();
        $dir        = $upload_dir['basedir'] . '/wfx-invoices/qr';
        wp_mkdir_p( $dir );

        $hash = substr( hash( 'sha256', $payload ), 0, 16 );
        $path = $dir . '/' . $hash . '.png';

        if ( file_exists( $path ) ) {
            return $path;
        }

        try {
            $result = Builder::create()
                ->writer( new PngWriter() )
                ->data( $payload )
                ->encoding( new Encoding( 'UTF-8' ) )
                ->size( 220 )
                ->margin( 8 )
                ->build();
            file_put_contents( $path, $result->getString() );
            return file_exists( $path ) ? $path : '';
        } catch ( \Throwable $e ) {
            if ( function_exists( 'wc_get_logger' ) ) {
                wc_get_logger()->warning( 'SEPA QR generation failed: ' . $e->getMessage(), [ 'source' => 'gofactox-e-invoicing-for-woocommerce' ] );
            }
            return '';
        }
    }
}
