<?php
if ( ! defined( 'ABSPATH' ) ) exit;

/**
 * Adds the UAE VAT Invoice metabox to the WooCommerce order edit page.
 * Works with both classic order edit (post.php) and HPOS order edit.
 */
class PBUAIV_Order_Metabox {

    private static ?PBUAIV_Order_Metabox $instance = null;

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

    private function __construct() {
        // Register metabox for both classic CPT (shop_order) and HPOS (woocommerce_page_wc-orders)
        add_action( 'add_meta_boxes', [ $this, 'register' ] );
        // Order billing TRN field
        add_action( 'woocommerce_admin_order_data_after_billing_address', [ $this, 'render_billing_trn' ] );
        add_action( 'woocommerce_process_shop_order_meta', [ $this, 'save_billing_trn' ] );
        // HPOS provides the order object before WooCommerce persists it. Updating
        // metadata here avoids recursively calling WC_Order::save() from the
        // woocommerce_update_order action.
        add_action( 'woocommerce_admin_process_shop_order_object', [ $this, 'save_billing_trn_hpos' ] );
    }

    public function register() : void {
        // Array of screens covers both classic and HPOS order edit pages
        add_meta_box(
            'pbuaiv-documents',
            __( '🇦🇪 UAE VAT Documents', 'pb-invoicing-system' ),
            [ $this, 'render' ],
            [ 'shop_order', 'woocommerce_page_wc-orders' ],
            'side',
            'high'
        );
    }

    // ── Render ────────────────────────────────────────────────────────────────

    public function render( $post_or_order ) : void {
        $order = $post_or_order instanceof WC_Order ? $post_or_order : wc_get_order( $post_or_order->ID );
        if ( ! $order ) return;

        $docs = $this->get_doc_rows( $order );
        ?>
        <div class="pbuaiv-metabox">
            <?php foreach ( $docs as $doc_type => $row ) : ?>
                <div class="pbuaiv-doc-row" id="pbuaiv-row-<?php echo esc_attr( $doc_type ); ?>">
                    <div class="pbuaiv-doc-row__header">
                        <span class="pbuaiv-doc-row__icon"><?php echo esc_html( $row['icon'] ); ?></span>
                        <span class="pbuaiv-doc-row__label"><?php echo esc_html( $row['label'] ); ?></span>
                        <?php if ( $row['issued'] ) : ?>
                            <span class="pbuaiv-badge pbuaiv-badge--<?php echo esc_attr( $row['status'] ); ?>">
                                <?php echo esc_html( $row['doc_number'] ); ?>
                            </span>
                        <?php else : ?>
                            <span class="pbuaiv-badge pbuaiv-badge--pending"><?php esc_html_e( 'Not issued', 'pb-invoicing-system' ); ?></span>
                        <?php endif; ?>
                    </div>
                    <div class="pbuaiv-doc-row__actions">
                        <?php if ( ! $row['issued'] ) : ?>
                            <button type="button"
                                class="pbuaiv-btn pbuaiv-btn--primary pbuaiv-btn--sm pbuaiv-action-issue"
                                data-order="<?php echo (int) $order->get_id(); ?>"
                                data-type="<?php echo esc_attr( $doc_type ); ?>">
                                <?php esc_html_e( 'Issue', 'pb-invoicing-system' ); ?>
                            </button>
                        <?php else : ?>
                            <a href="<?php echo esc_url( PBUAIV_Download_Handler::get_url( $order->get_id(), $doc_type, 'download' ) ); ?>"
                               target="_blank"
                               class="pbuaiv-btn pbuaiv-btn--secondary pbuaiv-btn--sm">
                                <span class="dashicons dashicons-download"></span>
                                <?php esc_html_e( 'Download', 'pb-invoicing-system' ); ?>
                            </a>
                            <a href="<?php echo esc_url( PBUAIV_Download_Handler::get_url( $order->get_id(), $doc_type, 'view' ) ); ?>"
                               target="_blank"
                               class="pbuaiv-btn pbuaiv-btn--ghost pbuaiv-btn--sm">
                                <span class="dashicons dashicons-visibility"></span>
                                <?php esc_html_e( 'View', 'pb-invoicing-system' ); ?>
                            </a>
                            <button type="button"
                                class="pbuaiv-btn pbuaiv-btn--ghost pbuaiv-btn--sm pbuaiv-action-send"
                                data-order="<?php echo (int) $order->get_id(); ?>"
                                data-type="<?php echo esc_attr( $doc_type ); ?>">
                                <span class="dashicons dashicons-email-alt"></span>
                                <?php esc_html_e( 'Send', 'pb-invoicing-system' ); ?>
                            </button>
                            <button type="button"
                                class="pbuaiv-btn pbuaiv-btn--ghost pbuaiv-btn--sm pbuaiv-action-regenerate"
                                data-order="<?php echo (int) $order->get_id(); ?>"
                                data-type="<?php echo esc_attr( $doc_type ); ?>"
                                title="<?php esc_attr_e( 'Regenerate PDF', 'pb-invoicing-system' ); ?>">
                                <span class="dashicons dashicons-update"></span>
                            </button>
                            <button type="button"
                                class="pbuaiv-btn pbuaiv-btn--danger pbuaiv-btn--sm pbuaiv-action-void"
                                data-order="<?php echo (int) $order->get_id(); ?>"
                                data-type="<?php echo esc_attr( $doc_type ); ?>"
                                title="<?php esc_attr_e( 'Void document', 'pb-invoicing-system' ); ?>">
                                <span class="dashicons dashicons-trash"></span>
                            </button>
                        <?php endif; ?>
                        <?php if ( in_array( $doc_type, [ 'invoice', 'proforma' ], true ) ) : ?>
                            <a href="<?php echo esc_url( $this->get_xml_url( $order->get_id(), $doc_type ) ); ?>"
                               class="pbuaiv-btn pbuaiv-btn--ghost pbuaiv-btn--sm"
                               title="<?php esc_attr_e( 'Download PINT AE XML', 'pb-invoicing-system' ); ?>">
                                XML
                            </a>
                        <?php endif; ?>
                    </div>
                    <?php if ( $row['issued'] && $row['sent_at'] ) : ?>
                        <div class="pbuaiv-doc-row__meta">
                            <?php printf(
                                /* translators: %s: sent date */
                                esc_html__( 'Sent: %s', 'pb-invoicing-system' ),
                                esc_html( date_i18n( get_option( 'date_format' ), strtotime( $row['sent_at'] ) ) )
                            ); ?>
                        </div>
                    <?php endif; ?>
                </div>
            <?php endforeach; ?>

            <!-- PINT AE XML Export note -->
            <div class="pbuaiv-xml-note">
                <small><?php esc_html_e( 'XML = PINT AE format for UAE e-invoicing mandate (2027)', 'pb-invoicing-system' ); ?></small>
            </div>

            <?php wp_nonce_field( 'pbuaiv_metabox', 'pbuaiv_metabox_nonce' ); ?>
        </div>
        <?php
    }

    // ── Data prep ────────────────────────────────────────────────────────────

    private function get_doc_rows( WC_Order $order ) : array {
        $types = [
            'invoice'       => [ 'label' => __( 'Tax Invoice', 'pb-invoicing-system' ),     'icon' => '🧾' ],
            'receipt'       => [ 'label' => __( 'Receipt', 'pb-invoicing-system' ),         'icon' => '✅' ],
            'credit_note'   => [ 'label' => __( 'Credit Note', 'pb-invoicing-system' ),     'icon' => '↩️' ],
            'proforma'      => [ 'label' => __( 'Proforma Invoice', 'pb-invoicing-system' ),'icon' => '📋' ],
            'packing_slip'  => [ 'label' => __( 'Packing Slip', 'pb-invoicing-system' ),    'icon' => '📦' ],
            'delivery_note' => [ 'label' => __( 'Delivery Note', 'pb-invoicing-system' ),   'icon' => '🚚' ],
        ];

        $rows = [];
        foreach ( $types as $type => $info ) {
            $doc    = PBUAIV_Email_Manager::factory( $type, $order );
            $record = $doc ? $doc->get_db_record() : null;
            $rows[ $type ] = array_merge( $info, [
                'issued'     => (bool) $record,
                'doc_number' => $record ? $record->doc_number : '',
                'doc_date'   => $record ? $record->doc_date   : '',
                'status'     => $record ? $record->status     : '',
                'sent_at'    => $record ? $record->sent_at    : null,
            ] );
        }
        return $rows;
    }

    private function get_xml_url( int $order_id, string $doc_type ) : string {
        return add_query_arg( [
            'pbuaiv_action' => 'xml',
            'doc_type'   => $doc_type,
            'order_id'   => $order_id,
            'nonce'      => wp_create_nonce( 'pbuaiv_xml_' . $order_id ),
        ], admin_url( 'admin-ajax.php' ) );
    }

    // ── Billing TRN field ─────────────────────────────────────────────────────

    public function render_billing_trn( WC_Order $order ) : void {
        $trn = $order->get_meta( '_billing_trn', true );
        $rc  = $order->get_meta( '_reverse_charge', true );
        ?>
        <div class="pbuaiv-order-field">
            <label for="pbuaiv_billing_trn"><strong><?php esc_html_e( 'Customer TRN (UAE VAT)', 'pb-invoicing-system' ); ?></strong></label>
            <input type="text" id="pbuaiv_billing_trn" name="pbuaiv_billing_trn" value="<?php echo esc_attr( $trn ); ?>" class="short" maxlength="15" placeholder="100000000000001" />
            <?php if ( $trn && ! PBUAIV_FTA_Compliance::validate_trn( $trn ) ) : ?>
                <span class="pbuaiv-trn-error" style="color:#ef4444;font-size:11px;">⚠ <?php esc_html_e( 'Invalid TRN format (must be 15 digits starting with 1 or 3)', 'pb-invoicing-system' ); ?></span>
            <?php endif; ?>
        </div>
        <div class="pbuaiv-order-field" style="margin-top:8px;">
            <label>
                <input type="checkbox" name="pbuaiv_reverse_charge" value="yes" <?php checked( $rc, 'yes' ); ?> />
                <?php esc_html_e( 'Reverse Charge Mechanism applies', 'pb-invoicing-system' ); ?>
            </label>
        </div>
        <?php
    }

    public function save_billing_trn( int $order_id ) : void {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return;
        }

        if ( ! $this->apply_billing_trn_from_request( $order ) ) {
            return;
        }

        // Classic order screen: persist only metadata. Never call $order->save()
        // from an order-update callback, as that re-enters WooCommerce saving.
        $order->save_meta_data();
    }

    /**
     * Save the custom fields on the HPOS order screen before WooCommerce performs
     * its own single order save.
     */
    public function save_billing_trn_hpos( WC_Order $order ) : void {
        $this->apply_billing_trn_from_request( $order );
    }

    private function apply_billing_trn_from_request( WC_Order $order ) : bool {
        if ( ! isset( $_POST['pbuaiv_metabox_nonce'] ) ) {
            return false;
        }
        if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['pbuaiv_metabox_nonce'] ) ), 'pbuaiv_metabox' ) ) {
            return false;
        }
        if ( ! current_user_can( 'edit_shop_order', $order->get_id() ) && ! current_user_can( 'manage_woocommerce' ) ) {
            return false;
        }

        if ( isset( $_POST['pbuaiv_billing_trn'] ) ) {
            $trn = sanitize_text_field( wp_unslash( $_POST['pbuaiv_billing_trn'] ) );
            $order->update_meta_data( '_billing_trn', $trn );
        }

        $order->update_meta_data( '_reverse_charge', isset( $_POST['pbuaiv_reverse_charge'] ) ? 'yes' : 'no' );
        return true;
    }
}
