<?php

namespace Devikit\Infakt;

use Devikit\Infakt\Admin\Settings;
use Devikit\Infakt\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_infakt_create_invoice', [ $this, 'ajax_create_invoice' ] );
        add_action( 'wp_ajax_devikit_infakt_create_proforma', [ $this, 'ajax_create_proforma' ] );
        add_action( 'wp_ajax_devikit_infakt_download_pdf', [ $this, 'ajax_download_pdf' ] );
        add_action( 'wp_ajax_devikit_infakt_send_invoice_email', [ $this, 'ajax_send_invoice_email' ] );
        add_action( 'wp_ajax_devikit_infakt_send_proforma_email', [ $this, 'ajax_send_proforma_email' ] );
        add_action( 'devikit_infakt_send_delayed_invoice_email', [ $this, 'handle_delayed_invoice_email' ], 10, 2 );
        add_action( 'devikit_infakt_send_delayed_proforma_email', [ $this, 'handle_delayed_proforma_email' ], 10, 2 );
        
        // Frontend invoice download for customers
        add_action( 'woocommerce_view_order', [ $this, 'display_invoice_download_button' ], 20 );
        add_action( 'template_redirect', [ $this, 'handle_invoice_download' ] );
    }

    /**
     * Add Meta Box
     */
    public function add_order_meta_box() {
        add_meta_box(
            'devikit_infakt_invoice',
            __( 'Infakt Invoice', 'invoicing-integration-for-infakt-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_infakt_invoice',
                __( 'Infakt Invoice', 'invoicing-integration-for-infakt-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 edit pages
        if ( ! in_array( $hook_suffix, [ 'post.php', 'woocommerce_page_wc-orders' ], true ) ) {
            return;
        }
        
        global $post;
        $order_id = null;
        
        // Get order ID from post or from $_GET
        if ( $post && $post->post_type === 'shop_order' ) {
            $order_id = $post->ID;
        } elseif ( isset( $_GET['id'] ) ) {
            $order_id = absint( $_GET['id'] );
        }
        
        if ( ! $order_id ) {
            return;
        }
        
        wp_enqueue_script( 'jquery' );
        
        // Inline script for metabox actions
        $metabox_js = "
            jQuery(document).ready(function($) {
                $('#devikit-infakt-create-invoice').on('click', function() {
                    var \$btn = $(this);
                    var \$loading = $('#devikit-infakt-loading');
                    var \$error = $('#devikit-infakt-error');
                    
                    \$btn.hide();
                    \$loading.show();
                    \$error.text('');

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

                    $.post(ajaxurl, {
                        action: 'devikit_infakt_create_proforma',
                        order_id: \$btn.data('order-id'),
                        nonce: '" . wp_create_nonce( 'infakt_create_proforma' ) . "'
                    }, function(response) {
                        \$loading.hide();
                        if (response.success) {
                            location.reload();
                        } else {
                            \$btn.show();
                            \$error.text(response.data.message);
                        }
                    });
                });
                
                $('#devikit-infakt-download-pdf, #devikit-infakt-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('" . esc_js( __( 'Downloading...', 'invoicing-integration-for-infakt-and-woocommerce' ) ) . "');
                    
                    $.post(ajaxurl, {
                        action: 'devikit_infakt_download_pdf',
                        invoice_id: invoiceId,
                        invoice_number: invoiceNumber,
                        nonce: '" . wp_create_nonce( 'infakt_download_pdf' ) . "'
                    }, 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 || '" . esc_js( __( 'Failed to download PDF', 'invoicing-integration-for-infakt-and-woocommerce' ) ) . "');
                        }
                    });
                });
                
                $('#devikit-infakt-send-email').off('click').on('click', function(e) {
                    e.preventDefault();
                    
                    var \$btn = $(this);
                    var \$loading = $('#devikit-infakt-email-loading');
                    var \$success = $('#devikit-infakt-email-success');
                    var \$error = $('#devikit-infakt-email-error');
                    
                    if (!confirm('" . esc_js( __( 'Are you sure you want to send the invoice to the customer?', 'invoicing-integration-for-infakt-and-woocommerce' ) ) . "')) {
                        return false;
                    }
                    
                    \$btn.prop('disabled', true).hide();
                    \$loading.show();
                    \$success.hide();
                    \$error.text('');

                    $.post(ajaxurl, {
                        action: 'devikit_infakt_send_invoice_email',
                        order_id: \$btn.data('order-id'),
                        nonce: '" . wp_create_nonce( 'infakt_send_email' ) . "'
                    }, function(response) {
                        \$loading.hide();
                        if (response.success) {
                            \$success.show();
                            setTimeout(function() {
                                \$btn.prop('disabled', false).show();
                                \$success.hide();
                            }, 3000);
                        } else {
                            \$btn.prop('disabled', false).show();
                            \$error.text(response.data && response.data.message ? response.data.message : 'Unknown error');
                        }
                    }).fail(function(xhr, status, error) {
                        \$loading.hide();
                        \$btn.prop('disabled', false).show();
                        \$error.text('AJAX Error: ' + error + ' (Status: ' + status + ')');
                    });
                    
                    return false;
                });
                
                $('#devikit-infakt-send-proforma-email').off('click').on('click', function(e) {
                    e.preventDefault();
                    
                    var \$btn = $(this);
                    var \$loading = $('#devikit-infakt-proforma-email-loading');
                    var \$success = $('#devikit-infakt-proforma-email-success');
                    var \$error = $('#devikit-infakt-proforma-email-error');
                    
                    if (!confirm('" . esc_js( __( 'Are you sure you want to send the proforma to the customer?', 'invoicing-integration-for-infakt-and-woocommerce' ) ) . "')) {
                        return false;
                    }
                    
                    \$btn.prop('disabled', true).hide();
                    \$loading.show();
                    \$success.hide();
                    \$error.text('');

                    $.post(ajaxurl, {
                        action: 'devikit_infakt_send_proforma_email',
                        order_id: \$btn.data('order-id'),
                        nonce: '" . wp_create_nonce( 'infakt_send_proforma_email' ) . "'
                    }, function(response) {
                        \$loading.hide();
                        if (response.success) {
                            \$success.show();
                            setTimeout(function() {
                                \$btn.prop('disabled', false).show();
                                \$success.hide();
                            }, 3000);
                        } else {
                            \$btn.prop('disabled', false).show();
                            \$error.text(response.data && response.data.message ? response.data.message : 'Unknown error');
                        }
                    }).fail(function(xhr, status, error) {
                        \$loading.hide();
                        \$btn.prop('disabled', false).show();
                        \$error.text('AJAX Error: ' + error + ' (Status: ' + status + ')');
                    });
                    
                    return false;
                });
            });
        ";
        
        wp_add_inline_script( 'jquery', $metabox_js );
    }

    /**
     * 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( '_infakt_invoice_id' );
        $invoice_uuid = $order->get_meta( '_infakt_invoice_uuid' );
        $invoice_number = $order->get_meta( '_infakt_invoice_number' );
        
        $proforma_id = $order->get_meta( '_infakt_proforma_id' );
        $proforma_number = $order->get_meta( '_infakt_proforma_number' );
        
        // 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\InfaktPro\Plugin' );

        ?>
        <div class="devikit-infakt-metabox">
            <?php if ( $proforma_id ) : ?>
                <?php
                // Check for proforma total mismatch
                $has_proforma_mismatch = $order->get_meta( '_infakt_proforma_total_mismatch' ) === 'yes';
                if ( $has_proforma_mismatch ) :
                    $proforma_order_total = floatval( $order->get_meta( '_infakt_proforma_order_total' ) );
                    $proforma_infakt_total = floatval( $order->get_meta( '_infakt_proforma_infakt_total' ) );
                    $proforma_difference = floatval( $order->get_meta( '_infakt_proforma_total_difference' ) );
                ?>
                <div style="background:#fff3cd; border:1px solid #ffc107; padding:10px; border-radius:4px; margin-bottom:10px;">
                    <strong style="color:#856404;">
                        <?php echo esc_html__( '⚠ Total Mismatch Detected', 'invoicing-integration-for-infakt-and-woocommerce' ); ?>
                    </strong>
                    <p style="margin:5px 0 0; font-size:12px; 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-infakt-and-woocommerce' ),
                            number_format( $proforma_order_total, 2, ',', ' ' ),
                            number_format( $proforma_infakt_total, 2, ',', ' ' ),
                            number_format( $proforma_difference, 2, ',', ' ' )
                        );
                        ?>
                    </p>
                    <p style="margin:5px 0 0; font-size:11px; color:#856404;">
                        <?php echo esc_html__( 'Email was not sent automatically due to this mismatch.', 'invoicing-integration-for-infakt-and-woocommerce' ); ?>
                    </p>
                </div>
                <?php endif; ?>
                <p>
                    <strong><?php echo esc_html__( 'Proforma Created:', 'invoicing-integration-for-infakt-and-woocommerce' ); ?></strong><br>
                    <?php echo esc_html( $proforma_number ?: $proforma_id ); ?>
                </p>
                <p>
                    <a href="https://app.infakt.pl/app/faktury/<?php echo esc_attr( $proforma_id ); ?>" target="_blank" class="button">
                        <?php echo esc_html__( 'Open in Infakt', 'invoicing-integration-for-infakt-and-woocommerce' ); ?>
                    </a>
                    <button type="button" class="button" id="devikit-infakt-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-infakt-and-woocommerce' ); ?>
                    </button>
                </p>
                <p style="margin-top:10px;">
                    <?php if ( $is_pro_installed ) : ?>
                        <button type="button" class="button" id="devikit-infakt-send-proforma-email" 
                                data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
                            <?php echo esc_html__( 'Send Proforma by Email', 'invoicing-integration-for-infakt-and-woocommerce' ); ?>
                        </button>
                        <span id="devikit-infakt-proforma-email-loading" style="display:none;"><?php echo esc_html__( 'Sending...', 'invoicing-integration-for-infakt-and-woocommerce' ); ?></span>
                        <span id="devikit-infakt-proforma-email-success" style="color:green; display:none;"><?php echo esc_html__( '✓ Sent', 'invoicing-integration-for-infakt-and-woocommerce' ); ?></span>
                        <p id="devikit-infakt-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-infakt-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-infakt-and-woocommerce' ),
                                '<a href="https://devikit.pl/produkt/infakt-woocommerce-pro/" target="_blank" style="color:#2271b1; text-decoration:none;">' . esc_html__( 'PRO version', 'invoicing-integration-for-infakt-and-woocommerce' ) . '</a>'
                            );
                            ?>
                        </small>
                    <?php endif; ?>
                </p>
                <hr style="margin:15px 0;">
            <?php endif; ?>
            
            <?php if ( $invoice_id ) : ?>
                <?php
                // Check for invoice total mismatch
                $has_invoice_mismatch = $order->get_meta( '_infakt_invoice_total_mismatch' ) === 'yes';
                if ( $has_invoice_mismatch ) :
                    $invoice_order_total = floatval( $order->get_meta( '_infakt_invoice_order_total' ) );
                    $invoice_infakt_total = floatval( $order->get_meta( '_infakt_invoice_infakt_total' ) );
                    $invoice_difference = floatval( $order->get_meta( '_infakt_invoice_total_difference' ) );
                ?>
                <div style="background:#fff3cd; border:1px solid #ffc107; padding:10px; border-radius:4px; margin-bottom:10px;">
                    <strong style="color:#856404;">
                        <?php echo esc_html__( '⚠ Total Mismatch Detected', 'invoicing-integration-for-infakt-and-woocommerce' ); ?>
                    </strong>
                    <p style="margin:5px 0 0; font-size:12px; 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-infakt-and-woocommerce' ),
                            number_format( $invoice_order_total, 2, ',', ' ' ),
                            number_format( $invoice_infakt_total, 2, ',', ' ' ),
                            number_format( $invoice_difference, 2, ',', ' ' )
                        );
                        ?>
                    </p>
                    <p style="margin:5px 0 0; font-size:11px; color:#856404;">
                        <?php echo esc_html__( 'Email was not sent automatically due to this mismatch.', 'invoicing-integration-for-infakt-and-woocommerce' ); ?>
                    </p>
                </div>
                <?php endif; ?>
                <p>
                    <strong><?php echo esc_html__( 'Invoice Created:', 'invoicing-integration-for-infakt-and-woocommerce' ); ?></strong><br>
                    <?php echo esc_html( $invoice_number ?: $invoice_id ); ?>
                </p>
                <p>
                    <a href="https://app.infakt.pl/app/faktury/<?php echo esc_attr( $invoice_id ); ?>" target="_blank" class="button">
                        <?php echo esc_html__( 'Open in Infakt', 'invoicing-integration-for-infakt-and-woocommerce' ); ?>
                    </a>
                    <button type="button" class="button" id="devikit-infakt-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-infakt-and-woocommerce' ); ?>
                    </button>
                </p>
                <p style="margin-top:10px;">
                    <?php if ( $is_pro_installed ) : ?>
                        <button type="button" class="button" id="devikit-infakt-send-email" 
                                data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
                            <?php echo esc_html__( 'Send Invoice by Email', 'invoicing-integration-for-infakt-and-woocommerce' ); ?>
                        </button>
                        <span id="devikit-infakt-email-loading" style="display:none;"><?php echo esc_html__( 'Sending...', 'invoicing-integration-for-infakt-and-woocommerce' ); ?></span>
                        <span id="devikit-infakt-email-success" style="color:green; display:none;"><?php echo esc_html__( '✓ Sent', 'invoicing-integration-for-infakt-and-woocommerce' ); ?></span>
                        <p id="devikit-infakt-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-infakt-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-infakt-and-woocommerce' ),
                                '<a href="https://devikit.pl/produkt/infakt-woocommerce-pro/" target="_blank" style="color:#2271b1; text-decoration:none;">' . esc_html__( 'PRO version', 'invoicing-integration-for-infakt-and-woocommerce' ) . '</a>'
                            );
                            ?>
                        </small>
                    <?php endif; ?>
                </p>

                <?php
                // KSeF section - PRO adds its own button/status, FREE shows disabled button
                if ( $is_pro_installed ) {
                    // Hook for PRO to add KSeF status and button
                    do_action( 'devikit_infakt_metabox_after_invoice', $order, $invoice_uuid );
                } else {
                    // FREE version - disabled button with PRO link
                    ?>
                    <p style="margin-top:10px;">
                        <button type="button" class="button" disabled style="opacity:0.5; cursor:not-allowed;">
                            <?php echo esc_html__( 'Send to KSeF', 'invoicing-integration-for-infakt-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-infakt-and-woocommerce' ),
                                '<a href="https://devikit.pl/produkt/infakt-woocommerce-pro/" target="_blank" style="color:#2271b1; text-decoration:none;">' . esc_html__( 'PRO version', 'invoicing-integration-for-infakt-and-woocommerce' ) . '</a>'
                            );
                            ?>
                        </small>
                    </p>
                    <?php
                }
                ?>
            <?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-infakt-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-infakt-create-invoice" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
                            <?php echo esc_html__( 'Create Invoice', 'invoicing-integration-for-infakt-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-infakt-create-proforma" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
                                <?php echo esc_html__( 'Create Proforma', 'invoicing-integration-for-infakt-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-infakt-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-infakt-and-woocommerce' ),
                                    '<a href="https://devikit.pl/produkt/infakt-woocommerce-pro/" target="_blank" style="color:#2271b1; text-decoration:none;">' . esc_html__( 'PRO version', 'invoicing-integration-for-infakt-and-woocommerce' ) . '</a>'
                                );
                                ?>
                            </small>
                        <?php endif; ?>
                    </p>
                <?php endif; ?>
                <span id="devikit-infakt-loading" style="display:none;"><?php echo esc_html__( 'Creating invoice...', 'invoicing-integration-for-infakt-and-woocommerce' ); ?></span>
                <?php if ( $is_pro_installed && ! $proforma_id ) : ?>
                    <span id="devikit-infakt-proforma-loading" style="display:none;"><?php echo esc_html__( 'Creating proforma...', 'invoicing-integration-for-infakt-and-woocommerce' ); ?></span>
                <?php endif; ?>
                <p id="devikit-infakt-error" style="color:red; margin-top:10px;"></p>
                <?php if ( $is_pro_installed && ! $proforma_id ) : ?>
                    <p id="devikit-infakt-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( 'infakt_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( 'infakt_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\InfaktPro\Plugin' ) ) {
            wp_send_json_error( [ 'message' => __( 'PRO version required', 'invoicing-integration-for-infakt-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-infakt-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( 'infakt_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( 'infakt_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\InfaktPro\Plugin' ) ) {
            $this->api_client->log( 'AJAX Send Invoice Email: PRO not active', 'error' );
            wp_send_json_error( [ 'message' => __( 'PRO version required', 'invoicing-integration-for-infakt-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-infakt-and-woocommerce' ) ] );
        }
        
        // Get invoice data
        $invoice_id = $order->get_meta( '_infakt_invoice_id' );
        $invoice_number = $order->get_meta( '_infakt_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-infakt-and-woocommerce' ) ] );
        }
        
        // Prepare invoice data for email
        $invoice_data = [
            'url' => 'https://app.infakt.pl/app/faktury/' . $invoice_id,
            '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_infakt_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['infakt_invoice_email'] ) ) {
            $infakt_email = $wc_emails['infakt_invoice_email'];
            $this->api_client->log( 'InFakt Invoice Email status: ' . wp_json_encode( [
                'enabled' => $infakt_email->is_enabled(),
                'id' => $infakt_email->id
            ], JSON_UNESCAPED_UNICODE ), 'debug' );
        } else {
            $this->api_client->log( 'InFakt Invoice Email NOT registered!', 'error' );
        }
        
        // Trigger email hook
        do_action( 'devikit_infakt_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-infakt-and-woocommerce' ) );

        $this->api_client->log( 'AJAX Send Invoice Email: Returning success', 'debug' );
        wp_send_json_success( [ 'message' => __( 'Email sent successfully', 'invoicing-integration-for-infakt-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( 'infakt_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\InfaktPro\Plugin' ) ) {
            $this->api_client->log( 'AJAX Send Proforma Email: PRO not active', 'error' );
            wp_send_json_error( [ 'message' => __( 'PRO version required', 'invoicing-integration-for-infakt-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-infakt-and-woocommerce' ) ] );
        }
        
        // Get proforma data
        $proforma_id = $order->get_meta( '_infakt_proforma_id' );
        $proforma_number = $order->get_meta( '_infakt_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-infakt-and-woocommerce' ) ] );
        }
        
        // Prepare proforma data for email
        $proforma_data = [
            'url' => 'https://app.infakt.pl/app/faktury/' . $proforma_id,
            '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_infakt_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_infakt_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-infakt-and-woocommerce' ) );

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

    /**
     * Create Invoice for Order
     *
     * @param \WC_Order $order
     * @param bool     $is_automatic Whether created by automation (delayed email) or manual (immediate email)
     * @return int|WP_Error Invoice ID or Error
     */
    public function create_invoice_for_order( $order, $is_automatic = false ) {
        // 1. Get or Create Client
        $client_id = $this->get_or_create_client( $order );
        if ( is_wp_error( $client_id ) ) {
            return $client_id;
        }

        // 2. Prepare Invoice Data
        $invoice_data = $this->prepare_invoice_data( $order, $client_id );
        $invoice_data = apply_filters( 'devikit_infakt_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' );

        // Clean empty values
        if ( empty( $invoice_data['vat_exemption_reason'] ) ) {
            unset( $invoice_data['vat_exemption_reason'] );
        }
        if ( ! isset( $invoice_data['document_markings_ids'] ) || empty( $invoice_data['document_markings_ids'] ) || ! is_array( $invoice_data['document_markings_ids'] ) ) {
            unset( $invoice_data['document_markings_ids'] );
        }
        if ( empty( $invoice_data['bank_account'] ) ) {
            unset( $invoice_data['bank_account'] );
        }

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

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

        // 4. Save Invoice ID and validate totals
        if ( isset( $response['id'] ) ) {
            $order->update_meta_data( '_infakt_invoice_id', $response['id'] );
            $order->update_meta_data( '_infakt_invoice_uuid', $response['uuid'] );
            $order->update_meta_data( '_infakt_invoice_number', $response['number'] );
            
            // Get invoice total from inFakt response
            // inFakt API returns gross_price (total with VAT in grosz - need to divide by 100)
            $invoice_total = 0;
            if ( isset( $response['gross_price'] ) ) {
                // gross_price is in grosz (1/100 PLN), convert to PLN
                $invoice_total = floatval( $response['gross_price'] ) / 100;
            } elseif ( isset( $response['left_to_pay'] ) ) {
                // Fallback to left_to_pay (also in grosz)
                $invoice_total = floatval( $response['left_to_pay'] ) / 100;
            } else {
                // Fetch full invoice details to get total if not in create response
                $invoice_uuid = $response['uuid'] ?? '';
                if ( ! empty( $invoice_uuid ) ) {
                    $full_invoice = $this->api_client->get_invoice( $invoice_uuid );
                    if ( ! is_wp_error( $full_invoice ) ) {
                        if ( isset( $full_invoice['gross_price'] ) ) {
                            $invoice_total = floatval( $full_invoice['gross_price'] ) / 100;
                        } elseif ( isset( $full_invoice['left_to_pay'] ) ) {
                            $invoice_total = floatval( $full_invoice['left_to_pay'] ) / 100;
                        }
                        
                        $this->api_client->log( 'Fetched invoice details for total: ' . wp_json_encode( $full_invoice, JSON_UNESCAPED_UNICODE ), 'debug' );
                    }
                }
            }
            
            $this->api_client->log( 'Invoice total validation: invoice_total=' . $invoice_total . ' (from API gross_price=' . ( $response['gross_price'] ?? 'N/A' ) . ')', 'debug' );
            
            // 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 = $invoice_total > 0 && $total_difference >= 0.01;
            
            if ( $has_total_mismatch ) {
                $order->update_meta_data( '_infakt_invoice_total_mismatch', 'yes' );
                $order->update_meta_data( '_infakt_invoice_order_total', $order_total );
                $order->update_meta_data( '_infakt_invoice_infakt_total', $invoice_total );
                $order->update_meta_data( '_infakt_invoice_total_difference', $total_difference );
                
                /* translators: 1: Invoice number, 2: Order total, 3: Invoice total */
                $order->add_order_note( sprintf( 
                    __( 'Infakt Invoice created: %1$s (Total mismatch: Order %2$s vs Invoice %3$s)', 'invoicing-integration-for-infakt-and-woocommerce' ), 
                    $response['number'],
                    number_format( $order_total, 2, ',', ' ' ),
                    number_format( $invoice_total, 2, ',', ' ' )
                ) );
            } else {
                $order->delete_meta_data( '_infakt_invoice_total_mismatch' );
                $order->delete_meta_data( '_infakt_invoice_order_total' );
                $order->delete_meta_data( '_infakt_invoice_infakt_total' );
                $order->delete_meta_data( '_infakt_invoice_total_difference' );
                
                /* translators: %s: Invoice number */
                $order->add_order_note( sprintf( __( 'Infakt Invoice created: %s', 'invoicing-integration-for-infakt-and-woocommerce' ), $response['number'] ) );
            }
            
            $order->save();
            
            // Trigger email only if totals match (if PRO is active and enabled)
            if ( ! $has_total_mismatch ) {
                $this->maybe_send_invoice_email( $order, $response, $is_automatic );
            }
            
            return $response['id'];
        }

        return new \WP_Error( 'infakt_unknown_error', 'Unknown response from Infakt API' );
    }
    
    /**
     * Create Proforma for Order
     *
     * @param \WC_Order $order
     * @param bool     $is_automatic Whether created by automation (delayed email) or manual (immediate email)
     * @return int|WP_Error Proforma ID or Error
     */
    public function create_proforma_for_order( $order, $is_automatic = false ) {
        // 1. Get or Create Client
        $client_id = $this->get_or_create_client( $order );
        if ( is_wp_error( $client_id ) ) {
            return $client_id;
        }

        // 2. Prepare Proforma Data (similar to invoice but with kind='proforma')
        $proforma_data = $this->prepare_invoice_data( $order, $client_id );
        $proforma_data['kind'] = 'proforma'; // Set document type as proforma
        $proforma_data['paid_price'] = 0; // Proformas are always "to pay", never marked as paid
        $proforma_data = apply_filters( 'devikit_infakt_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' );

        // Clean empty values
        if ( empty( $proforma_data['vat_exemption_reason'] ) ) {
            unset( $proforma_data['vat_exemption_reason'] );
        }
        if ( ! isset( $proforma_data['document_markings_ids'] ) || empty( $proforma_data['document_markings_ids'] ) || ! is_array( $proforma_data['document_markings_ids'] ) ) {
            unset( $proforma_data['document_markings_ids'] );
        }
        if ( empty( $proforma_data['bank_account'] ) ) {
            unset( $proforma_data['bank_account'] );
        }

        // 3. Send to API (same endpoint, kind parameter determines document type)
        $response = $this->api_client->create_invoice( $proforma_data );

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

        // 4. Save Proforma ID and validate totals
        if ( isset( $response['id'] ) ) {
            $order->update_meta_data( '_infakt_proforma_id', $response['id'] );
            $order->update_meta_data( '_infakt_proforma_uuid', $response['uuid'] );
            $order->update_meta_data( '_infakt_proforma_number', $response['number'] );
            
            // Get proforma total from inFakt response
            // inFakt API returns gross_price (total with VAT in grosz - need to divide by 100)
            $proforma_total = 0;
            if ( isset( $response['gross_price'] ) ) {
                // gross_price is in grosz (1/100 PLN), convert to PLN
                $proforma_total = floatval( $response['gross_price'] ) / 100;
            } elseif ( isset( $response['left_to_pay'] ) ) {
                // Fallback to left_to_pay (also in grosz)
                $proforma_total = floatval( $response['left_to_pay'] ) / 100;
            } else {
                // Fetch full proforma details to get total if not in create response
                $proforma_uuid = $response['uuid'] ?? '';
                if ( ! empty( $proforma_uuid ) ) {
                    $full_proforma = $this->api_client->get_invoice( $proforma_uuid );
                    if ( ! is_wp_error( $full_proforma ) ) {
                        if ( isset( $full_proforma['gross_price'] ) ) {
                            $proforma_total = floatval( $full_proforma['gross_price'] ) / 100;
                        } elseif ( isset( $full_proforma['left_to_pay'] ) ) {
                            $proforma_total = floatval( $full_proforma['left_to_pay'] ) / 100;
                        }
                        
                        $this->api_client->log( 'Fetched proforma details for total: ' . wp_json_encode( $full_proforma, JSON_UNESCAPED_UNICODE ), 'debug' );
                    }
                }
            }
            
            $this->api_client->log( 'Proforma total validation: proforma_total=' . $proforma_total . ' (from API gross_price=' . ( $response['gross_price'] ?? 'N/A' ) . ')', 'debug' );
            
            // 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.01) to account for float precision issues
            $has_total_mismatch = $proforma_total > 0 && $total_difference >= 0.01;
            
            if ( $has_total_mismatch ) {
                $order->update_meta_data( '_infakt_proforma_total_mismatch', 'yes' );
                $order->update_meta_data( '_infakt_proforma_order_total', $order_total );
                $order->update_meta_data( '_infakt_proforma_infakt_total', $proforma_total );
                $order->update_meta_data( '_infakt_proforma_total_difference', $total_difference );
                
                /* translators: 1: Proforma number, 2: Order total, 3: Proforma total */
                $order->add_order_note( sprintf( 
                    __( 'Infakt Proforma created: %1$s (Total mismatch: Order %2$s vs Proforma %3$s)', 'invoicing-integration-for-infakt-and-woocommerce' ), 
                    $response['number'],
                    number_format( $order_total, 2, ',', ' ' ),
                    number_format( $proforma_total, 2, ',', ' ' )
                ) );
            } else {
                $order->delete_meta_data( '_infakt_proforma_total_mismatch' );
                $order->delete_meta_data( '_infakt_proforma_order_total' );
                $order->delete_meta_data( '_infakt_proforma_infakt_total' );
                $order->delete_meta_data( '_infakt_proforma_total_difference' );
                
                /* translators: %s: Proforma number */
                $order->add_order_note( sprintf( __( 'Infakt Proforma created: %s', 'invoicing-integration-for-infakt-and-woocommerce' ), $response['number'] ) );
            }
            
            $order->save();
            
            // Trigger email only if totals match (if PRO is active and enabled)
            if ( ! $has_total_mismatch ) {
                $this->maybe_send_proforma_email( $order, $response, $is_automatic );
            }
            
            return $response['id'];
        }

        return new \WP_Error( 'infakt_unknown_error', 'Unknown response from Infakt API' );
    }
    
    /**
     * Maybe send proforma email
     *
     * For automatic creation, the email is delayed by 5 minutes to allow KSeF processing.
     * Manual creation sends the email immediately.
     *
     * @param \WC_Order $order
     * @param array    $response       Proforma data from API
     * @param bool     $is_automatic    Whether created by automation (delayed) or manual (immediate)
     */
    private function maybe_send_proforma_email( $order, $response, $is_automatic = false ) {
        $this->api_client->log( 'Checking if proforma email should be sent', 'debug' );

        // Check if PRO version is active
        if ( ! class_exists( 'Devikit\InfaktPro\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( 'devikit_infakt_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;
        }

        $proforma_data = [
            'url' => 'https://app.infakt.pl/app/faktury/' . $response['id'],
            'number' => $response['number'],
            'id' => $response['id']
        ];

        if ( $is_automatic && function_exists( 'as_schedule_single_action' ) ) {
            // Schedule email with 5-minute delay to allow KSeF processing
            $delay_minutes = apply_filters( 'devikit_infakt_proforma_email_delay_minutes', 5 );

            as_schedule_single_action(
                time() + ( $delay_minutes * 60 ),
                'devikit_infakt_send_delayed_proforma_email',
                [
                    'order_id'      => $order->get_id(),
                    'proforma_data' => $proforma_data,
                ],
                'devikit-infakt'
            );

            $order->add_order_note( sprintf(
                /* translators: %d: delay in minutes */
                __( 'Proforma email scheduled — will be sent in %d minutes (waiting for KSeF processing)', 'invoicing-integration-for-infakt-and-woocommerce' ),
                $delay_minutes
            ) );
        } else {
            // Manual creation — send immediately
            WC()->mailer();
            do_action( 'devikit_infakt_proforma_generated', $order->get_id(), $proforma_data );
            $order->add_order_note( __( 'Proforma email sent to customer automatically', 'invoicing-integration-for-infakt-and-woocommerce' ) );
        }
    }
    
    /**
     * Maybe send invoice email
     *
     * For automatic creation, the email is delayed by 5 minutes to allow KSeF processing.
     * Manual creation sends the email immediately.
     *
     * @param \WC_Order $order
     * @param array    $response     Invoice data from API
     * @param bool     $is_automatic Whether created by automation (delayed) or manual (immediate)
     */
    private function maybe_send_invoice_email( $order, $response, $is_automatic = false ) {
        $this->api_client->log( 'Checking if invoice email should be sent', 'debug' );

        // Check if PRO version is active
        if ( ! class_exists( 'Devikit\InfaktPro\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( 'devikit_infakt_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;
        }

        $invoice_data = [
            'url' => 'https://app.infakt.pl/app/faktury/' . $response['id'],
            'number' => $response['number'],
            'id' => $response['id'],
            'uuid' => $response['uuid'] ?? null
        ];

        if ( $is_automatic && function_exists( 'as_schedule_single_action' ) ) {
            // Schedule email with 5-minute delay to allow KSeF processing
            $delay_minutes = apply_filters( 'devikit_infakt_invoice_email_delay_minutes', 5 );

            as_schedule_single_action(
                time() + ( $delay_minutes * 60 ),
                'devikit_infakt_send_delayed_invoice_email',
                [
                    'order_id'     => $order->get_id(),
                    'invoice_data' => $invoice_data,
                ],
                'devikit-infakt'
            );

            $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-infakt-and-woocommerce' ),
                $delay_minutes
            ) );
        } else {
            // Manual creation — send immediately
            WC()->mailer();
            do_action( 'devikit_infakt_invoice_generated', $order->get_id(), $invoice_data );
            $order->add_order_note( __( 'Invoice email sent to customer automatically', 'invoicing-integration-for-infakt-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, uuid)
     */
    public function handle_delayed_invoice_email( $order_id, $invoice_data ) {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return;
        }

        WC()->mailer();
        do_action( 'devikit_infakt_invoice_generated', $order_id, $invoice_data );
        $order->add_order_note( __( 'Invoice email sent to customer (delayed — after KSeF processing)', 'invoicing-integration-for-infakt-and-woocommerce' ) );
    }

    /**
     * Handle delayed proforma email (called by Action Scheduler)
     *
     * @param int   $order_id      Order ID
     * @param array $proforma_data Proforma data (url, number, id)
     */
    public function handle_delayed_proforma_email( $order_id, $proforma_data ) {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return;
        }

        WC()->mailer();
        do_action( 'devikit_infakt_proforma_generated', $order_id, $proforma_data );
        $order->add_order_note( __( 'Proforma email sent to customer (delayed — after KSeF processing)', 'invoicing-integration-for-infakt-and-woocommerce' ) );
    }

    /**
     * Parse billing address line 2 into building number + flat when line 1 is street-only.
     *
     * Handles common PL formats: "15", "15/3", "15 m. 3", "15 lok. 3", "15 3", free text after number.
     *
     * @param string    $line2 Trimmed second address line.
     * @param \WC_Order $order Order (for filters).
     * @return array{street_number: string, flat_number: string}|null Null = caller may treat whole line as flat only.
     */
    private function parse_billing_address_line2_for_split_street( $line2, $order ) {
        $line2 = trim( preg_replace( '/\s+/u', ' ', $line2 ) );
        if ( '' === $line2 ) {
            return null;
        }

        $building = '(\d+[a-zA-Z]?)';
        $parsed   = null;

        // 15/3, 15a/2 (flat part may include spaces, e.g. "3 piętro").
        if ( preg_match( '/^' . $building . '\s*\/\s*(.+)$/u', $line2, $m ) ) {
            $parsed = [
                'street_number' => $m[1],
                'flat_number'   => trim( $m[2] ),
            ];
        } elseif ( preg_match( '/^' . $building . '\s*(?:m\.|mieszkanie\b|lok\.?|lokal\b|apt\.)\s*(.+)$/iu', $line2, $m ) ) {
            // 15 m. 3, 15 mieszkanie 3, 15 lok. 3 (not bare "m" — that is handled below).
            $parsed = [
                'street_number' => $m[1],
                'flat_number'   => trim( $m[2] ),
            ];
        } elseif ( preg_match( '/^' . $building . '\s+m\s+(\d+[a-zA-Z]?)$/iu', $line2, $m ) ) {
            // 15 m 3 (single-letter m separator).
            $parsed = [
                'street_number' => $m[1],
                'flat_number'   => $m[2],
            ];
        } elseif ( preg_match( '/^' . $building . '\s+(\d+[a-zA-Z]?)$/u', $line2, $m ) ) {
            // 15 3 — two numeric tokens (dom + lokal).
            $parsed = [
                'street_number' => $m[1],
                'flat_number'   => $m[2],
            ];
        } elseif ( preg_match( '/^' . $building . '$/u', $line2, $m ) ) {
            // Building number only.
            $parsed = [
                'street_number' => $m[1],
                'flat_number'   => '',
            ];
        } elseif ( preg_match( '/^' . $building . '\s+(.+)$/u', $line2, $m ) ) {
            // First token = building, remainder = flat (free text).
            $parsed = [
                'street_number' => $m[1],
                'flat_number'   => trim( $m[2] ),
            ];
        }

        if ( null === $parsed ) {
            return null;
        }

        /**
         * Filters parsed street_number and flat_number from billing address line 2.
         *
         * @param array{street_number: string, flat_number: string} $parsed Parsed parts.
         * @param string                                            $line2  Original trimmed line 2.
         * @param \WC_Order                                         $order  Order.
         */
        return apply_filters( 'devikit_infakt_parse_billing_address_line2', $parsed, $line2, $order );
    }

    /**
     * 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.
            // Infakt 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 Infakt 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 from billing line 1.
        if ( preg_match( '/^(.+)\s+(\d+[a-zA-Z]*(\/\d+)?)$/', $client_data['street'], $matches ) ) {
            $client_data['street'] = $matches[1];
            $client_data['street_number'] = $matches[2];
        }

        $address_2 = trim( (string) $order->get_billing_address_2() );

        if ( '' !== $address_2 ) {
            if ( '' !== $client_data['street_number'] ) {
                // Line 1 already has building number — line 2 is usually flat / extra info.
                $client_data['flat_number'] = $address_2;
            } else {
                // Line 1 is street-only: split building + flat from line 2 (WooCommerce split checkout).
                $split = $this->parse_billing_address_line2_for_split_street( $address_2, $order );
                if ( null !== $split ) {
                    $client_data['street_number'] = $split['street_number'];
                    $client_data['flat_number']   = $split['flat_number'];
                } else {
                    $client_data['flat_number'] = $address_2;
                }
            }
        }

        /**
         * Filters Infakt client address fields built from the order (after internal parsing).
         *
         * @param array     $client_data Keys: street, street_number, flat_number, city, etc.
         * @param \WC_Order $order       Order.
         */
        $client_data = apply_filters( 'devikit_infakt_client_address_from_order', $client_data, $order );

        if ( ! empty( $nip ) ) {
            // Clean NIP based on country
            // For PL: remove all non-digits (Polish NIP is 10 digits only)
            // For foreign countries: remove only spaces and dashes (preserve country prefix like PL, DE, GB, etc.)
            if ( $billing_country === 'PL' ) {
                $nip = preg_replace( '/[^0-9]/', '', $nip );
            } else {
                // For foreign countries, preserve country prefix and remove only spaces/dashes
                $nip = preg_replace( '/[\s\-]/', '', $nip );
                
                // Ensure country prefix is present for foreign VAT numbers
                // API requires country prefix for non-PL countries (e.g., DE123456789, GB123456789)
                $country_prefix = strtoupper( $billing_country );
                if ( ! empty( $country_prefix ) && strpos( $nip, $country_prefix ) !== 0 ) {
                    // Add country prefix if not already present
                    $nip = $country_prefix . $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_infakt_settings', [] );
        $payment_method = $this->map_order_to_infakt_payment_method( $order );
        
        // Invoice date = today (when invoice is issued).
        // Sale date = order creation date by default, or same as invoice date if setting enabled.
        $invoice_date = current_time( 'Y-m-d' );
        $sale_date = $order->get_date_created()->date( 'Y-m-d' );
        if ( ! empty( $settings['sale_date_same_as_invoice_date'] ) && 'yes' === $settings['sale_date_same_as_invoice_date'] ) {
            $sale_date = $invoice_date;
        }
        
        $data = [
            'client_id' => $client_id,
            'currency' => $order->get_currency(), // Order currency (e.g., PLN, USD, EUR)
            'payment_method' => $payment_method,
            '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( $invoice_date . ' + ' . intval( $settings['payment_deadline_days'] ) . ' days' ) );
        }
        
        // Add paid price - determines if invoice shows "paid" or "to pay"
        // Infakt API expects paid_price in minor currency units (grosze for PLN), not PLN float — same as line item prices.
        // This will be set to 0 for proformas later (via filter or kind check)
        $paid_pln    = (float) $this->get_order_paid_price( $order );
        $data['paid_price'] = $paid_pln > 0 ? (int) $this->format_price_for_infakt( $paid_pln ) : 0;
        
        $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_pln' => $paid_pln,
            'paid_price_api_grosze' => $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'] : '';
        
        // Check WooCommerce price settings to determine price type
        $prices_include_tax = get_option( 'woocommerce_prices_include_tax', 'no' );
        $use_gross_price = wc_string_to_bool( $prices_include_tax );
        $price_type = $use_gross_price ? 'gross_price' : 'net_price';
        
        // Map Items - send total price for the line (not unit price) for better rounding compatibility
        foreach ( $order->get_items() as $item ) {
            $product = $item->get_product();
            
            // Skip items with zero price
            $item_total = (float) $item->get_total();
            if ( 0.0 === $item_total ) {
                continue;
            }
            
            // Get tax rate from item
            $tax_rate = $this->get_item_tax_rate( $item, $settings );
            
            // Calculate price (total or gross total depending on WooCommerce settings)
            // Send total price for the line to avoid rounding issues
            $price = $use_gross_price ? $item_total + $item->get_total_tax() : $item_total;
            
            // Format product name based on settings
            $product_name = $this->format_product_name( $item, $product, $settings );
            
            $service = [
                'name' => $product_name,
                'tax_symbol' => $tax_rate,
                $price_type => $this->format_price_for_infakt( $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 items
        $shipping_items = $order->get_items( 'shipping' );
        foreach ( $shipping_items as $shipping_item ) {
            if ( $shipping_item instanceof \WC_Order_Item_Shipping ) {
                $shipping_total = (float) $shipping_item->get_total();
                
                // Skip zero shipping
                if ( 0 === (int) $shipping_total ) {
                    continue;
                }
                
                // Calculate shipping tax rate
                $shipping_tax_rate = $this->get_shipping_tax_rate( $shipping_item, $settings, $data['services'] );
                
                // For shipping, use net_price
                $shipping_service = [
                    'name' => ! empty( $shipping_item->get_name() ) ? $shipping_item->get_name() : __( 'Shipping', 'invoicing-integration-for-infakt-and-woocommerce' ),
                    'tax_symbol' => $shipping_tax_rate,
                    'net_price' => $this->format_price_for_infakt( $shipping_total ),
                    'quantity' => 1,
                    'unit' => 'szt.',
                ];
                
                // 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;
            }
        }
        
        // Check if order contains only virtual products (services)
        $has_virtual_products = false;
        $has_physical_products = false;
        
        foreach ( $order->get_items() as $item ) {
            $product = $item->get_product();
            if ( $product ) {
                if ( $product->is_virtual() ) {
                    $has_virtual_products = true;
                } else {
                    $has_physical_products = true;
                }
            }
        }
        
        // Set sale_type based on order content
        $billing_country = $order->get_billing_country();
        
        // For foreign orders (non-PL countries), sale_type is required
        if ( ! empty( $billing_country ) && $billing_country !== 'PL' ) {
            // If all products are virtual, set sale_type to 'service'
            // Otherwise set to 'merchandise' (sprzedaż towarów)
            if ( $has_virtual_products && ! $has_physical_products ) {
                $data['sale_type'] = 'service';
            } else {
                $data['sale_type'] = 'merchandise';
            }
        } elseif ( $has_virtual_products && ! $has_physical_products ) {
            // For PL orders with only virtual products, also set sale_type to 'service'
            $data['sale_type'] = 'service';
        }

        return $data;
    }

    /**
     * Map WooCommerce gateway to inFakt API payment_method codes.
     *
     * Allowed values per API: transfer, cash, card, barter, check, bill_of_sale, delivery,
     * compensation, accredited, paypal, instalment_sale, payu, tpay, przelewy24, dotpay, other.
     *
     * @param \WC_Order $order Order.
     * @return string
     */
    private function map_order_to_infakt_payment_method( $order ) {
        $method_id = strtolower( (string) $order->get_payment_method() );
        $title_lower = mb_strtolower( (string) $order->get_payment_method_title(), 'UTF-8' );

        // Exact gateway IDs (WooCommerce core + common plugins).
        $by_id = [
            'cod'                     => 'delivery',
            'bacs'                    => 'transfer',
            'cheque'                  => 'check',
            'cash'                    => 'cash',
            'paypal'                  => 'paypal',
            'stripe'                  => 'card',
            'woocommerce_payments'    => 'card',
            'ppcp-gateway'            => 'paypal',
            'ppec_paypal'             => 'paypal',
            'payu'                    => 'payu',
            'payuwc'                  => 'payu',
            'dotpay'                  => 'dotpay',
            'tpay'                    => 'tpay',
            'przelewy24'              => 'przelewy24',
            'paynow'                  => 'other',
            'mollie'                  => 'other',
            'klarna_payments'         => 'other',
            'square'                  => 'card',
            'braintree'               => 'card',
        ];

        if ( isset( $by_id[ $method_id ] ) ) {
            return apply_filters( 'devikit_infakt_payment_method', $by_id[ $method_id ], $order );
        }

        // Substrings in gateway id (e.g. przelewy24:block, stripe_woocommerce).
        $id_checks = [
            'przelewy24' => 'przelewy24',
            'p24'        => 'przelewy24',
            'payu'       => 'payu',
            'dotpay'     => 'dotpay',
            'tpay'       => 'tpay',
            'paypal'     => 'paypal',
            'ppcp'       => 'paypal',
            'ppec'       => 'paypal',
            'stripe'     => 'card',
            'woopayments'=> 'card',
            'mollie'     => 'other',
            'square'     => 'card',
            'braintree'  => 'card',
        ];

        foreach ( $id_checks as $needle => $code ) {
            if ( strpos( $method_id, $needle ) !== false ) {
                return apply_filters( 'devikit_infakt_payment_method', $code, $order );
            }
        }

        // WooCommerce Payments (WooPay) may use IDs like woocommerce_payments_* .
        if ( strpos( $method_id, 'woocommerce_payments' ) !== false ) {
            return apply_filters( 'devikit_infakt_payment_method', 'card', $order );
        }

        // Title-based fallback (localized labels).
        $title_checks = [
            [ [ 'pobraniem', 'cash on delivery', 'za pobraniem', 'przy odbiorze', 'on delivery' ], 'delivery' ],
            [ [ 'przelew', 'bank transfer', 'direct debit', 'przelewem' ], 'transfer' ],
            [ [ 'przelewy24', 'p24' ], 'przelewy24' ],
            [ [ 'payu' ], 'payu' ],
            [ [ 'tpay' ], 'tpay' ],
            [ [ 'dotpay' ], 'dotpay' ],
            [ [ 'paypal' ], 'paypal' ],
            [ [ 'karta', 'card', 'stripe' ], 'card' ],
            [ [ 'gotówk', 'cash' ], 'cash' ],
            [ [ 'czek', 'cheque' ], 'check' ],
            [ [ 'blik' ], 'przelewy24' ],
        ];

        foreach ( $title_checks as $pair ) {
            foreach ( $pair[0] as $word ) {
                if ( $word !== '' && strpos( $title_lower, $word ) !== false ) {
                    return apply_filters( 'devikit_infakt_payment_method', $pair[1], $order );
                }
            }
        }

        // Default: online/other gateways — avoid mislabelling as delivery.
        $fallback = $method_id === '' ? 'transfer' : 'other';

        return apply_filters( 'devikit_infakt_payment_method', $fallback, $order );
    }

    /**
     * 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. WooCommerce uses '' for "Standard rate" (see wc_get_product_tax_class_options()).
        // Do not gate mapping on ! empty( $tax_class ) — otherwise Standard products never match settings keyed by ''.
        $tax_class = $product->get_tax_class();

        // Map tax class to zw / 0 / np (including Standard = '').
        if ( isset( $settings['tax_class_zw'] ) && $settings['tax_class_zw'] !== '_none_' && $settings['tax_class_zw'] === $tax_class ) {
            return 'zw';
        }
        if ( isset( $settings['tax_class_zero'] ) && $settings['tax_class_zero'] !== '_none_' && $settings['tax_class_zero'] === $tax_class ) {
            return '0';
        }
        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: calculate from actual tax amounts stored in the order.
        // This reflects the real WooCommerce setting ("Shipping tax class") and
        // must take precedence over everything else – including product rates.
        $total = $item->get_total();
        $tax   = $item->get_total_tax();

        if ( $total > 0 && $tax > 0 ) {
            $rate = ( $tax / $total ) * 100;

            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';
            }
        }

        // Resolve shipping tax class once – used in both Priority 2 and 3.
        // WooCommerce stores '' for Standard rate and 'inherit' when shipping is
        // set to "Based on cart items". Both values must be handled without the
        // ! empty() guard so Standard rate can be mapped to zw/np/0 in settings.
        $tax_class  = $item->get_tax_class();
        $is_inherit = ( 'inherit' === $tax_class );

        // Priority 2: shipping tax is zero – resolve symbol before returning '0'.
        if ( $total > 0 && 0 == $tax ) {
            // When tax class is 'inherit', WooCommerce should have applied the same
            // class as the products; fall through to Priority 4 so we replicate that.
            if ( ! $is_inherit ) {
                if ( isset( $settings['tax_class_zw'] ) && $settings['tax_class_zw'] !== '_none_' && $settings['tax_class_zw'] === $tax_class ) {
                    return 'zw';
                }
                if ( isset( $settings['tax_class_np'] ) && $settings['tax_class_np'] !== '_none_' && $settings['tax_class_np'] === $tax_class ) {
                    return 'np';
                }
                if ( isset( $settings['tax_class_zero'] ) && $settings['tax_class_zero'] !== '_none_' && $settings['tax_class_zero'] === $tax_class ) {
                    return '0';
                }

                // No special mapping – tax is genuinely 0%.
                return '0';
            }
        }

        // Priority 3: no usable tax amount – check tax class mapping directly.
        if ( ! $is_inherit ) {
            if ( isset( $settings['tax_class_zw'] ) && $settings['tax_class_zw'] !== '_none_' && $settings['tax_class_zw'] === $tax_class ) {
                return 'zw';
            }
            if ( isset( $settings['tax_class_zero'] ) && $settings['tax_class_zero'] !== '_none_' && $settings['tax_class_zero'] === $tax_class ) {
                return '0';
            }
            if ( isset( $settings['tax_class_np'] ) && $settings['tax_class_np'] !== '_none_' && $settings['tax_class_np'] === $tax_class ) {
                return 'np';
            }
        }

        // Priority 4 (last resort): inherit highest VAT rate from cart products.
        // Used only when no usable tax data is present on the shipping item at all.
        if ( ! empty( $product_services ) ) {
            $tax_rates        = array_column( $product_services, 'tax_symbol' );
            $standard_rates   = [ '23', '8', '5' ];
            $cart_std_rates   = array_intersect( $tax_rates, $standard_rates );

            if ( ! empty( $cart_std_rates ) ) {
                foreach ( $standard_rates as $std ) {
                    if ( in_array( $std, $cart_std_rates, true ) ) {
                        return $std;
                    }
                }
            }

            $unique = array_unique( $tax_rates );
            if ( 1 === count( $unique ) && in_array( $unique[0], [ 'zw', 'np', '0' ], true ) ) {
                return $unique[0];
            }
        }

        // Absolute fallback.
        return '23';
    }

    /**
     * Adjust item prices to match WooCommerce order totals exactly
     * 
     * This fixes rounding differences between WooCommerce (per-item rounding) 
     * and inFakt (total rounding). WooCommerce rounds each item separately,
     * while inFakt sums all items and rounds the total.
     * 
     * @param array $items_data Array of service items with _wc_item_total and _wc_item_tax
     * @param float $order_total_net Order total net from WooCommerce
     * @param float $order_total_tax Order total tax from WooCommerce
     * @param float $order_total_gross Order total gross from WooCommerce
     * @return array Adjusted items data
     */
    private function adjust_item_prices_to_match_order_totals( $items_data, $order_total_net, $order_total_tax, $order_total_gross ) {
        if ( empty( $items_data ) ) {
            return $items_data;
        }
        
        // Calculate sum of all item totals from WooCommerce
        $sum_item_net = 0;
        foreach ( $items_data as $item ) {
            $sum_item_net += isset( $item['_wc_item_total'] ) ? $item['_wc_item_total'] : 0;
        }
        
        // Calculate difference between order total and sum of items
        $net_difference = $order_total_net - $sum_item_net;
        
        // If difference is very small (rounding error), adjust the last item
        // This ensures inFakt calculates totals that match WooCommerce exactly
        if ( abs( $net_difference ) > 0.001 ) {
            // Find the last taxable item (not zero tax rate)
            $last_adjustable_index = -1;
            for ( $i = count( $items_data ) - 1; $i >= 0; $i-- ) {
                $tax_rate = isset( $items_data[ $i ]['tax_symbol'] ) ? $items_data[ $i ]['tax_symbol'] : '23';
                if ( $tax_rate !== '0' && $tax_rate !== 'zw' && $tax_rate !== 'np' ) {
                    $last_adjustable_index = $i;
                    break;
                }
            }
            
            // If no taxable item found, use last item
            if ( $last_adjustable_index < 0 ) {
                $last_adjustable_index = count( $items_data ) - 1;
            }
            
            // Adjust the last item's unit price
            $last_item = &$items_data[ $last_adjustable_index ];
            $current_total = isset( $last_item['_wc_item_total'] ) ? $last_item['_wc_item_total'] : 0;
            $quantity = isset( $last_item['quantity'] ) ? (float) $last_item['quantity'] : 1;
            
            // Calculate new unit price
            $new_total = $current_total + $net_difference;
            $new_unit_price = $quantity > 0 ? $new_total / $quantity : $new_total;
            
            // Update unit price
            $last_item['unit_net_price'] = $this->format_price_for_infakt( $new_unit_price );
            
            $this->api_client->log( sprintf(
                'Adjusted item price to match order totals. Item: %s, Old total: %s, New total: %s, Difference: %s',
                isset( $last_item['name'] ) ? $last_item['name'] : 'Unknown',
                number_format( $current_total, 2, '.', '' ),
                number_format( $new_total, 2, '.', '' ),
                number_format( $net_difference, 2, '.', '' )
            ), 'debug' );
        }
        
        return $items_data;
    }

    /**
     * Format price for Infakt API (grosze as integer string)
     * 
     * @param float $price Price in PLN
     * @return string Price in grosze (cents)
     */
    private function format_price_for_infakt( $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 Infakt API
     * 
     * @param string $flat_rate Flat rate value (e.g., "8.5%", "8,5", "8.5")
     * @return float|string Formatted flat rate (Infakt 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 (Infakt 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 Infakt.
     * 
     * Returns the paid amount in PLN. For the Infakt API, convert with format_price_for_infakt()
     * (minor units / grosze) when sending paid_price.
     * Example: 20.00 PLN → 20.0
     * 
     * @param \WC_Order $order
     * @return float Paid amount in store currency (major units).
     */
    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\InfaktPro\Plugin' ) ) {
            $pro_settings = get_option( 'devikit_infakt_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;
    }
    
    /**
     * Display invoice download button on order details page (My Account)
     * 
     * @param int $order_id Order ID
     */
    public function display_invoice_download_button( $order_id ) {
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            return;
        }
        
        // Check if customer 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( '_infakt_invoice_id' );
        $invoice_number = $order->get_meta( '_infakt_invoice_number' );
        
        if ( ! $invoice_id ) {
            return;
        }
        
        $download_url = add_query_arg( [
            'action'     => 'download_infakt_invoice',
            'order_id'   => $order_id,
            'invoice_id' => $invoice_id,
            '_wpnonce'   => wp_create_nonce( 'download_infakt_invoice_' . $order_id ),
        ], home_url( '/' ) );
        
        echo '<p class="infakt-invoice-download" style="margin-top: 20px;">';
        echo '<a href="' . esc_url( $download_url ) . '" class="button" target="_blank">';
        echo esc_html__( 'Download Invoice', 'invoicing-integration-for-infakt-and-woocommerce' );
        if ( $invoice_number ) {
            echo ' (' . esc_html( $invoice_number ) . ')';
        }
        echo '</a>';
        echo '</p>';
    }
    
    /**
     * Handle invoice download from frontend (My Account)
     */
    public function handle_invoice_download() {
        // phpcs:disable WordPress.Security.NonceVerification.Recommended -- Nonce verification below
        if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'download_infakt_invoice' ) {
            return;
        }
        
        if ( ! isset( $_GET['order_id'], $_GET['invoice_id'], $_GET['_wpnonce'] ) ) {
            wp_die( esc_html__( 'Invalid request', 'invoicing-integration-for-infakt-and-woocommerce' ) );
        }
        
        $order_id = absint( $_GET['order_id'] );
        $invoice_id = absint( $_GET['invoice_id'] );
        // phpcs:enable WordPress.Security.NonceVerification.Recommended
        
        if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'download_infakt_invoice_' . $order_id ) ) {
            wp_die( esc_html__( 'Invalid security token', 'invoicing-integration-for-infakt-and-woocommerce' ) );
        }
        
        $order = wc_get_order( $order_id );
        if ( ! $order ) {
            wp_die( esc_html__( 'Order not found', 'invoicing-integration-for-infakt-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-infakt-and-woocommerce' ) );
        }
        
        // Verify invoice ID matches order meta
        $stored_invoice_id = $order->get_meta( '_infakt_invoice_id' );
        if ( $stored_invoice_id != $invoice_id ) {
            wp_die( esc_html__( 'Invoice not found for this order', 'invoicing-integration-for-infakt-and-woocommerce' ) );
        }
        
        // Download PDF
        $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( '_infakt_invoice_number' );
        $filename = $invoice_number ? sanitize_file_name( $invoice_number ) . '.pdf' : 'invoice-' . $invoice_id . '.pdf';
        
        // Send PDF to browser
        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;
    }
}

