<?php

namespace Devikit\Fakturowo;

use Devikit\Fakturowo\Admin\Settings;
use Devikit\Fakturowo\Api\Client;

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

class InvoiceManager {

    /**
     * @var Client
     */
    private $api_client;

    /**
     * @var Settings
     */
    private $settings;

    /**
     * Constructor
     * 
     * @param Client $api_client
     * @param Settings $settings
     */
    public function __construct( Client $api_client, Settings $settings ) {
        $this->api_client = $api_client;
        $this->settings = $settings;

        add_action( 'add_meta_boxes', [ $this, 'add_order_meta_box' ] );
        add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_metabox_scripts' ] );
        add_action( 'wp_ajax_devikit_fakturowo_create_invoice', [ $this, 'ajax_create_invoice' ] );
        add_action( 'wp_ajax_devikit_fakturowo_create_proforma', [ $this, 'ajax_create_proforma' ] );
        add_action( 'wp_ajax_devikit_fakturowo_download_pdf', [ $this, 'ajax_download_pdf' ] );
        add_action( 'wp_ajax_devikit_fakturowo_send_invoice_email', [ $this, 'ajax_send_invoice_email' ] );
        add_action( 'wp_ajax_devikit_fakturowo_send_proforma_email', [ $this, 'ajax_send_proforma_email' ] );
        
        // Frontend invoice download
        add_action( 'woocommerce_view_order', [ $this, 'display_invoice_download_button' ], 20 );
        add_action( 'template_redirect', [ $this, 'handle_invoice_download' ] );
        
        // Delayed invoice email handler (Action Scheduler)
        add_action( 'devikit_fakturowo_send_delayed_invoice_email', [ $this, 'handle_delayed_invoice_email' ], 10, 2 );
    }

    /**
     * Add Meta Box
     */
    public function add_order_meta_box() {
        add_meta_box(
            'devikit_fakturowo_invoice',
            __( 'Fakturowo Invoice', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
            [ $this, 'render_meta_box' ],
            'shop_order',
            'side',
            'high'
        );
        
        // HPOS support
        if ( class_exists( '\Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController' ) && wc_get_container()->get( \Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController::class )->custom_orders_table_usage_is_enabled() ) {
             add_meta_box(
                'devikit_fakturowo_invoice',
                __( 'Fakturowo Invoice', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                [ $this, 'render_meta_box' ],
                wc_get_page_screen_id( 'shop_order' ),
                'side',
                'high'
            );
        }
    }

    /**
     * Enqueue metabox scripts
     */
    public function enqueue_metabox_scripts( $hook_suffix ) {
        // Only on order pages
        if ( $hook_suffix !== 'post.php' && $hook_suffix !== 'woocommerce_page_wc-orders' ) {
            return;
        }
        
        global $post;
        $screen = get_current_screen();
        
        // Check if it's an order page
        if ( ( $post && $post->post_type !== 'shop_order' ) && ( ! $screen || $screen->id !== 'woocommerce_page_wc-orders' ) ) {
            return;
        }
        
        wp_enqueue_script( 'jquery' );
        
        $nonce_invoice = esc_js( wp_create_nonce( 'fakturowo_create_invoice' ) );
        $nonce_proforma = esc_js( wp_create_nonce( 'fakturowo_create_proforma' ) );
        $nonce_download = esc_js( wp_create_nonce( 'fakturowo_download_pdf' ) );
        $nonce_send_invoice = esc_js( wp_create_nonce( 'fakturowo_send_email' ) );
        $nonce_send_proforma = esc_js( wp_create_nonce( 'fakturowo_send_proforma_email' ) );
        $downloading_text = esc_js( __( 'Downloading...', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        $sending_text = esc_js( __( 'Sending...', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        $error_download = esc_js( __( 'Failed to download PDF', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        $error_send = esc_js( __( 'Failed to send email', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        
        $inline_script = "
            jQuery(document).ready(function($) {
                // Create invoice button
                $('#devikit-fakturowo-create-invoice').on('click', function() {
                    var \$btn = $(this);
                    var \$loading = $('#devikit-fakturowo-loading');
                    var \$error = $('#devikit-fakturowo-error');
                    
                    \$btn.hide();
                    \$loading.show();
                    \$error.text('');

                    $.post(ajaxurl, {
                        action: 'devikit_fakturowo_create_invoice',
                        order_id: \$btn.data('order-id'),
                        nonce: '" . $nonce_invoice . "'
                    }, function(response) {
                        \$loading.hide();
                        if (response.success) {
                            location.reload();
                        } else {
                            \$btn.show();
                            \$error.text(response.data.message);
                        }
                    });
                });
                
                // Create proforma button
                $('#devikit-fakturowo-create-proforma').on('click', function() {
                    var \$btn = $(this);
                    var \$loading = $('#devikit-fakturowo-proforma-loading');
                    var \$error = $('#devikit-fakturowo-proforma-error');
                    
                    \$btn.hide();
                    \$loading.show();
                    \$error.text('');

                    $.post(ajaxurl, {
                        action: 'devikit_fakturowo_create_proforma',
                        order_id: \$btn.data('order-id'),
                        nonce: '" . $nonce_proforma . "'
                    }, function(response) {
                        \$loading.hide();
                        if (response.success) {
                            location.reload();
                        } else {
                            \$btn.show();
                            \$error.text(response.data.message);
                        }
                    });
                });
                
                // Download PDF buttons
                $('#devikit-fakturowo-download-pdf, #devikit-fakturowo-download-proforma-pdf').on('click', function() {
                    var \$btn = $(this);
                    var invoiceId = \$btn.data('invoice-id');
                    var invoiceNumber = \$btn.data('invoice-number');
                    var originalText = \$btn.text();
                    
                    \$btn.prop('disabled', true).text('" . $downloading_text . "');
                    
                    $.post(ajaxurl, {
                        action: 'devikit_fakturowo_download_pdf',
                        invoice_id: invoiceId,
                        invoice_number: invoiceNumber,
                        nonce: '" . $nonce_download . "'
                    }, function(response) {
                        \$btn.prop('disabled', false).text(originalText);
                        
                        if (response.success && response.data.pdf) {
                            var binary = atob(response.data.pdf);
                            var array = new Uint8Array(binary.length);
                            for (var i = 0; i < binary.length; i++) {
                                array[i] = binary.charCodeAt(i);
                            }
                            var blob = new Blob([array], {type: 'application/pdf'});
                            var url = window.URL.createObjectURL(blob);
                            var a = document.createElement('a');
                            a.href = url;
                            a.download = response.data.filename;
                            document.body.appendChild(a);
                            a.click();
                            window.URL.revokeObjectURL(url);
                            document.body.removeChild(a);
                        } else {
                            alert(response.data.message || '" . $error_download . "');
                        }
                    }).fail(function() {
                        \$btn.prop('disabled', false).text(originalText);
                        alert('" . $error_download . "');
                    });
                });
                
                // Send invoice email button
                $('#devikit-fakturowo-send-invoice-email').on('click', function() {
                    var \$btn = $(this);
                    var orderId = \$btn.data('order-id');
                    var originalText = \$btn.text();
                    
                    \$btn.prop('disabled', true).text('" . $sending_text . "');
                    
                    $.post(ajaxurl, {
                        action: 'devikit_fakturowo_send_invoice_email',
                        order_id: orderId,
                        nonce: '" . $nonce_send_invoice . "'
                    }, function(response) {
                        \$btn.prop('disabled', false).text(originalText);
                        if (response.success) {
                            alert(response.data.message);
                        } else {
                            alert(response.data.message || '" . $error_send . "');
                        }
                    }).fail(function() {
                        \$btn.prop('disabled', false).text(originalText);
                        alert('" . $error_send . "');
                    });
                });
                
                // Send proforma email button
                $('#devikit-fakturowo-send-proforma-email').on('click', function() {
                    var \$btn = $(this);
                    var orderId = \$btn.data('order-id');
                    var originalText = \$btn.text();
                    
                    \$btn.prop('disabled', true).text('" . $sending_text . "');
                    
                    $.post(ajaxurl, {
                        action: 'devikit_fakturowo_send_proforma_email',
                        order_id: orderId,
                        nonce: '" . $nonce_send_proforma . "'
                    }, function(response) {
                        \$btn.prop('disabled', false).text(originalText);
                        if (response.success) {
                            alert(response.data.message);
                        } else {
                            alert(response.data.message || '" . $error_send . "');
                        }
                    }).fail(function() {
                        \$btn.prop('disabled', false).text(originalText);
                        alert('" . $error_send . "');
                    });
                });
            });
        ";
        
        wp_add_inline_script( 'jquery', $inline_script );
    }

    /**
     * Render Meta Box
     * 
     * @param \WP_Post|\WC_Order $post_or_order_object
     */
    public function render_meta_box( $post_or_order_object ) {
        $order = ( $post_or_order_object instanceof \WC_Order ) ? $post_or_order_object : wc_get_order( $post_or_order_object->ID );
        if ( ! $order ) return;

        $invoice_id = $order->get_meta( '_fakturowo_invoice_id' );
        $invoice_uuid = $order->get_meta( '_fakturowo_invoice_uuid' );
        $invoice_number = $order->get_meta( '_fakturowo_invoice_number' );
        $invoice_url = $order->get_meta( '_fakturowo_invoice_url' );
        
        $proforma_id = $order->get_meta( '_fakturowo_proforma_id' );
        $proforma_number = $order->get_meta( '_fakturowo_proforma_number' );
        $proforma_url = $order->get_meta( '_fakturowo_proforma_url' );
        
        // In FREE version: only check if PRO plugin exists (don't check license)
        // PRO version will handle license checking via its own hooks
        $is_pro_installed = class_exists( 'Devikit\FakturowoPro\Plugin' );

        ?>
        <div class="devikit-fakturowo-metabox">
            <?php if ( $proforma_id ) : ?>
                <p>
                    <strong><?php echo esc_html__( 'Proforma Created:', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></strong><br>
                    <?php echo esc_html( $proforma_number ?: $proforma_id ); ?>
                </p>
                
                <?php
                // Check for total mismatch
                $has_proforma_mismatch = $order->get_meta( '_fakturowo_proforma_total_mismatch' ) === 'yes';
                if ( $has_proforma_mismatch ) {
                    $order_total = floatval( $order->get_meta( '_fakturowo_proforma_order_total' ) );
                    $proforma_total = floatval( $order->get_meta( '_fakturowo_proforma_fakturowo_total' ) );
                    $difference = floatval( $order->get_meta( '_fakturowo_proforma_total_difference' ) );
                    ?>
                    <div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 10px; margin: 10px 0;">
                        <p style="margin: 0; font-weight: bold; color: #856404;">
                            <?php echo esc_html__( '⚠ Total Mismatch Detected', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </p>
                        <p style="margin: 5px 0 0 0; color: #856404;">
                            <?php 
                            printf(
                                /* translators: 1: Order total, 2: Proforma total, 3: Difference */
                                esc_html__( 'Order total: %1$s | Proforma total: %2$s | Difference: %3$s', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                                number_format( $order_total, 2, ',', ' ' ),
                                number_format( $proforma_total, 2, ',', ' ' ),
                                number_format( $difference, 2, ',', ' ' )
                            );
                            ?>
                        </p>
                        <p style="margin: 5px 0 0 0; color: #856404; font-size: 12px;">
                            <?php echo esc_html__( 'Email was not sent automatically. Please review the proforma and send manually if needed.', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </p>
                    </div>
                    <?php
                }
                ?>
                
                <p>
                    <?php if ( $proforma_url ) : ?>
                        <a href="<?php echo esc_url( $proforma_url ); ?>" target="_blank" class="button">
                            <?php echo esc_html__( 'Open in Fakturowo', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </a>
                    <?php else : ?>
                        <button type="button" class="button" disabled style="opacity:0.5; cursor:not-allowed;" title="<?php echo esc_attr__( 'Preview URL not available', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>">
                            <?php echo esc_html__( 'Open in Fakturowo', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </button>
                    <?php endif; ?>
                    <button type="button" class="button" id="devikit-fakturowo-download-proforma-pdf" 
                            data-invoice-id="<?php echo esc_attr( $proforma_id ); ?>"
                            data-invoice-number="<?php echo esc_attr( $proforma_number ); ?>">
                        <?php echo esc_html__( 'Download PDF', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                    </button>
                </p>
                <p style="margin-top:10px;">
                    <?php if ( $is_pro_installed ) : ?>
                        <button type="button" class="button" id="devikit-fakturowo-send-proforma-email" 
                                data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
                            <?php echo esc_html__( 'Send Proforma by Email', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </button>
                        <span id="devikit-fakturowo-proforma-email-loading" style="display:none;"><?php echo esc_html__( 'Sending...', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></span>
                        <span id="devikit-fakturowo-proforma-email-success" style="color:green; display:none;"><?php echo esc_html__( '✓ Sent', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></span>
                        <p id="devikit-fakturowo-proforma-email-error" style="color:red; margin-top:10px;"></p>
                    <?php else : ?>
                        <button type="button" class="button" disabled style="opacity:0.5; cursor:not-allowed;">
                            <?php echo esc_html__( 'Send Proforma by Email', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?> 🔒
                        </button>
                        <br>
                        <small style="color:#666; margin-top:5px; display:block;">
                            <?php 
                            printf(
                                /* translators: %s: link to PRO version */
                                esc_html__( 'Available in %s', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                                '<a href="https://devikit.pl/produkt/fakturowo-woocommerce-pro/" target="_blank" style="color:#2271b1; text-decoration:none;">' . esc_html__( 'PRO version', 'invoicing-integration-for-fakturowo-and-woocommerce' ) . '</a>'
                            );
                            ?>
                        </small>
                    <?php endif; ?>
                </p>
                <hr style="margin:15px 0;">
            <?php endif; ?>
            
            <?php if ( $invoice_id ) : ?>
                <p>
                    <strong><?php echo esc_html__( 'Invoice Created:', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></strong><br>
                    <?php echo esc_html( $invoice_number ?: $invoice_id ); ?>
                </p>
                
                <?php
                // Check for total mismatch
                $has_total_mismatch = $order->get_meta( '_fakturowo_invoice_total_mismatch' ) === 'yes';
                if ( $has_total_mismatch ) {
                    $order_total = floatval( $order->get_meta( '_fakturowo_invoice_order_total' ) );
                    $invoice_total = floatval( $order->get_meta( '_fakturowo_invoice_fakturowo_total' ) );
                    $difference = floatval( $order->get_meta( '_fakturowo_invoice_total_difference' ) );
                    ?>
                    <div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 10px; margin: 10px 0;">
                        <p style="margin: 0; font-weight: bold; color: #856404;">
                            <?php echo esc_html__( '⚠ Total Mismatch Detected', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </p>
                        <p style="margin: 5px 0 0 0; color: #856404;">
                            <?php 
                            printf(
                                /* translators: 1: Order total, 2: Invoice total, 3: Difference */
                                esc_html__( 'Order total: %1$s | Invoice total: %2$s | Difference: %3$s', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                                number_format( $order_total, 2, ',', ' ' ),
                                number_format( $invoice_total, 2, ',', ' ' ),
                                number_format( $difference, 2, ',', ' ' )
                            );
                            ?>
                        </p>
                        <p style="margin: 5px 0 0 0; color: #856404; font-size: 12px;">
                            <?php echo esc_html__( 'Email was not sent automatically. Please review the invoice and send manually if needed.', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </p>
                    </div>
                    <?php
                }
                ?>
                
                <p>
                    <?php if ( $invoice_url ) : ?>
                        <a href="<?php echo esc_url( $invoice_url ); ?>" target="_blank" class="button">
                            <?php echo esc_html__( 'Open in Fakturowo', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </a>
                    <?php else : ?>
                        <button type="button" class="button" disabled style="opacity:0.5; cursor:not-allowed;" title="<?php echo esc_attr__( 'Preview URL not available', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>">
                            <?php echo esc_html__( 'Open in Fakturowo', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </button>
                    <?php endif; ?>
                    <button type="button" class="button" id="devikit-fakturowo-download-pdf" 
                            data-invoice-id="<?php echo esc_attr( $invoice_id ); ?>"
                            data-invoice-number="<?php echo esc_attr( $invoice_number ); ?>">
                        <?php echo esc_html__( 'Download PDF', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                    </button>
                </p>
                <p style="margin-top:10px;">
                    <?php if ( $is_pro_installed ) : ?>
                        <button type="button" class="button" id="devikit-fakturowo-send-invoice-email" 
                                data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
                            <?php echo esc_html__( 'Send Invoice by Email', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </button>
                        <span id="devikit-fakturowo-email-loading" style="display:none;"><?php echo esc_html__( 'Sending...', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></span>
                        <span id="devikit-fakturowo-email-success" style="color:green; display:none;"><?php echo esc_html__( '✓ Sent', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></span>
                        <p id="devikit-fakturowo-email-error" style="color:red; margin-top:10px;"></p>
                    <?php else : ?>
                        <button type="button" class="button" disabled style="opacity:0.5; cursor:not-allowed;">
                            <?php echo esc_html__( 'Send Invoice by Email', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?> 🔒
                        </button>
                        <br>
                        <small style="color:#666; margin-top:5px; display:block;">
                            <?php 
                            printf(
                                /* translators: %s: link to PRO version */
                                esc_html__( 'Available in %s', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                                '<a href="https://devikit.pl/produkt/fakturowo-woocommerce-pro/" target="_blank" style="color:#2271b1; text-decoration:none;">' . esc_html__( 'PRO version', 'invoicing-integration-for-fakturowo-and-woocommerce' ) . '</a>'
                            );
                            ?>
                        </small>
                    <?php endif; ?>
                </p>

            <?php endif; ?>
            
            <?php if ( ! $invoice_id || ! $proforma_id ) : ?>
                <?php if ( ! $invoice_id && ! $proforma_id ) : ?>
                    <p><?php echo esc_html__( 'No documents created yet.', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></p>
                <?php elseif ( $proforma_id && ! $invoice_id ) : ?>
                    <hr style="margin:15px 0;">
                <?php endif; ?>
                
                <p style="margin-top:10px;">
                    <?php if ( ! $invoice_id ) : ?>
                        <button type="button" class="button button-primary" id="devikit-fakturowo-create-invoice" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
                            <?php echo esc_html__( 'Create Invoice', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                        </button>
                    <?php endif; ?>
                </p>
                    
                <?php if ( ! $proforma_id ) : ?>
                    <p style="margin-top:10px;">
                        <?php if ( $is_pro_installed ) : ?>
                            <button type="button" class="button" id="devikit-fakturowo-create-proforma" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
                                <?php echo esc_html__( 'Create Proforma', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?>
                            </button>
                        <?php else : ?>
                            <button type="button" class="button" disabled style="opacity:0.5; cursor:not-allowed;">
                                <?php echo esc_html__( 'Create Proforma', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?> 🔒
                            </button>
                            <br>
                            <small style="color:#666; margin-top:5px; display:block;">
                                <?php 
                                printf(
                                    /* translators: %s: link to PRO version */
                                    esc_html__( 'Proformas available in %s', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                                    '<a href="https://devikit.pl/produkt/fakturowo-woocommerce-pro/" target="_blank" style="color:#2271b1; text-decoration:none;">' . esc_html__( 'PRO version', 'invoicing-integration-for-fakturowo-and-woocommerce' ) . '</a>'
                                );
                                ?>
                            </small>
                        <?php endif; ?>
                    </p>
                <?php endif; ?>
                <span id="devikit-fakturowo-loading" style="display:none;"><?php echo esc_html__( 'Creating invoice...', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></span>
                <?php if ( $is_pro_installed && ! $proforma_id ) : ?>
                    <span id="devikit-fakturowo-proforma-loading" style="display:none;"><?php echo esc_html__( 'Creating proforma...', 'invoicing-integration-for-fakturowo-and-woocommerce' ); ?></span>
                <?php endif; ?>
                <p id="devikit-fakturowo-error" style="color:red; margin-top:10px;"></p>
                <?php if ( $is_pro_installed && ! $proforma_id ) : ?>
                    <p id="devikit-fakturowo-proforma-error" style="color:red; margin-top:10px;"></p>
                <?php endif; ?>
            <?php endif; ?>
        </div>
        <?php
    }

    /**
     * AJAX Create Invoice
     */
    public function ajax_create_invoice() {
        check_ajax_referer( 'fakturowo_create_invoice', 'nonce' );
        
        if ( ! current_user_can( 'edit_shop_orders' ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized' ] );
        }

        $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
        $order = wc_get_order( $order_id );

        if ( ! $order ) {
            wp_send_json_error( [ 'message' => 'Order not found' ] );
        }

        $result = $this->create_invoice_for_order( $order );

        if ( is_wp_error( $result ) ) {
            wp_send_json_error( [ 'message' => $result->get_error_message() ] );
        }

        wp_send_json_success();
    }
    
    /**
     * AJAX Create Proforma
     */
    public function ajax_create_proforma() {
        check_ajax_referer( 'fakturowo_create_proforma', 'nonce' );
        
        if ( ! current_user_can( 'edit_shop_orders' ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized' ] );
        }
        
        // Check if PRO is active
        if ( ! class_exists( 'Devikit\FakturowoPro\Plugin' ) ) {
            wp_send_json_error( [ 'message' => __( 'PRO version required', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
        }

        $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
        $order = wc_get_order( $order_id );

        if ( ! $order ) {
            wp_send_json_error( [ 'message' => __( 'Order not found', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
        }

        $result = $this->create_proforma_for_order( $order );

        if ( is_wp_error( $result ) ) {
            wp_send_json_error( [ 'message' => $result->get_error_message() ] );
        }

        wp_send_json_success();
    }

    /**
     * AJAX Download PDF
     */
    public function ajax_download_pdf() {
        check_ajax_referer( 'fakturowo_download_pdf', 'nonce' );
        
        if ( ! current_user_can( 'edit_shop_orders' ) ) {
            wp_send_json_error( [ 'message' => 'Unauthorized' ] );
        }

        $invoice_id = isset( $_POST['invoice_id'] ) ? absint( $_POST['invoice_id'] ) : 0;
        $invoice_number = isset( $_POST['invoice_number'] ) ? sanitize_text_field( wp_unslash( $_POST['invoice_number'] ) ) : 'invoice';

        if ( ! $invoice_id ) {
            wp_send_json_error( [ 'message' => 'Invoice ID missing' ] );
        }

        $pdf_content = $this->api_client->download_invoice_pdf( $invoice_id );

        if ( is_wp_error( $pdf_content ) ) {
            // Log error for debugging
            $this->api_client->log( 'PDF Download Error: ' . $pdf_content->get_error_message(), 'error' );
            wp_send_json_error( [ 'message' => $pdf_content->get_error_message() ] );
        }

        // Check if response is actually PDF (binary data)
        if ( empty( $pdf_content ) ) {
            wp_send_json_error( [ 'message' => 'PDF content is empty' ] );
        }

        // Return PDF as base64 for download via JavaScript
        wp_send_json_success( [ 
            'pdf' => base64_encode( $pdf_content ),
            'filename' => sanitize_file_name( $invoice_number ) . '.pdf'
        ] );
    }
    
    /**
     * AJAX Send Invoice Email
     */
    public function ajax_send_invoice_email() {
        $this->api_client->log( 'AJAX Send Invoice Email called', 'debug' );
        
        check_ajax_referer( 'fakturowo_send_email', 'nonce' );
        
        if ( ! current_user_can( 'edit_shop_orders' ) ) {
            $this->api_client->log( 'AJAX Send Invoice Email: Unauthorized', 'error' );
            wp_send_json_error( [ 'message' => 'Unauthorized' ] );
        }
        
        // Check if PRO is active
        if ( ! class_exists( 'Devikit\FakturowoPro\Plugin' ) ) {
            $this->api_client->log( 'AJAX Send Invoice Email: PRO not active', 'error' );
            wp_send_json_error( [ 'message' => __( 'PRO version required', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
        }
        
        // Force load WooCommerce emails
        WC()->mailer();

        $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
        $this->api_client->log( 'AJAX Send Invoice Email: Order ID: ' . $order_id, 'debug' );
        
        $order = wc_get_order( $order_id );

        if ( ! $order ) {
            $this->api_client->log( 'AJAX Send Invoice Email: Order not found', 'error' );
            wp_send_json_error( [ 'message' => __( 'Order not found', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
        }
        
        // Get invoice data
        $invoice_id = $order->get_meta( '_fakturowo_invoice_id' );
        $invoice_number = $order->get_meta( '_fakturowo_invoice_number' );
        
        $this->api_client->log( 'AJAX Send Invoice Email: Invoice data: ' . wp_json_encode( [
            'invoice_id' => $invoice_id,
            'invoice_number' => $invoice_number
        ], JSON_UNESCAPED_UNICODE ), 'debug' );
        
        if ( ! $invoice_id ) {
            $this->api_client->log( 'AJAX Send Invoice Email: Invoice not found', 'error' );
            wp_send_json_error( [ 'message' => __( 'Invoice not found', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
        }
        
        // Check for total mismatch - do not send email if totals don't match
        $has_total_mismatch = $order->get_meta( '_fakturowo_invoice_total_mismatch' ) === 'yes';
        if ( $has_total_mismatch ) {
            $order_total = floatval( $order->get_meta( '_fakturowo_invoice_order_total' ) );
            $invoice_total = floatval( $order->get_meta( '_fakturowo_invoice_fakturowo_total' ) );
            $difference = floatval( $order->get_meta( '_fakturowo_invoice_total_difference' ) );
            
            $this->api_client->log( 'AJAX Send Invoice Email: Total mismatch detected - email blocked', 'error' );
            wp_send_json_error( [ 
                'message' => sprintf(
                    /* translators: 1: Order total, 2: Invoice total, 3: Difference */
                    __( 'Cannot send email: Total mismatch detected. Order total: %1$s | Invoice total: %2$s | Difference: %3$s', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                    number_format( $order_total, 2, ',', ' ' ),
                    number_format( $invoice_total, 2, ',', ' ' ),
                    number_format( $difference, 2, ',', ' ' )
                )
            ] );
        }
        
        // Prepare invoice data for email
        $invoice_data = [
            'url' => '',
            'number' => $invoice_number,
            'id' => $invoice_id
        ];
        
        $this->api_client->log( 'AJAX Send Invoice Email: Triggering hook with data: ' . wp_json_encode( $invoice_data, JSON_UNESCAPED_UNICODE ), 'debug' );
        
        // Check if there are any listeners
        $has_listeners = has_action( 'devikit_fakturowo_invoice_generated' );
        $this->api_client->log( 'AJAX Send Invoice Email: Hook listeners count: ' . ( $has_listeners ? $has_listeners : '0' ), 'debug' );
        
        // Get all registered email classes
        $wc_emails = WC()->mailer()->get_emails();
        $email_classes = array_keys( $wc_emails );
        $this->api_client->log( 'Registered WC email classes: ' . wp_json_encode( $email_classes, JSON_UNESCAPED_UNICODE ), 'debug' );
        
        // Check if our email is enabled
        if ( isset( $wc_emails['fakturowo_invoice_email'] ) ) {
            $fakturowo_email = $wc_emails['fakturowo_invoice_email'];
            $this->api_client->log( 'Fakturowo Invoice Email status: ' . wp_json_encode( [
                'enabled' => $fakturowo_email->is_enabled(),
                'id' => $fakturowo_email->id
            ], JSON_UNESCAPED_UNICODE ), 'debug' );
        } else {
            $this->api_client->log( 'Fakturowo Invoice Email NOT registered!', 'error' );
        }
        
        // Trigger email hook
        do_action( 'devikit_fakturowo_invoice_generated', $order_id, $invoice_data );
        
        $this->api_client->log( 'AJAX Send Invoice Email: Hook triggered', 'debug' );
        
        $order->add_order_note( __( 'Invoice email sent to customer', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );

        $this->api_client->log( 'AJAX Send Invoice Email: Returning success', 'debug' );
        wp_send_json_success( [ 'message' => __( 'Email sent successfully', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
    }
    
    /**
     * AJAX Send Proforma Email
     */
    public function ajax_send_proforma_email() {
        $this->api_client->log( 'AJAX Send Proforma Email called', 'debug' );
        
        check_ajax_referer( 'fakturowo_send_proforma_email', 'nonce' );
        
        if ( ! current_user_can( 'edit_shop_orders' ) ) {
            $this->api_client->log( 'AJAX Send Proforma Email: Unauthorized', 'error' );
            wp_send_json_error( [ 'message' => 'Unauthorized' ] );
        }
        
        // Check if PRO is active
        if ( ! class_exists( 'Devikit\FakturowoPro\Plugin' ) ) {
            $this->api_client->log( 'AJAX Send Proforma Email: PRO not active', 'error' );
            wp_send_json_error( [ 'message' => __( 'PRO version required', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
        }
        
        // Force load WooCommerce emails
        WC()->mailer();

        $order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
        $this->api_client->log( 'AJAX Send Proforma Email: Order ID: ' . $order_id, 'debug' );
        
        $order = wc_get_order( $order_id );

        if ( ! $order ) {
            $this->api_client->log( 'AJAX Send Proforma Email: Order not found', 'error' );
            wp_send_json_error( [ 'message' => __( 'Order not found', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
        }
        
        // Get proforma data
        $proforma_id = $order->get_meta( '_fakturowo_proforma_id' );
        $proforma_number = $order->get_meta( '_fakturowo_proforma_number' );
        
        $this->api_client->log( 'AJAX Send Proforma Email: Proforma data: ' . wp_json_encode( [
            'proforma_id' => $proforma_id,
            'proforma_number' => $proforma_number
        ], JSON_UNESCAPED_UNICODE ), 'debug' );
        
        if ( ! $proforma_id ) {
            $this->api_client->log( 'AJAX Send Proforma Email: Proforma not found', 'error' );
            wp_send_json_error( [ 'message' => __( 'Proforma not found', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
        }
        
        // Check for total mismatch - do not send email if totals don't match
        $has_total_mismatch = $order->get_meta( '_fakturowo_proforma_total_mismatch' ) === 'yes';
        if ( $has_total_mismatch ) {
            $order_total = floatval( $order->get_meta( '_fakturowo_proforma_order_total' ) );
            $proforma_total = floatval( $order->get_meta( '_fakturowo_proforma_fakturowo_total' ) );
            $difference = floatval( $order->get_meta( '_fakturowo_proforma_total_difference' ) );
            
            $this->api_client->log( 'AJAX Send Proforma Email: Total mismatch detected - email blocked', 'error' );
            wp_send_json_error( [ 
                'message' => sprintf(
                    /* translators: 1: Order total, 2: Proforma total, 3: Difference */
                    __( 'Cannot send email: Total mismatch detected. Order total: %1$s | Proforma total: %2$s | Difference: %3$s', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                    number_format( $order_total, 2, ',', ' ' ),
                    number_format( $proforma_total, 2, ',', ' ' ),
                    number_format( $difference, 2, ',', ' ' )
                )
            ] );
        }
        
        // Prepare proforma data for email
        $proforma_data = [
            'url' => '',
            'number' => $proforma_number,
            'id' => $proforma_id
        ];
        
        $this->api_client->log( 'AJAX Send Proforma Email: Triggering hook with data: ' . wp_json_encode( $proforma_data, JSON_UNESCAPED_UNICODE ), 'debug' );
        
        // Check if there are any listeners
        $has_listeners = has_action( 'devikit_fakturowo_proforma_generated' );
        $this->api_client->log( 'AJAX Send Proforma Email: Hook listeners count: ' . ( $has_listeners ? $has_listeners : '0' ), 'debug' );
        
        // Trigger email hook
        do_action( 'devikit_fakturowo_proforma_generated', $order_id, $proforma_data );
        
        $this->api_client->log( 'AJAX Send Proforma Email: Hook triggered', 'debug' );
        
        $order->add_order_note( __( 'Proforma email sent to customer', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );

        $this->api_client->log( 'AJAX Send Proforma Email: Returning success', 'debug' );
        wp_send_json_success( [ 'message' => __( 'Email sent successfully', 'invoicing-integration-for-fakturowo-and-woocommerce' ) ] );
    }

    /**
     * Create Invoice for Order
     * 
     * @param \WC_Order $order
     * @param bool $is_automatic Whether invoice is created automatically (for delayed email logic)
     * @return int|WP_Error Invoice ID or Error
     */
    public function create_invoice_for_order( $order, $is_automatic = false ) {
        // 1. Prepare document data for Fakturowo API (api_zadanie=1).
        $invoice_data = $this->prepare_document_data( $order, 0 ); // 0 = Faktura VAT
        $invoice_data = apply_filters( 'devikit_fakturowo_invoice_data', $invoice_data, $order );
        
        // Log invoice data for debugging
        $this->api_client->log( 'Invoice data prepared: ' . wp_json_encode( $invoice_data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT ), 'debug' );

        // 2. Send to API
        $response = $this->api_client->create_invoice( $invoice_data );

        if ( is_wp_error( $response ) ) {
            $order->add_order_note( __( 'Fakturowo Invoice Error: ', 'invoicing-integration-for-fakturowo-and-woocommerce' ) . $response->get_error_message() );
            return $response;
        }

        // 3. Save Invoice api_numer and fetch document number
        if ( isset( $response['api_numer'] ) && $response['api_numer'] !== '' ) {
            $api_numer = $response['api_numer'];
            
            // Fetch document details to get the actual invoice number (e.g. "FV/01/2025")
            $details = $this->api_client->get_document_details( $api_numer );
            $document_number = '';
            
            if ( ! is_wp_error( $details ) && isset( $details['dokument_numer'] ) ) {
                $document_number = $details['dokument_numer'];
            }
            
            // Verify total amount match
            $has_total_mismatch = false;
            if ( ! is_wp_error( $details ) && isset( $details['wartosc_brutto'] ) ) {
                // Get invoice total from Fakturowo (wartosc_brutto is in PLN, may be string or number)
                $invoice_total = floatval( $details['wartosc_brutto'] );
                
                // Compare with order total (gross total including taxes)
                $order_total = floatval( $order->get_total() );
                $total_difference = abs( $invoice_total - $order_total );
                
                // Any difference, even 0.01 grosz, should be marked as mismatch
                // Use small tolerance (0.001) to account for float precision issues
                $has_total_mismatch = $total_difference >= 0.001;
                
                if ( $has_total_mismatch ) {
                    $order->update_meta_data( '_fakturowo_invoice_total_mismatch', 'yes' );
                    $order->update_meta_data( '_fakturowo_invoice_order_total', $order_total );
                    $order->update_meta_data( '_fakturowo_invoice_fakturowo_total', $invoice_total );
                    $order->update_meta_data( '_fakturowo_invoice_total_difference', $total_difference );
                    
                    /* translators: 1: Invoice number/ID, 2: Order total, 3: Invoice total */
                    $order->add_order_note( sprintf( 
                        __( 'Fakturowo Invoice created: %1$s (Total mismatch: Order %2$s vs Invoice %3$s)', 'invoicing-integration-for-fakturowo-and-woocommerce' ), 
                        $document_number ? $document_number : $api_numer,
                        number_format( $order_total, 2, ',', ' ' ),
                        number_format( $invoice_total, 2, ',', ' ' )
                    ) );
                } else {
                    $order->delete_meta_data( '_fakturowo_invoice_total_mismatch' );
                    $order->delete_meta_data( '_fakturowo_invoice_order_total' );
                    $order->delete_meta_data( '_fakturowo_invoice_fakturowo_total' );
                    $order->delete_meta_data( '_fakturowo_invoice_total_difference' );
                    
                    /* translators: %s: Invoice number */
                    $order->add_order_note( sprintf( __( 'Fakturowo Invoice created: %s', 'invoicing-integration-for-fakturowo-and-woocommerce' ), $document_number ? $document_number : $api_numer ) );
                }
            } else {
                /* translators: %s: Invoice number */
                $order->add_order_note( sprintf( __( 'Fakturowo Invoice created: %s', 'invoicing-integration-for-fakturowo-and-woocommerce' ), $document_number ? $document_number : $api_numer ) );
            }
            
            // Save both: api_numer (for API operations) and dokument_numer (for display)
            $order->update_meta_data( '_fakturowo_invoice_id', $api_numer );
            $order->update_meta_data( '_fakturowo_invoice_number', $document_number ? $document_number : $api_numer );
            
            // Build preview URL - use API response if available, otherwise construct from base URL
            $preview_url = '';
            if ( isset( $response['preview_url'] ) && $response['preview_url'] !== '' ) {
                $preview_url = $response['preview_url'];
            } else {
                // Construct URL from api_url setting: https://konto.fakturowo.pl/pokaz/{api_numer}
                $settings = get_option( 'devikit_fakturowo_settings', [] );
                $api_url = isset( $settings['api_url'] ) ? $settings['api_url'] : '';
                if ( $api_url ) {
                    // Remove /api from the end and add /pokaz/{api_numer}
                    $base_url = preg_replace( '/\/api\/?$/', '', $api_url );
                    $preview_url = $base_url . '/pokaz/' . $api_numer;
                }
            }
            
            if ( $preview_url ) {
                $order->update_meta_data( '_fakturowo_invoice_url', $preview_url );
            }
            
            $order->save();
            
            // Only send email if totals match
            if ( ! $has_total_mismatch ) {
                // Trigger email (if PRO is active and enabled)
                $this->maybe_send_invoice_email( $order, $response, $document_number, $is_automatic );
            }
            
            return $api_numer;
        }

        return new \WP_Error( 'fakturowo_unknown_error', 'Unknown response from Fakturowo API' );
    }
    
    /**
     * Create Proforma for Order
     * 
     * @param \WC_Order $order
     * @return int|WP_Error Proforma ID or Error
     */
    public function create_proforma_for_order( $order ) {
        // 1. Prepare Proforma data for Fakturowo API (api_zadanie=1).
        $proforma_data = $this->prepare_document_data( $order, 2 ); // 2 = Faktura proforma
        $proforma_data = apply_filters( 'devikit_fakturowo_proforma_data', $proforma_data, $order );
        
        // Log proforma data for debugging
        $this->api_client->log( 'Proforma data prepared: ' . wp_json_encode( $proforma_data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT ), 'debug' );

        // 2. Send to API
        $response = $this->api_client->create_invoice( $proforma_data );

        if ( is_wp_error( $response ) ) {
            $order->add_order_note( __( 'Fakturowo Proforma Error: ', 'invoicing-integration-for-fakturowo-and-woocommerce' ) . $response->get_error_message() );
            return $response;
        }

        // 3. Save Proforma api_numer and fetch document number
        if ( isset( $response['api_numer'] ) && $response['api_numer'] !== '' ) {
            $api_numer = $response['api_numer'];
            
            // Fetch document details to get the actual proforma number (e.g. "FP/01/2025")
            $details = $this->api_client->get_document_details( $api_numer );
            $document_number = '';
            
            if ( ! is_wp_error( $details ) && isset( $details['dokument_numer'] ) ) {
                $document_number = $details['dokument_numer'];
            }
            
            // Verify total amount match
            $has_total_mismatch = false;
            if ( ! is_wp_error( $details ) && isset( $details['wartosc_brutto'] ) ) {
                // Get proforma total from Fakturowo (wartosc_brutto is in PLN, may be string or number)
                $proforma_total = floatval( $details['wartosc_brutto'] );
                
                // Compare with order total (gross total including taxes)
                $order_total = floatval( $order->get_total() );
                $total_difference = abs( $proforma_total - $order_total );
                
                // Any difference, even 0.01 grosz, should be marked as mismatch
                // Use small tolerance (0.001) to account for float precision issues
                $has_total_mismatch = $total_difference >= 0.001;
                
                if ( $has_total_mismatch ) {
                    $order->update_meta_data( '_fakturowo_proforma_total_mismatch', 'yes' );
                    $order->update_meta_data( '_fakturowo_proforma_order_total', $order_total );
                    $order->update_meta_data( '_fakturowo_proforma_fakturowo_total', $proforma_total );
                    $order->update_meta_data( '_fakturowo_proforma_total_difference', $total_difference );
                    
                    /* translators: 1: Proforma number/ID, 2: Order total, 3: Proforma total */
                    $order->add_order_note( sprintf( 
                        __( 'Fakturowo Proforma created: %1$s (Total mismatch: Order %2$s vs Proforma %3$s)', 'invoicing-integration-for-fakturowo-and-woocommerce' ), 
                        $document_number ? $document_number : $api_numer,
                        number_format( $order_total, 2, ',', ' ' ),
                        number_format( $proforma_total, 2, ',', ' ' )
                    ) );
                } else {
                    $order->delete_meta_data( '_fakturowo_proforma_total_mismatch' );
                    $order->delete_meta_data( '_fakturowo_proforma_order_total' );
                    $order->delete_meta_data( '_fakturowo_proforma_fakturowo_total' );
                    $order->delete_meta_data( '_fakturowo_proforma_total_difference' );
                    
                    /* translators: %s: Proforma number */
                    $order->add_order_note( sprintf( __( 'Fakturowo Proforma created: %s', 'invoicing-integration-for-fakturowo-and-woocommerce' ), $document_number ? $document_number : $api_numer ) );
                }
            } else {
                /* translators: %s: Proforma number */
                $order->add_order_note( sprintf( __( 'Fakturowo Proforma created: %s', 'invoicing-integration-for-fakturowo-and-woocommerce' ), $document_number ? $document_number : $api_numer ) );
            }
            
            // Save both: api_numer (for API operations) and dokument_numer (for display)
            $order->update_meta_data( '_fakturowo_proforma_id', $api_numer );
            $order->update_meta_data( '_fakturowo_proforma_number', $document_number ? $document_number : $api_numer );
            
            // Build preview URL - use API response if available, otherwise construct from base URL
            $preview_url = '';
            if ( isset( $response['preview_url'] ) && $response['preview_url'] !== '' ) {
                $preview_url = $response['preview_url'];
            } else {
                // Construct URL from api_url setting: https://konto.fakturowo.pl/pokaz/{api_numer}
                $settings = get_option( 'devikit_fakturowo_settings', [] );
                $api_url = isset( $settings['api_url'] ) ? $settings['api_url'] : '';
                if ( $api_url ) {
                    // Remove /api from the end and add /pokaz/{api_numer}
                    $base_url = preg_replace( '/\/api\/?$/', '', $api_url );
                    $preview_url = $base_url . '/pokaz/' . $api_numer;
                }
            }
            
            if ( $preview_url ) {
                $order->update_meta_data( '_fakturowo_proforma_url', $preview_url );
            }
            
            $order->save();
            
            // Only send email if totals match
            if ( ! $has_total_mismatch ) {
                // Trigger email (if PRO is active and enabled)
                $this->maybe_send_proforma_email( $order, $response, $document_number );
            }
            
            return $api_numer;
        }

        return new \WP_Error( 'fakturowo_unknown_error', 'Unknown response from Fakturowo API' );
    }
    
    /**
     * Maybe send proforma email
     * 
     * @param \WC_Order $order
     * @param array $response Proforma data from API
     * @param string $document_number Actual proforma number (e.g. "FP/01/2025")
     */
    private function maybe_send_proforma_email( $order, $response, $document_number = '' ) {
        $this->api_client->log( 'Checking if proforma email should be sent', 'debug' );
        
        // Check for total mismatch - do not send email if totals don't match
        $has_total_mismatch = $order->get_meta( '_fakturowo_proforma_total_mismatch' ) === 'yes';
        if ( $has_total_mismatch ) {
            $this->api_client->log( 'Proforma total mismatch detected - email not sent', 'debug' );
            return;
        }
        
        // Check if PRO version is active
        if ( ! class_exists( 'Devikit\FakturowoPro\Plugin' ) ) {
            $this->api_client->log( 'PRO version not active - email not sent', 'debug' );
            return;
        }
        
        $this->api_client->log( 'PRO version active', 'debug' );
        
        // Get PRO settings
        $pro_settings = get_option( 'woocommerce_fakturowo_pro_settings', [] );
        
        $this->api_client->log( 'PRO settings: ' . wp_json_encode( [
            'send_proforma_email' => $pro_settings['send_proforma_email'] ?? 'not set'
        ], JSON_UNESCAPED_UNICODE ), 'debug' );
        
        // Check if auto email sending is enabled
        if ( empty( $pro_settings['send_proforma_email'] ) || $pro_settings['send_proforma_email'] !== 'yes' ) {
            $this->api_client->log( 'Auto proforma email sending disabled - email not sent', 'debug' );
            return;
        }
        
        // Force load WooCommerce emails (required for automation context)
        WC()->mailer();
        $this->api_client->log( 'WooCommerce mailer loaded', 'debug' );
        
        // Build preview URL - use API response if available, otherwise construct from base URL
        $preview_url = '';
        if ( isset( $response['preview_url'] ) && $response['preview_url'] !== '' ) {
            $preview_url = $response['preview_url'];
        } else if ( isset( $response['api_numer'] ) && $response['api_numer'] !== '' ) {
            // Construct URL from api_url setting: https://konto.fakturowo.pl/pokaz/{api_numer}
            $settings = get_option( 'devikit_fakturowo_settings', [] );
            $api_url = isset( $settings['api_url'] ) ? $settings['api_url'] : '';
            if ( $api_url ) {
                // Remove /api from the end and add /pokaz/{api_numer}
                $base_url = preg_replace( '/\/api\/?$/', '', $api_url );
                $preview_url = $base_url . '/pokaz/' . $response['api_numer'];
            }
        }
        
        // Prepare proforma data for email
        $proforma_data = [
            'url' => $preview_url,
            'number' => $document_number ? $document_number : ( $response['api_numer'] ?? '' ),
            'id' => $response['api_numer'] ?? ''
        ];
        
        $this->api_client->log( 'Triggering proforma email hook with data: ' . wp_json_encode( $proforma_data, JSON_UNESCAPED_UNICODE ), 'debug' );
        
        // Check if there are any listeners
        $has_listeners = has_action( 'devikit_fakturowo_proforma_generated' );
        $this->api_client->log( 'Hook listeners count: ' . ( $has_listeners ? $has_listeners : '0' ), 'debug' );
        
        // Trigger email hook
        do_action( 'devikit_fakturowo_proforma_generated', $order->get_id(), $proforma_data );
        
        $this->api_client->log( 'Proforma email hook triggered', 'debug' );
        
        // Add order note about email being sent
        $order->add_order_note( __( 'Proforma email sent to customer automatically', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
    }
    
    /**
     * Maybe send invoice email
     * 
     * For automatic invoice creation, the email is delayed by 5 minutes
     * to allow KSeF (Krajowy System e-Faktur) to process the invoice first.
     * Manual invoice creation (by admin) sends the email immediately.
     *
     * @param \WC_Order $order
     * @param array $response Invoice data from API
     * @param string $document_number Actual invoice number (e.g. "FV/01/2025")
     * @param bool $is_automatic Whether invoice was created automatically (for delayed email)
     */
    private function maybe_send_invoice_email( $order, $response, $document_number = '', $is_automatic = false ) {
        $this->api_client->log( 'Checking if invoice email should be sent', 'debug' );
        
        // Check for total mismatch - do not send email if totals don't match
        $has_total_mismatch = $order->get_meta( '_fakturowo_invoice_total_mismatch' ) === 'yes';
        if ( $has_total_mismatch ) {
            $this->api_client->log( 'Invoice total mismatch detected - email not sent', 'debug' );
            return;
        }
        
        // Check if PRO version is active
        if ( ! class_exists( 'Devikit\FakturowoPro\Plugin' ) ) {
            $this->api_client->log( 'PRO version not active - email not sent', 'debug' );
            return;
        }
        
        $this->api_client->log( 'PRO version active', 'debug' );
        
        // Get PRO settings
        $pro_settings = get_option( 'woocommerce_fakturowo_pro_settings', [] );
        
        $this->api_client->log( 'PRO settings: ' . wp_json_encode( [
            'send_invoice_email' => $pro_settings['send_invoice_email'] ?? 'not set'
        ], JSON_UNESCAPED_UNICODE ), 'debug' );
        
        // Check if auto email sending is enabled
        if ( empty( $pro_settings['send_invoice_email'] ) || $pro_settings['send_invoice_email'] !== 'yes' ) {
            $this->api_client->log( 'Auto email sending disabled - email not sent', 'debug' );
            return;
        }
        
        // Build preview URL - use API response if available, otherwise construct from base URL
        $preview_url = '';
        if ( isset( $response['preview_url'] ) && $response['preview_url'] !== '' ) {
            $preview_url = $response['preview_url'];
        } else if ( isset( $response['api_numer'] ) && $response['api_numer'] !== '' ) {
            // Construct URL from api_url setting: https://konto.fakturowo.pl/pokaz/{api_numer}
            $settings = get_option( 'devikit_fakturowo_settings', [] );
            $api_url = isset( $settings['api_url'] ) ? $settings['api_url'] : '';
            if ( $api_url ) {
                // Remove /api from the end and add /pokaz/{api_numer}
                $base_url = preg_replace( '/\/api\/?$/', '', $api_url );
                $preview_url = $base_url . '/pokaz/' . $response['api_numer'];
            }
        }
        
        // Prepare invoice data for hook
        $invoice_data = [
            'url' => $preview_url,
            'number' => $document_number ? $document_number : ( $response['api_numer'] ?? '' ),
            'id' => $response['api_numer'] ?? '',
            'uuid' => null
        ];
        
        if ( $is_automatic ) {
            // Schedule email with 5-minute delay to allow KSeF processing
            $delay_minutes = apply_filters( 'devikit_fakturowo_invoice_email_delay_minutes', 5 );
            
            as_schedule_single_action(
                time() + ( $delay_minutes * 60 ),
                'devikit_fakturowo_send_delayed_invoice_email',
                [
                    'order_id'     => $order->get_id(),
                    'invoice_data' => $invoice_data,
                ],
                'devikit-fakturowo'
            );
            
            $order->add_order_note( sprintf(
                /* translators: %d: delay in minutes */
                __( 'Invoice email scheduled — will be sent in %d minutes (waiting for KSeF processing)', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                $delay_minutes
            ) );
            $order->save();
        } else {
            // Manual invoice creation — send immediately
            WC()->mailer();
            $this->api_client->log( 'Triggering invoice generated hook with data: ' . wp_json_encode( $invoice_data, JSON_UNESCAPED_UNICODE ), 'debug' );
            do_action( 'devikit_fakturowo_invoice_generated', $order->get_id(), $invoice_data );
            $this->api_client->log( 'Invoice generated hook triggered', 'debug' );
            $order->add_order_note( __( 'Invoice email sent to customer automatically', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        }
    }
    
    /**
     * Handle delayed invoice email (called by Action Scheduler)
     *
     * @param int   $order_id     Order ID
     * @param array $invoice_data Invoice data (url, number, id)
     */
    public function handle_delayed_invoice_email( $order_id, $invoice_data ) {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return;
        }
        
        WC()->mailer();
        do_action( 'devikit_fakturowo_invoice_generated', $order_id, $invoice_data );
        
        $order->add_order_note( __( 'Invoice email sent to customer (delayed — after KSeF processing)', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
    }

    /**
     * Get or Create Client
     * 
     * @param \WC_Order $order
     * @return int|WP_Error
     */
    private function get_or_create_client( $order ) {
        $nip = $order->get_meta( '_billing_nip' ); // Common plugin format
        if ( empty( $nip ) ) {
             $nip = $order->get_meta( 'vat_number' ); // Another common format
        }
        // Fallback for PL NIP if valid
        $billing_country = $order->get_billing_country();
        if( empty($nip) && $billing_country === 'PL' ) {
            // NIP not found? Try to proceed without NIP (private person) or return error depending on requirements.
            // Fakturowo usually requires NIP for companies.
        }

        $is_company = ! empty( $order->get_billing_company() );
        
        $client_data = [
            'street'       => $order->get_billing_address_1(),
            'street_number'=> '',
            'flat_number'  => '',
            'city'         => $order->get_billing_city(),
            'country'      => $order->get_billing_country(),
            'postal_code'  => $order->get_billing_postcode(),
            'phone_number' => $order->get_billing_phone(),
            'email'        => $order->get_billing_email(),
        ];
        
        // For companies
        if ( $is_company ) {
            $client_data['company_name'] = $order->get_billing_company();
            $client_data['business_activity_kind'] = 'other_business';
            // Companies in Fakturowo cannot have first_name and last_name
        } else {
            // For individuals (private persons)
            $client_data['first_name'] = $order->get_billing_first_name();
            $client_data['last_name'] = $order->get_billing_last_name();
            // For private persons, create company_name from first and last name
            $client_data['company_name'] = trim( $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() );
            $client_data['business_activity_kind'] = 'private_person';
        }

        // Basic heuristic for street number
        if ( preg_match( '/^(.+)\s+(\d+[a-zA-Z]*(\/\d+)?)$/', $client_data['street'], $matches ) ) {
            $client_data['street'] = $matches[1];
            $client_data['street_number'] = $matches[2];
        }
        
        // Flat number from address_2 (e.g., apartment number)
        $address_2 = $order->get_billing_address_2();
        if ( ! empty( $address_2 ) ) {
            $client_data['flat_number'] = $address_2;
        }

        if ( ! empty( $nip ) ) {
            // Remove only dashes and spaces, preserve country code and digits
            $nip = preg_replace( '/[\s\-]/', '', $nip );
            $client_data['nip'] = $nip;
            
            $existing_client = $this->api_client->get_client_by_nip( $nip );
            if ( $existing_client ) {
                // Log existing client data for debugging
                $this->api_client->log( 'Existing client found: ' . wp_json_encode( $existing_client, JSON_UNESCAPED_UNICODE ), 'debug' );
                $this->api_client->log( 'New client data from order: ' . wp_json_encode( $client_data, JSON_UNESCAPED_UNICODE ), 'debug' );
                
                // ALWAYS update existing client with new data from order
                $update_result = $this->api_client->update_client( $existing_client['id'], $client_data );
                
                if ( is_wp_error( $update_result ) ) {
                    $this->api_client->log( 'Failed to update client: ' . $update_result->get_error_message(), 'error' );
                } else {
                    $this->api_client->log( 'Client updated successfully', 'info' );
                }
                
                // Return client ID regardless of update result
                return $existing_client['id'];
            }
        }

        // Create new client
        $response = $this->api_client->create_client( $client_data );

        if ( is_wp_error( $response ) ) {
            return $response;
        }

        return isset( $response['id'] ) ? $response['id'] : new \WP_Error( 'create_client_fail', 'Failed to create client' );
    }

    /**
     * Prepare Invoice Data
     * 
     * @param \WC_Order $order
     * @param int $client_id
     * @return array
     */
    private function prepare_invoice_data( $order, $client_id ) {
        $settings = get_option( 'devikit_fakturowo_settings', [] );
        $payment_method = $order->get_payment_method_title();
        
        // Invoice date = today (when invoice is issued)
        // Sale date = order creation date (when transaction happened)
        $invoice_date = current_time( 'Y-m-d' );
        $sale_date = $order->get_date_created()->date( 'Y-m-d' );
        
        $data = [
            'client_id' => $client_id,
            'currency' => $order->get_currency(), // Order currency (e.g., PLN, USD, EUR)
            'payment_method' => $payment_method, // Fakturowo has specific dictionary for this? Usually maps to 'transfer', 'cash', etc. Free version: just send string or map basic ones.
            'invoice_date' => $invoice_date,
            'sale_date' => $sale_date,
            'services' => []
        ];
        
        // Add payment deadline (days)
        if ( ! empty( $settings['payment_deadline_days'] ) ) {
            $data['payment_date'] = gmdate( 'Y-m-d', strtotime( $date . ' + ' . intval( $settings['payment_deadline_days'] ) . ' days' ) );
        }
        
        // Add paid price - determines if invoice shows "paid" or "to pay"
        // This will be set to 0 for proformas later (via filter or kind check)
        $data['paid_price'] = $this->get_order_paid_price( $order );
        
        $this->api_client->log( 'Order payment status: ' . wp_json_encode( [
            'is_paid' => $order->is_paid(),
            'payment_method' => $order->get_payment_method(),
            'status' => $order->get_status(),
            'currency' => $order->get_currency(),
            'paid_price' => $data['paid_price'],
            'total' => $order->get_total()
        ], JSON_UNESCAPED_UNICODE ), 'debug' );
        
        // Add bank account if configured (for all payment methods that need it)
        if ( ! empty( $settings['bank_account'] ) ) {
            $data['bank_account'] = $settings['bank_account'];
        }
        
        // Add VAT exemption reason
        if ( ! empty( $settings['vat_exemption_reason'] ) ) {
            $data['vat_exemption_reason'] = (string) $settings['vat_exemption_reason'];
        }
        
        // Add income marking (transaction category)
        if ( ! empty( $settings['income_marking'] ) ) {
            $data['document_markings_ids'] = [ (int) $settings['income_marking'] ];
        }

        // Check if flat rate (ryczałt) is enabled
        $flat_rate_enabled = isset( $settings['is_flat_rate'] ) && $settings['is_flat_rate'] === 'yes';
        $flat_rate_default = isset( $settings['flat_rate_default'] ) ? $settings['flat_rate_default'] : '';
        $flat_rate_attribute = isset( $settings['flat_rate_attribute'] ) ? $settings['flat_rate_attribute'] : '';
        
        // Map Items
        foreach ( $order->get_items() as $item ) {
            $product = $item->get_product();
            
            // Get tax rate from item
            $tax_rate = $this->get_item_tax_rate( $item, $settings );
            
            // Calculate unit price (total / quantity)
            $unit_price = $item->get_total() / $item->get_quantity();
            
            // Format product name based on settings
            $product_name = $this->format_product_name( $item, $product, $settings );
            
            $service = [
                'name' => $product_name,
                'tax_symbol' => $tax_rate,
                'unit_net_price' => $this->format_price_for_fakturowo( $unit_price ),
                'quantity' => $item->get_quantity(),
                'unit' => 'szt.',
            ];
            
            // Add flat rate if enabled
            if ( $flat_rate_enabled && $product ) {
                $flat_rate_value = '';
                
                // Try to get from product attribute
                if ( ! empty( $flat_rate_attribute ) ) {
                    $flat_rate_value = $product->get_attribute( $flat_rate_attribute );
                    
                    // If variation, try parent product
                    if ( empty( $flat_rate_value ) && $product instanceof \WC_Product_Variation ) {
                        $parent = wc_get_product( $product->get_parent_id() );
                        if ( $parent ) {
                            $flat_rate_value = $parent->get_attribute( $flat_rate_attribute );
                        }
                    }
                }
                
                // Use default if no attribute value
                if ( empty( $flat_rate_value ) && ! empty( $flat_rate_default ) ) {
                    $flat_rate_value = $flat_rate_default;
                }
                
                if ( ! empty( $flat_rate_value ) ) {
                    // Convert to proper format (remove % and , then convert to float as string)
                    $service['flat_rate_tax_symbol'] = $this->format_flat_rate( $flat_rate_value );
                }
            }
            
            $data['services'][] = $service;
        }

        // Shipping
        $shipping_items = $order->get_items( 'shipping' );
        foreach ( $shipping_items as $shipping_item ) {
            if ( $shipping_item instanceof \WC_Order_Item_Shipping && $shipping_item->get_total() > 0 ) {
                // Calculate shipping tax rate
                $shipping_tax_rate = $this->get_shipping_tax_rate( $shipping_item, $settings, $data['services'] );
                
                $shipping_service = [
                    'name' => ! empty( $shipping_item->get_name() ) ? $shipping_item->get_name() : __( 'Shipping', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                    'tax_symbol' => $shipping_tax_rate,
                    'unit_net_price' => $this->format_price_for_fakturowo( $shipping_item->get_total() ),
                    'quantity' => 1,
                    'unit' => 'usł.',
                ];
                
                // Add flat rate for shipping if enabled
                if ( $flat_rate_enabled && ! empty( $flat_rate_default ) ) {
                    $shipping_service['flat_rate_tax_symbol'] = $this->format_flat_rate( $flat_rate_default );
                }
                
                $data['services'][] = $shipping_service;
            }
        }

        return $data;
    }

    /**
     * Get tax rate for order item
     * 
     * @param \WC_Order_Item_Product $item
     * @param array $settings
     * @return string
     */
    private function get_item_tax_rate( $item, $settings ) {
        $product = $item->get_product();
        
        if ( ! $product ) {
            return '23'; // Default
        }
        
        // Get product tax class
        $tax_class = $product->get_tax_class();
        
        // Check if tax class is mapped to special rates
        if ( ! empty( $tax_class ) ) {
            // Exempt rate mapping (zw - zwolnione)
            if ( isset( $settings['tax_class_zw'] ) && $settings['tax_class_zw'] !== '_none_' && $settings['tax_class_zw'] === $tax_class ) {
                return 'zw';
            }
            
            // Zero rate mapping (0 - zero VAT)
            if ( isset( $settings['tax_class_zero'] ) && $settings['tax_class_zero'] !== '_none_' && $settings['tax_class_zero'] === $tax_class ) {
                return '0';
            }
            
            // Not applicable mapping (np - nie podlega)
            if ( isset( $settings['tax_class_np'] ) && $settings['tax_class_np'] !== '_none_' && $settings['tax_class_np'] === $tax_class ) {
                return 'np';
            }
        }
        
        // Try to calculate from actual tax amount
        $total = $item->get_total();
        $tax = $item->get_total_tax();
        
        if ( $total > 0 && $tax > 0 ) {
            $rate = ( $tax / $total ) * 100;
            
            // Round to common rates
            if ( $rate >= 22 && $rate <= 24 ) {
                return '23';
            } elseif ( $rate >= 7 && $rate <= 9 ) {
                return '8';
            } elseif ( $rate >= 4 && $rate <= 6 ) {
                return '5';
            } elseif ( $rate < 1 ) {
                return '0'; // 0% VAT
            }
        } elseif ( $total > 0 && $tax == 0 ) {
            // No tax - check if explicitly mapped, otherwise default to 0
            return '0';
        }
        
        // Default to 23%
        return '23';
    }

    /**
     * Get tax rate for shipping item
     * 
     * @param \WC_Order_Item_Shipping $item
     * @param array $settings
     * @param array $product_services Already processed product services
     * @return string
     */
    private function get_shipping_tax_rate( $item, $settings, $product_services = [] ) {
        // Priority 1: Inherit from products (WooCommerce behavior)
        $inherited_rate = null;
        
        if ( ! empty( $product_services ) ) {
            // Collect all tax rates from products
            $tax_rates = [];
            $has_standard_rate = false;
            
            foreach ( $product_services as $service ) {
                if ( isset( $service['vat'] ) ) {
                    $tax = $service['vat'];
                    $tax_rates[] = $tax;
                    
                    // Check if any product has standard rate (23, 8, 5)
                    if ( in_array( $tax, [ '23', '8', '5' ], true ) ) {
                        $has_standard_rate = true;
                    }
                }
            }
            
            // If any product has standard VAT rate, use the HIGHEST standard rate for shipping
            if ( $has_standard_rate ) {
                if ( in_array( '23', $tax_rates, true ) ) {
                    $inherited_rate = '23';
                } elseif ( in_array( '8', $tax_rates, true ) ) {
                    $inherited_rate = '8';
                } elseif ( in_array( '5', $tax_rates, true ) ) {
                    $inherited_rate = '5';
                }
            } else {
                // If ALL products have the same special rate (zw, np, 0), use it for shipping
                $unique_rates = array_unique( $tax_rates );
                if ( count( $unique_rates ) === 1 ) {
                    $rate = $unique_rates[0];
                    if ( in_array( $rate, [ 'zw', 'np', '0' ], true ) ) {
                        $inherited_rate = $rate;
                    }
                }
            }
        }
        
        // Priority 2: Shipping tax class mapping (explicit override)
        $tax_class = $item->get_tax_class();
        
        if ( ! empty( $tax_class ) ) {
            // Exempt rate mapping (zw - zwolnione)
            if ( isset( $settings['tax_class_zw'] ) && $settings['tax_class_zw'] !== '_none_' && $settings['tax_class_zw'] === $tax_class ) {
                return 'zw';
            }
            
            // Zero rate mapping (0 - zero VAT)
            if ( isset( $settings['tax_class_zero'] ) && $settings['tax_class_zero'] !== '_none_' && $settings['tax_class_zero'] === $tax_class ) {
                return '0';
            }
            
            // Not applicable mapping (np - nie podlega)
            if ( isset( $settings['tax_class_np'] ) && $settings['tax_class_np'] !== '_none_' && $settings['tax_class_np'] === $tax_class ) {
                return 'np';
            }
        }
        
        // Priority 3: Return inherited rate from products if available
        if ( $inherited_rate !== null ) {
            return $inherited_rate;
        }
        
        // Priority 4: Calculate from actual tax amount (last resort)
        $total = $item->get_total();
        $tax = $item->get_total_tax();
        
        if ( $total > 0 && $tax > 0 ) {
            $rate = ( $tax / $total ) * 100;
            
            // Round to common rates
            if ( $rate >= 22 && $rate <= 24 ) {
                return '23';
            } elseif ( $rate >= 7 && $rate <= 9 ) {
                return '8';
            } elseif ( $rate >= 4 && $rate <= 6 ) {
                return '5';
            } elseif ( $rate < 1 ) {
                return '0';
            }
        }
        
        // Default to 23%
        return '23';
    }

    /**
     * Format price for Fakturowo API (grosze as integer string)
     * 
     * @param float $price Price in PLN
     * @return string Price in grosze (cents)
     */
    private function format_price_for_fakturowo( $price ) {
        // Convert to float and ensure 2 decimal places
        $price = (float) $price;
        
        // Format as string without decimal separator (grosze)
        // 8.13 PLN → "813" (813 grosze)
        return number_format( $price, 2, '', '' );
    }

    /**
     * Format flat rate value for Fakturowo API
     * 
     * @param string $flat_rate Flat rate value (e.g., "8.5%", "8,5", "8.5")
     * @return float|string Formatted flat rate (Fakturowo accepts both float and string)
     */
    private function format_flat_rate( $flat_rate ) {
        // Remove % sign
        $flat_rate = str_replace( '%', '', $flat_rate );
        // Replace comma with dot
        $flat_rate = str_replace( ',', '.', $flat_rate );
        // Convert to float (Fakturowo API accepts numeric values for flat_rate_tax_symbol)
        return floatval( $flat_rate );
    }
    
    /**
     * Get order paid price
     * 
     * Determines how much of the order has been paid.
     * If order is paid, returns total amount, otherwise 0.
     * This affects whether invoice shows "paid" or "to pay" in Fakturowo.
     * 
     * IMPORTANT: Returns raw float/int in PLN (NOT formatted as grosze like net_price!)
     * Example: 20.00 PLN → returns 20 (or 20.0)
     * 
     * @param \WC_Order $order
     * @return float|int Paid amount in PLN
     */
    private function get_order_paid_price( $order ) {
        // For COD (cash on delivery), only mark as paid if order is completed
        if ( $order->get_payment_method() === 'cod' && $order->get_status() !== 'completed' ) {
            return 0;
        }
        
        // Check if order is paid (has payment date)
        if ( ! $order->is_paid() ) {
            return 0;
        }
        
        // Return as-is from WooCommerce (float in PLN, e.g., 20.0)
        // Do NOT format as grosze - that's only for net_price fields
        return $order->get_total();
    }

    /**
     * Format product name based on settings (PRO feature)
     * 
     * @param \WC_Order_Item_Product $item
     * @param \WC_Product|null $product
     * @param array $settings
     * @return string Formatted product name
     */
    private function format_product_name( $item, $product, $settings ) {
        $name = $item->get_name();
        
        // Check if PRO version is active and has product_name_format setting
        if ( class_exists( 'Devikit\FakturowoPro\Plugin' ) ) {
            $pro_settings = get_option( 'woocommerce_fakturowo_pro_settings', [] );
            $format = isset( $pro_settings['product_name_format'] ) ? $pro_settings['product_name_format'] : 'name';
            
            if ( $product && $format !== 'name' ) {
                $sku = $product->get_sku();
                
                if ( ! empty( $sku ) ) {
                    switch ( $format ) {
                        case 'name_sku':
                            // "Product Name [SKU123]"
                            $name .= ' [' . $sku . ']';
                            break;
                        case 'sku_name':
                            // "[SKU123] Product Name"
                            $name = '[' . $sku . '] ' . $name;
                            break;
                    }
                }
            }
        }
        
        return $name;
    }

    /**
     * Prepare Fakturowo document payload (API v1, api_zadanie=1).
     *
     * @param \WC_Order $order
     * @param int $document_type dokument_rodzaj (0=Faktura VAT, 2=Proforma)
     * @return array
     */
    private function prepare_document_data( $order, $document_type = 0 ) {
        $settings = get_option( 'devikit_fakturowo_settings', [] );

        $document_date_w = current_time( 'd-m-Y' );
        $document_date_s = $order->get_date_created() ? $order->get_date_created()->date( 'd-m-Y' ) : current_time( 'd-m-Y' );

        // Buyer (nabywca_*) - sprzedawca_* nie jest wymagany jeśli ustawiony domyślny sprzedawca w Fakturowo.
        $company = $order->get_billing_company();
        $first_name = $order->get_billing_first_name();
        $last_name = $order->get_billing_last_name();

        $nip = $order->get_meta( '_billing_nip' );
        if ( empty( $nip ) ) {
            $nip = $order->get_meta( 'vat_number' );
        }
        // Remove only dashes and spaces, preserve country code and digits
        $nip = ! empty( $nip ) ? preg_replace( '/[\s\-]/', '', (string) $nip ) : '';

        $address = $this->split_street_and_numbers( $order->get_billing_address_1(), $order->get_billing_address_2() );

        // Determine if this is a private person (no company name and no NIP)
        $is_private_person = empty( $company ) && empty( $nip );

        // Get billing country code (ISO 3166-1 alpha-2, e.g., PL, DE, US)
        $billing_country = $order->get_billing_country();
        
        if ( $is_private_person ) {
            // Private person - use nabywca_osoba=1 + nabywca_imie/nabywca_nazwisko
            $buyer = [
                'nabywca_osoba'    => '1',
                'nabywca_imie'     => $first_name,
                'nabywca_nazwisko' => $last_name,
                'nabywca_miasto'   => $order->get_billing_city(),
                'nabywca_kod'      => $order->get_billing_postcode(),
                'nabywca_ulica'    => $address['street'],
                'nabywca_budynek'  => $address['building'],
                'nabywca_lokal'    => $address['local'],
            ];
            
            // Add country code if available
            if ( ! empty( $billing_country ) ) {
                $buyer['nabywca_kraj'] = strtoupper( $billing_country );
            }
        } else {
            // Company or person with NIP - use nabywca_nazwa + nabywca_nip
            $buyer_name = ! empty( $company ) ? $company : trim( $first_name . ' ' . $last_name );
            
            $buyer = [
                'nabywca_nazwa'   => $buyer_name,
                'nabywca_nip'     => $nip,
                'nabywca_miasto'  => $order->get_billing_city(),
                'nabywca_kod'     => $order->get_billing_postcode(),
                'nabywca_ulica'   => $address['street'],
                'nabywca_budynek' => $address['building'],
                'nabywca_lokal'   => $address['local'],
            ];
            
            // Add country code if available
            if ( ! empty( $billing_country ) ) {
                $buyer['nabywca_kraj'] = strtoupper( $billing_country );
            }
        }

        // Items (produkt_*_1..N) - brutto całkowite (API Fakturowo oczekuje całkowitej wartości brutto).
        $items = [];

        foreach ( $order->get_items() as $item ) {
            $product = $item->get_product();
            $qty = (float) $item->get_quantity();
            if ( $qty <= 0 ) {
                continue;
            }

            $tax_symbol = $this->get_item_tax_rate( $item, $settings );
            $gross_total = (float) $item->get_total() + (float) $item->get_total_tax();

            $items[] = [
                'name'  => $this->format_product_name( $item, $product, $settings ),
                'qty'   => (string) (int) $qty,
                'jm'    => '2', // szt.
                'vat'   => (string) $tax_symbol,
                'gross' => number_format( $gross_total, 2, '.', '' ),
            ];
        }

        // Shipping as service (usł.=1).
        foreach ( $order->get_items( 'shipping' ) as $shipping_item ) {
            if ( ! ( $shipping_item instanceof \WC_Order_Item_Shipping ) ) {
                continue;
            }
            $gross = (float) $shipping_item->get_total() + (float) $shipping_item->get_total_tax();
            if ( $gross <= 0 ) {
                continue;
            }

            // Use the same tax rate logic as products (respects mapped tax classes)
            $vat = $this->get_shipping_tax_rate( $shipping_item, $settings, $items );

            $items[] = [
                'name'  => $shipping_item->get_name() ? $shipping_item->get_name() : __( 'Shipping', 'invoicing-integration-for-fakturowo-and-woocommerce' ),
                'qty'   => '1',
                'jm'    => '1', // usł.
                'vat'   => $vat,
                'gross' => number_format( $gross, 2, '.', '' ),
            ];
        }

        // Optional bank account -> dokument_konto (jeśli user wpisze ręcznie).
        $bank_account = isset( $settings['bank_account'] ) ? (string) $settings['bank_account'] : '';
        
        // Optional seller signature -> sprzedawca_podpis
        $seller_signature = isset( $settings['seller_signature'] ) ? (string) $settings['seller_signature'] : '';
        
        // Payment method for Fakturowo API (dokument_zaplata)
        $payment_method = $order->get_payment_method_title();

        $payload = [
            'document_type'   => (int) $document_type,
            'document_access' => 1, // Enable public access to get preview_url
            'document_date_w' => $document_date_w,
            'document_date_s' => $document_date_s,
            'buyer'           => $buyer,
            'items'           => $items,
        ];
        
        // Check if order is paid
        $is_paid = $order->is_paid();
        
        // Add payment deadline ONLY for unpaid orders
        // dokument_termin expects text like "7 dni", "14 dni" etc.
        if ( ! $is_paid ) {
            if ( ! empty( $settings['payment_deadline_days'] ) ) {
                $payload['dokument_termin'] = (int) $settings['payment_deadline_days'] . ' dni';
            } else {
                // Default to 14 days (Fakturowo default)
                $payload['dokument_termin'] = '14 dni';
            }
        }
        
        // Add payment method (dokument_zaplata)
        // Map WooCommerce payment method to Fakturowo payment type code
        if ( ! empty( $payment_method ) ) {
            $payload['dokument_zaplata'] = $this->map_payment_method( $payment_method, $order );
        }

        if ( $bank_account !== '' ) {
            $payload['dokument_konto'] = $bank_account;
        }
        
        // Add seller signature if provided
        if ( $seller_signature !== '' ) {
            $payload['sprzedawca_podpis'] = $seller_signature;
        }
        
        // Add paid amount (zapłacono) - determines if invoice shows "paid" or "to pay"
        $paid_price = $this->get_order_paid_price( $order );
        if ( $paid_price > 0 ) {
            $payload['dokument_zaplacono'] = number_format( $paid_price, 2, '.', '' );
        }

        // Add currency (dokument_waluta)
        $currency_code = $order->get_currency();
        $fakturowo_currency = $this->map_currency_code( $currency_code );
        if ( $fakturowo_currency !== null ) {
            $payload['dokument_waluta'] = (string) $fakturowo_currency;
        }

        return $payload;
    }

    /**
     * Split billing address into street + building + local.
     *
     * @param string $address_1
     * @param string $address_2
     * @return array{street:string,building:string,local:string}
     */
    private function split_street_and_numbers( $address_1, $address_2 ) {
        $street = (string) $address_1;
        $building = '';
        $local = '';

        // Try to parse last token as building[/local]
        if ( preg_match( '/^(.+?)\\s+(\\d+[a-zA-Z]?)(?:\\/(\\d+[a-zA-Z]?))?$/u', trim( $street ), $m ) ) {
            $street = trim( $m[1] );
            $building = $m[2];
            $local = isset( $m[3] ) ? $m[3] : '';
        }

        // If local still empty, try address_2
        if ( $local === '' && ! empty( $address_2 ) ) {
            $local = trim( (string) $address_2 );
        }

        return [
            'street' => $street,
            'building' => $building,
            'local' => $local,
        ];
    }
    
    /**
     * Map currency ISO code to Fakturowo currency code
     *
     * @param string $currency_code ISO 4217 currency code (e.g., PLN, EUR, USD)
     * @return int|null Fakturowo currency code or null if not found
     */
    private function map_currency_code( $currency_code ) {
        $currency_code = strtoupper( trim( (string) $currency_code ) );
        
        // Map according to Fakturowo API documentation
        $mapping = [
            'PLN' => 0,   // PLN
            'EUR' => 1,   // EUR
            'USD' => 2,   // USD
            'GBP' => 3,   // GBP
            'CHF' => 4,   // CHF
            'CAD' => 5,   // CAD
            'AUD' => 6,   // AUD
            'JPY' => 7,   // JPY
            'THB' => 8,   // THB
            'HKD' => 9,   // HKD
            'NZD' => 10,  // NZD
            'SGD' => 11,  // SGD
            'HUF' => 12,  // HUF
            'UAH' => 13,  // UAH
            'CZK' => 14,  // CZK
            'DKK' => 15,  // DKK
            'ISK' => 16,  // ISK
            'NOK' => 17,  // NOK
            'SEK' => 18,  // SEK
            'HRK' => 19,  // HRK
            'RON' => 20,  // RON
            'BGN' => 21,  // BGN
            'TRY' => 22,  // TRY
            'ILS' => 23,  // ILS
            'CLP' => 24,  // CLP
            'PHP' => 25,  // PHP
            'MXN' => 26,  // MXN
            'ZAR' => 27,  // ZAR
            'BRL' => 28,  // BRL
            'MYR' => 29,  // MYR
            'RUB' => 30,  // RUB
            'IDR' => 31,  // IDR
            'INR' => 32,  // INR
            'KRW' => 33,  // KRW
            'CNY' => 34,  // CNY
            'XDR' => 35,  // XDR
            'AED' => 36,  // AED
            'AFN' => 37,  // AFN
            'MGA' => 38,  // MGA
            'PAB' => 39,  // PAB
            'ETB' => 40,  // ETB
            'VEF' => 41,  // VEF
            'BOB' => 42,  // BOB
            'CRC' => 43,  // CRC
            'SVC' => 44,  // SVC
            'NIO' => 45,  // NIO
            'GMD' => 46,  // GMD
            'MKD' => 47,  // MKD
            'DZD' => 48,  // DZD
            'BHD' => 49,  // BHD
            'IQD' => 50,  // IQD
            'JOD' => 51,  // JOD
            'KWD' => 52,  // KWD
            'LYD' => 53,  // LYD
            'RSD' => 54,  // RSD
            'TND' => 55,  // TND
            'MAD' => 56,  // MAD
            'STD' => 57,  // STD
            'BSD' => 58,  // BSD
            'BBD' => 59,  // BBD
            'BZD' => 60,  // BZD
            'BND' => 61,  // BND
            'FJD' => 62,  // FJD
            'GYD' => 63,  // GYD
            'JMD' => 64,  // JMD
            'LRD' => 65,  // LRD
            'NAD' => 66,  // NAD
            'SRD' => 67,  // SRD
            'TTD' => 68,  // TTD
            'XCD' => 69,  // XCD
            'SBD' => 70,  // SBD
            'VND' => 71,  // VND
            'AMD' => 72,  // AMD
            'CVE' => 73,  // CVE
            'AWG' => 74,  // AWG
            'BIF' => 75,  // BIF
            'XOF' => 76,  // XOF
            'XAF' => 77,  // XAF
            'XPF' => 78,  // XPF
            'DJF' => 79,  // DJF
            'GNF' => 80,  // GNF
            'KMF' => 81,  // KMF
            'CDF' => 82,  // CDF
            'RWF' => 83,  // RWF
            'EGP' => 84,  // EGP
            'GIP' => 85,  // GIP
            'LBP' => 86,  // LBP
            'SDG' => 87,  // SDG
            'SYP' => 88,  // SYP
            'GHS' => 89,  // GHS
            'HTG' => 90,  // HTG
            'PYG' => 91,  // PYG
            'ANG' => 92,  // ANG
            'PGK' => 93,  // PGK
            'LAK' => 94,  // LAK
            'MWK' => 95,  // MWK
            'ZMW' => 96,  // ZMW
            'AOA' => 97,  // AOA
            'MMK' => 98,  // MMK
            'GEL' => 99,  // GEL
            'MDL' => 100, // MDL
            'ALL' => 101, // ALL
            'HNL' => 102, // HNL
            'SLL' => 103, // SLL
            'SZL' => 104, // SZL
            'LSL' => 105, // LSL
            'AZN' => 106, // AZN
            'MZN' => 107, // MZN
            'NGN' => 108, // NGN
            'ERN' => 109, // ERN
            'TWD' => 110, // TWD
            'PEN' => 111, // PEN
            'MRO' => 112, // MRO
            'TOP' => 113, // TOP
            'MOP' => 114, // MOP
            'ARS' => 115, // ARS
            'DOP' => 116, // DOP
            'COP' => 117, // COP
            'UYU' => 118, // UYU
            'BWP' => 119, // BWP
            'GTQ' => 120, // GTQ
            'IRR' => 121, // IRR
            'YER' => 122, // YER
            'QAR' => 123, // QAR
            'OMR' => 124, // OMR
            'SAR' => 125, // SAR
            'KHR' => 126, // KHR
            'BYN' => 127, // BYN
            'LKR' => 128, // LKR
            'MVR' => 129, // MVR
            'MUR' => 130, // MUR
            'NPR' => 131, // NPR
            'PKR' => 132, // PKR
            'SCR' => 133, // SCR
            'KGS' => 134, // KGS
            'TJS' => 135, // TJS
            'UZS' => 136, // UZS
            'KES' => 137, // KES
            'SOS' => 138, // SOS
            'TZS' => 139, // TZS
            'UGX' => 140, // UGX
            'BDT' => 141, // BDT
            'WST' => 142, // WST
            'KZT' => 143, // KZT
            'MNT' => 144, // MNT
            'VUV' => 145, // VUV
            'BAM' => 146, // BAM
            'SSP' => 147, // SSP
            'TMT' => 148, // TMT
            'CUP' => 149, // CUP
            'STN' => 150, // STN
            'MRU' => 151, // MRU
            'VES' => 152, // VES
        ];
        
        return isset( $mapping[ $currency_code ] ) ? $mapping[ $currency_code ] : null;
    }

    /**
     * Map WooCommerce payment method to Fakturowo payment method code
     *
     * @param string $payment_method Payment method title from WooCommerce
     * @param \WC_Order $order Order object
     * @return string Fakturowo payment method code (dokument_zaplata parameter)
     */
    private function map_payment_method( $payment_method, $order ) {
        $method_id = $order->get_payment_method();
        
        // Check if order is paid (use "zapłacono poprzez..." codes)
        $is_paid = $order->is_paid();
        
        // Map common WooCommerce payment methods to Fakturowo dokument_zaplata codes
        // Full list in API documentation: dokument_zaplata parameter
        $mapping = [
            // Cash on Delivery
            'cod'           => '12', // za pobraniem
            
            // Bank transfer - depends on payment deadline
            'bacs'          => $is_paid ? '14' : '0', // zapłacono przelewem : przelew
            
            // Cash
            'cash'          => $is_paid ? '15' : '13', // zapłacono gotówką : gotówka
            
            // Online payments (always "zapłacono poprzez...")
            'paypal'        => '16', // zapłacono poprzez Paypal.com
            'stripe'        => '60', // zapłacono poprzez Stripe.com
            'przelewy24'    => '20', // zapłacono poprzez Przelewy24.pl
            'payu'          => '18', // zapłacono poprzez Payu.pl
            'paynow'        => '58', // zapłacono poprzez Paynow.pl
            'paypro'        => '65', // zapłacono poprzez Paypro.pl
            'dotpay'        => '17', // zapłacono poprzez Dotpay.pl
            'tpay'          => '64', // zapłacono poprzez Tpay.com
            'cashbill'      => '19', // zapłacono poprzez Cashbill.pl
            'paybylink'     => '67', // zapłacono poprzez Paybylink.pl
            'payoneer'      => '70', // zapłacono poprzez Payoneer.com
            
            // Other
            'cheque'        => '23', // czek
        ];
        
        // Check if we have explicit mapping
        if ( isset( $mapping[ $method_id ] ) ) {
            return $mapping[ $method_id ];
        }
        
        // Fallback based on payment method title (case insensitive)
        $title_lower = strtolower( (string) $payment_method );
        
        if ( strpos( $title_lower, 'pobraniem' ) !== false || strpos( $title_lower, 'cash on delivery' ) !== false ) {
            return '12'; // za pobraniem
        } elseif ( strpos( $title_lower, 'gotówka' ) !== false || strpos( $title_lower, 'cash' ) !== false ) {
            return $is_paid ? '15' : '13'; // zapłacono gotówką : gotówka
        } elseif ( strpos( $title_lower, 'paypal' ) !== false ) {
            return '16';
        } elseif ( strpos( $title_lower, 'stripe' ) !== false ) {
            return '60';
        } elseif ( strpos( $title_lower, 'przelewy24' ) !== false ) {
            return '20';
        } elseif ( strpos( $title_lower, 'payu' ) !== false ) {
            return '18';
        } elseif ( strpos( $title_lower, 'paynow' ) !== false ) {
            return '58';
        } elseif ( strpos( $title_lower, 'paypro' ) !== false ) {
            return '65';
        } elseif ( strpos( $title_lower, 'tpay' ) !== false ) {
            return '64';
        } elseif ( strpos( $title_lower, 'dotpay' ) !== false ) {
            return '17';
        } elseif ( strpos( $title_lower, 'blik' ) !== false ) {
            return '71'; // płatność BLIK
        }
        
        // Default to transfer (przelew or zapłacono przelewem depending on payment status)
        return $is_paid ? '14' : '0'; // zapłacono przelewem : przelew
    }

    /**
     * Display invoice download button on My Account order view
     */
    public function display_invoice_download_button( $order_id ) {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return;
        }

        // Verify user can view this order
        if ( ! current_user_can( 'view_order', $order_id ) && get_current_user_id() !== $order->get_customer_id() ) {
            return;
        }

        $invoice_id = $order->get_meta( '_fakturowo_invoice_id' );
        $invoice_number = $order->get_meta( '_fakturowo_invoice_number' );

        if ( $invoice_id ) {
            $download_url = add_query_arg( [
                'action'     => 'download_fakturowo_invoice',
                'order_id'   => $order_id,
                'invoice_id' => $invoice_id,
                '_wpnonce'   => wp_create_nonce( 'download_fakturowo_invoice_' . $order_id ),
            ], home_url( '/' ) );

            echo '<p class="fakturowo-invoice-download">';
            echo '<a href="' . esc_url( $download_url ) . '" class="button" target="_blank">';
            echo esc_html__( 'Download Invoice', 'invoicing-integration-for-fakturowo-and-woocommerce' );
            if ( $invoice_number ) {
                echo ' (' . esc_html( $invoice_number ) . ')';
            }
            echo '</a>';
            echo '</p>';
        }
    }

    /**
     * Handle invoice download from frontend
     */
    public function handle_invoice_download() {
        if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'download_fakturowo_invoice' ) {
            return;
        }

        if ( ! isset( $_GET['order_id'], $_GET['invoice_id'], $_GET['_wpnonce'] ) ) {
            wp_die( esc_html__( 'Invalid request', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        }

        $order_id = absint( $_GET['order_id'] );
        $invoice_id = sanitize_text_field( wp_unslash( $_GET['invoice_id'] ) );

        if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'download_fakturowo_invoice_' . $order_id ) ) {
            wp_die( esc_html__( 'Invalid security token', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        }

        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            wp_die( esc_html__( 'Order not found', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        }

        // Verify user can view this order
        if ( ! current_user_can( 'view_order', $order_id ) && get_current_user_id() !== $order->get_customer_id() ) {
            wp_die( esc_html__( 'You do not have permission to view this invoice', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        }

        // Verify invoice ID matches order meta
        $stored_invoice_id = $order->get_meta( '_fakturowo_invoice_id' );
        if ( $stored_invoice_id != $invoice_id ) {
            wp_die( esc_html__( 'Invoice not found for this order.', 'invoicing-integration-for-fakturowo-and-woocommerce' ) );
        }

        $pdf_content = $this->api_client->download_invoice_pdf( $invoice_id );

        if ( is_wp_error( $pdf_content ) ) {
            wp_die( esc_html( $pdf_content->get_error_message() ) );
        }

        $invoice_number = $order->get_meta( '_fakturowo_invoice_number' );
        $filename = $invoice_number ? sanitize_file_name( $invoice_number ) . '.pdf' : 'invoice-' . $invoice_id . '.pdf';

        header( 'Content-Type: application/pdf' );
        header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
        header( 'Content-Length: ' . strlen( $pdf_content ) );
        header( 'Cache-Control: private, max-age=0, must-revalidate' );
        header( 'Pragma: public' );

        echo $pdf_content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        exit;
    }
}

