<?php

declare (strict_types = 1);
namespace Brightfern\WooCommerce;

use WC_Order;
use WC_Order_Refund;
/**
 * Order-edit metabox showing the e-invoice status, number, the pre-flight gate
 * findings, and actions: download the generated XML (free) and resend (premium).
 * Registered for BOTH the HPOS orders screen and the legacy post screen.
 */
final class OrderMetabox {
    public function register() : void {
        add_action( 'add_meta_boxes', array($this, 'addBox') );
        add_action( 'admin_post_brightfern_download_xml', array($this, 'downloadXml') );
        add_action( 'admin_post_brightfern_download_creditnote_xml', array($this, 'downloadCreditNoteXml') );
    }

    public function addBox() : void {
        $screen = ( function_exists( 'wc_get_page_screen_id' ) ? wc_get_page_screen_id( 'shop-order' ) : 'shop_order' );
        foreach ( array_unique( array($screen, 'shop_order') ) as $scr ) {
            add_meta_box(
                'brightfern_einvoice',
                __( 'E-Invoice (Brightfern)', 'brightfern-e-invoicing-for-woocommerce' ),
                array($this, 'render'),
                $scr,
                'side',
                'default'
            );
        }
    }

    /** @param mixed $post_or_order */
    public function render( $post_or_order ) : void {
        $order = ( $post_or_order instanceof WC_Order ? $post_or_order : wc_get_order( ( is_object( $post_or_order ) ? $post_or_order->ID : 0 ) ) );
        if ( !$order instanceof WC_Order ) {
            return;
        }
        $status = (string) $order->get_meta( OutboundFlow::META_STATUS );
        $number = (string) $order->get_meta( OutboundFlow::META_NUMBER );
        $issues = json_decode( (string) $order->get_meta( OutboundFlow::META_ISSUES ), true );
        $issues = ( is_array( $issues ) ? $issues : array() );
        if ( '' === $status ) {
            echo '<p>' . esc_html__( 'No e-invoice generated yet for this order.', 'brightfern-e-invoicing-for-woocommerce' ) . '</p>';
        } else {
            echo '<p><strong>' . esc_html__( 'Status:', 'brightfern-e-invoicing-for-woocommerce' ) . '</strong> <code>' . esc_html( $status ) . '</code></p>';
            if ( '' !== $number ) {
                echo '<p><strong>' . esc_html__( 'Invoice #:', 'brightfern-e-invoicing-for-woocommerce' ) . '</strong> ' . esc_html( $number ) . '</p>';
            }
            if ( !empty( $issues ) ) {
                echo '<details><summary>' . esc_html__( 'Validation findings', 'brightfern-e-invoicing-for-woocommerce' ) . '</summary><ul style="margin-left:1em;list-style:disc;">';
                foreach ( $issues as $issue ) {
                    echo '<li>' . esc_html( (string) $issue ) . '</li>';
                }
                echo '</ul></details>';
            }
        }
        $hasPdf = '' !== (string) $order->get_meta( OutboundFlow::META_PDF );
        $hasXml = '' !== (string) $order->get_meta( OutboundFlow::META_XML );
        if ( $hasPdf || $hasXml ) {
            $download = wp_nonce_url( admin_url( 'admin-post.php?action=brightfern_download_xml&order_id=' . $order->get_id() ), 'brightfern_download_' . $order->get_id() );
            $label = ( $hasPdf ? __( 'Download Factur-X PDF', 'brightfern-e-invoicing-for-woocommerce' ) : __( 'Download XML', 'brightfern-e-invoicing-for-woocommerce' ) );
            echo '<p><a class="button" href="' . esc_url( $download ) . '">' . esc_html( $label ) . '</a></p>';
        }
        // Upsell copy is not gated functionality, so a plain runtime check is fine.
        if ( !brightfern_is_pro() ) {
            echo '<p><em>' . esc_html__( 'Upgrade to Pro to transmit and resend over the network.', 'brightfern-e-invoicing-for-woocommerce' ) . '</em></p>';
        }
        $this->renderCreditNotes( $order );
    }

    /** Lists any credit notes issued for this order's refunds, each with its own download link. */
    private function renderCreditNotes( WC_Order $order ) : void {
        $refunds = $order->get_refunds();
        if ( empty( $refunds ) ) {
            return;
        }
        $rows = array();
        foreach ( $refunds as $refund ) {
            $status = (string) $refund->get_meta( OutboundFlow::META_STATUS );
            if ( '' === $status ) {
                continue;
                // Refund with no brightfern credit note (e.g. order never had an invoice).
            }
            $rows[] = $refund;
        }
        if ( empty( $rows ) ) {
            return;
        }
        echo '<hr /><p><strong>' . esc_html__( 'Credit notes', 'brightfern-e-invoicing-for-woocommerce' ) . '</strong></p>';
        foreach ( $rows as $refund ) {
            $status = (string) $refund->get_meta( OutboundFlow::META_STATUS );
            $number = (string) $refund->get_meta( OutboundFlow::META_NUMBER );
            echo '<p><code>' . esc_html( $status ) . '</code>';
            if ( '' !== $number ) {
                echo ' ' . esc_html( $number );
            }
            if ( '' !== (string) $refund->get_meta( OutboundFlow::META_PDF ) || '' !== (string) $refund->get_meta( OutboundFlow::META_XML ) ) {
                $download = wp_nonce_url( admin_url( 'admin-post.php?action=brightfern_download_creditnote_xml&refund_id=' . $refund->get_id() ), 'brightfern_download_cn_' . $refund->get_id() );
                echo ' — <a href="' . esc_url( $download ) . '">' . esc_html__( 'Download', 'brightfern-e-invoicing-for-woocommerce' ) . '</a>';
            }
            echo '</p>';
        }
    }

    public function downloadXml() : void {
        $orderId = ( isset( $_GET['order_id'] ) ? absint( wp_unslash( $_GET['order_id'] ) ) : 0 );
        check_admin_referer( 'brightfern_download_' . $orderId );
        if ( !current_user_can( 'manage_woocommerce' ) ) {
            wp_die( esc_html__( 'Insufficient permissions.', 'brightfern-e-invoicing-for-woocommerce' ) );
        }
        $order = wc_get_order( $orderId );
        if ( !$order instanceof WC_Order ) {
            wp_die( esc_html__( 'Order not found.', 'brightfern-e-invoicing-for-woocommerce' ) );
        }
        $number = (string) $order->get_meta( OutboundFlow::META_NUMBER );
        $pdfBase64 = (string) $order->get_meta( OutboundFlow::META_PDF );
        if ( '' !== $pdfBase64 ) {
            $this->outputPdf( $pdfBase64, 'invoice-' . sanitize_file_name( ( '' !== $number ? $number : (string) $orderId ) ) . '.pdf' );
        }
        $xml = (string) $order->get_meta( OutboundFlow::META_XML );
        if ( '' === $xml ) {
            wp_die( esc_html__( 'No e-invoice XML stored for this order.', 'brightfern-e-invoicing-for-woocommerce' ) );
        }
        $this->outputXml( $xml, 'invoice-' . sanitize_file_name( ( '' !== $number ? $number : (string) $orderId ) ) . '.xml' );
    }

    public function downloadCreditNoteXml() : void {
        $refundId = ( isset( $_GET['refund_id'] ) ? absint( wp_unslash( $_GET['refund_id'] ) ) : 0 );
        check_admin_referer( 'brightfern_download_cn_' . $refundId );
        if ( !current_user_can( 'manage_woocommerce' ) ) {
            wp_die( esc_html__( 'Insufficient permissions.', 'brightfern-e-invoicing-for-woocommerce' ) );
        }
        $refund = wc_get_order( $refundId );
        if ( !$refund instanceof WC_Order_Refund ) {
            wp_die( esc_html__( 'Credit note not found.', 'brightfern-e-invoicing-for-woocommerce' ) );
        }
        $number = (string) $refund->get_meta( OutboundFlow::META_NUMBER );
        $pdfBase64 = (string) $refund->get_meta( OutboundFlow::META_PDF );
        if ( '' !== $pdfBase64 ) {
            $this->outputPdf( $pdfBase64, 'creditnote-' . sanitize_file_name( ( '' !== $number ? $number : (string) $refundId ) ) . '.pdf' );
        }
        $xml = (string) $refund->get_meta( OutboundFlow::META_XML );
        if ( '' === $xml ) {
            wp_die( esc_html__( 'No credit note XML stored for this refund.', 'brightfern-e-invoicing-for-woocommerce' ) );
        }
        $this->outputXml( $xml, 'creditnote-' . sanitize_file_name( ( '' !== $number ? $number : (string) $refundId ) ) . '.xml' );
    }

    /** Raw XML download: escaping would corrupt the document; Content-Type/Disposition below mean it's never rendered as HTML. */
    private function outputXml( string $xml, string $filename ) : void {
        header( 'Content-Type: application/xml; charset=utf-8' );
        header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
        echo $xml;
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- XML file download, must not be escaped.
        exit;
    }

    /** Factur-X PDF/A-3 download — stored base64-encoded in postmeta (text-oriented storage). */
    private function outputPdf( string $base64, string $filename ) : void {
        $pdf = base64_decode( $base64, true );
        if ( false === $pdf ) {
            wp_die( esc_html__( 'Stored Factur-X PDF is corrupt.', 'brightfern-e-invoicing-for-woocommerce' ) );
        }
        header( 'Content-Type: application/pdf' );
        header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
        header( 'Content-Length: ' . strlen( $pdf ) );
        echo $pdf;
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- binary PDF download, must not be escaped.
        exit;
    }

}
