<?php

namespace Devikit\Wfirma;

use Devikit\Wfirma\Admin\Settings;
use Devikit\Wfirma\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_wfirma_create_invoice', [ $this, 'ajax_create_invoice' ] );
		add_action( 'wp_ajax_devikit_wfirma_download_pdf', [ $this, 'ajax_download_pdf' ] );
		add_action( 'wp_ajax_devikit_wfirma_send_invoice_email', [ $this, 'ajax_send_invoice_email' ] );
		
		// Frontend invoice download
		add_action( 'woocommerce_view_order', [ $this, 'display_invoice_download_button' ], 20 );
		add_action( 'template_redirect', [ $this, 'handle_invoice_download' ] );
		
		// Delayed invoice email handler (Action Scheduler)
		add_action( 'devikit_wfirma_send_delayed_invoice_email', [ $this, 'handle_delayed_invoice_email' ], 10, 2 );
	}

	/**
	 * Add Meta Box
	 */
	public function add_order_meta_box() {
		add_meta_box(
			'devikit_wfirma_invoice',
			__( 'wFirma Invoice', 'invoicing-integration-for-wfirma-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_wfirma_invoice',
				__( 'wFirma Invoice', 'invoicing-integration-for-wfirma-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 ) {
		if ( ! in_array( $hook_suffix, [ 'post.php', 'woocommerce_page_wc-orders' ], true ) ) {
			return;
		}
		
		global $post;
		$order_id = null;
		
		if ( $post && $post->post_type === 'shop_order' ) {
			$order_id = $post->ID;
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Order ID from WP admin page context
		} elseif ( isset( $_GET['id'] ) ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Order ID from WP admin page context
			$order_id = absint( $_GET['id'] );
		}
		
		if ( ! $order_id ) {
			return;
		}
		
		wp_enqueue_script( 'jquery' );
		
		$metabox_js = "
			jQuery(document).ready(function($) {
				$('#devikit-wfirma-create-invoice').on('click', function() {
					var \$btn = $(this);
					var \$loading = $('#devikit-wfirma-loading');
					var \$error = $('#devikit-wfirma-error');
					
					\$btn.hide();
					\$loading.show();
					\$error.text('');

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

					$.post(ajaxurl, {
						action: 'devikit_wfirma_send_invoice_email',
						order_id: \$btn.data('order-id'),
						nonce: '" . esc_js( wp_create_nonce( 'wfirma_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 : '" . esc_js( __( 'Unknown error', 'invoicing-integration-for-wfirma-and-woocommerce' ) ) . "');
						}
					}).fail(function(xhr, status, error) {
						\$loading.hide();
						\$btn.prop('disabled', false).show();
						\$error.text('AJAX Error: ' + error);
					});
					
					return false;
				});
			});
		";
		
		wp_add_inline_script( 'jquery', $metabox_js );
	}

	/**
	 * Render Meta Box
	 */
	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( '_wfirma_invoice_id' );
		$invoice_number = $order->get_meta( '_wfirma_invoice_number' );
		
		$proforma_id = $order->get_meta( '_wfirma_proforma_id' );
		$proforma_number = $order->get_meta( '_wfirma_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\WfirmaPro\Plugin' );

		?>
		<div class="devikit-wfirma-metabox">
			<?php 
			// Proforma display
			if ( $proforma_id ) :
				if ( $is_pro_installed ) :
					// PRO with valid license - use hook for full functionality
					do_action( 'devikit_wfirma_metabox_proforma_display', $order, $proforma_id, $proforma_number );
				else :
					// No PRO or invalid license - show read-only proforma info
					?>
					<p>
						<strong><?php echo esc_html__( 'Proforma Created:', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?></strong><br>
						<?php echo esc_html( $proforma_number ?: $proforma_id ); ?>
					</p>
					<p>
						<button type="button" class="button" id="devikit-wfirma-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-wfirma-and-woocommerce' ); ?>
						</button>
					</p>
					<p style="margin-top:10px;">
						<button type="button" class="button" disabled style="opacity:0.5; cursor:not-allowed;">
							<?php echo esc_html__( 'Send Proforma by Email', 'invoicing-integration-for-wfirma-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-wfirma-and-woocommerce' ),
								'<a href="https://devikit.pl/produkt/wfirma-woocommerce-pro/" target="_blank" style="color:#2271b1;">' . esc_html__( 'PRO version', 'invoicing-integration-for-wfirma-and-woocommerce' ) . '</a>'
							);
							?>
						</small>
					</p>
					<hr style="margin:15px 0;">
					<?php
				endif;
			endif;
			?>
			
			<?php if ( $invoice_id ) : ?>
				<p>
					<strong><?php echo esc_html__( 'Invoice Created:', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?></strong><br>
					<?php echo esc_html( $invoice_number ?: $invoice_id ); ?>
				</p>
				
				<?php
				// Check for total mismatch
				$has_total_mismatch = $order->get_meta( '_wfirma_invoice_total_mismatch' ) === 'yes';
				if ( $has_total_mismatch ) {
					$order_total = floatval( $order->get_meta( '_wfirma_invoice_order_total' ) );
					$invoice_total = floatval( $order->get_meta( '_wfirma_invoice_wfirma_total' ) );
					$difference = floatval( $order->get_meta( '_wfirma_invoice_total_difference' ) );
					?>
					<div style="background: #fff3cd; border-left: 4px solid #ffc107; padding: 10px; margin: 10px 0;">
						<p style="margin: 0; font-weight: bold; color: #856404;">
							<?php echo esc_html__( '⚠ Total Mismatch Detected', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?>
						</p>
						<p style="margin: 5px 0 0 0; color: #856404;">
						<?php 
						printf(
							/* translators: 1: Order total, 2: Invoice total, 3: Difference */
							esc_html__( 'Order total: %1$s | Invoice total: %2$s | Difference: %3$s', 'invoicing-integration-for-wfirma-and-woocommerce' ),
							number_format( $order_total, 2, ',', ' ' ),
							number_format( $invoice_total, 2, ',', ' ' ),
								number_format( $difference, 2, ',', ' ' )
							);
							?>
						</p>
						<p style="margin: 5px 0 0 0; color: #856404; font-size: 12px;">
							<?php echo esc_html__( 'Email was not sent automatically. Please review the invoice and send manually if needed.', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?>
						</p>
					</div>
					<?php
				}
				?>
				
				<p>
					<button type="button" class="button" id="devikit-wfirma-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-wfirma-and-woocommerce' ); ?>
					</button>
				</p>
				<p style="margin-top:10px;">
					<?php if ( $is_pro_installed ) : ?>
						<button type="button" class="button" id="devikit-wfirma-send-email" 
								data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
							<?php echo esc_html__( 'Send Invoice by Email', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?>
						</button>
						<span id="devikit-wfirma-email-loading" style="display:none;"><?php echo esc_html__( 'Sending...', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?></span>
						<span id="devikit-wfirma-email-success" style="color:green; display:none;"><?php echo esc_html__( '✓ Sent', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?></span>
						<p id="devikit-wfirma-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-wfirma-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-wfirma-and-woocommerce' ),
							'<a href="https://devikit.pl/produkt/wfirma-woocommerce-pro/" target="_blank" style="color:#2271b1;">' . esc_html__( 'PRO version', 'invoicing-integration-for-wfirma-and-woocommerce' ) . '</a>'
						);
							?>
						</small>
					<?php endif; ?>
				</p>
			<?php endif; ?>
			
			<?php if ( ! $invoice_id || ! $proforma_id ) : ?>
				<?php if ( ! $invoice_id && ! $proforma_id ) : ?>
					<p><?php echo esc_html__( 'No documents created yet.', 'invoicing-integration-for-wfirma-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-wfirma-create-invoice" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
							<?php echo esc_html__( 'Create Invoice', 'invoicing-integration-for-wfirma-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-wfirma-create-proforma" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
								<?php echo esc_html__( 'Create Proforma', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?>
							</button>
							<span id="devikit-wfirma-proforma-loading" style="display:none;"><?php echo esc_html__( 'Creating proforma...', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?></span>
							<p id="devikit-wfirma-proforma-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__( 'Create Proforma', 'invoicing-integration-for-wfirma-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-wfirma-and-woocommerce' ),
									'<a href="https://devikit.pl/produkt/wfirma-woocommerce-pro/" target="_blank" style="color:#2271b1;">' . esc_html__( 'PRO version', 'invoicing-integration-for-wfirma-and-woocommerce' ) . '</a>'
								);
								?>
							</small>
						<?php endif; ?>
					</p>
				<?php endif; ?>
				<span id="devikit-wfirma-loading" style="display:none;"><?php echo esc_html__( 'Creating invoice...', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?></span>
				<p id="devikit-wfirma-error" style="color:red; margin-top:10px;"></p>
			<?php endif; ?>
		</div>

		<?php
		// Hook for PRO features (e.g., receipts) to be displayed after main invoice/proforma content
		if ( $is_pro_installed ) {
			do_action( 'devikit_wfirma_metabox_after_invoice', $order );
		} else {
			// FREE version or PRO without valid license - show disabled receipt section
			?>
			<div class="wfirma-receipt-section" style="margin-top: 15px; padding-top: 15px; border-top: 1px solid #ddd;">
				<h4 style="margin: 0 0 10px 0;"><?php echo esc_html__( 'Receipt', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?></h4>
				<p>
					<button type="button" class="button" disabled style="opacity:0.5; cursor:not-allowed;">
						<?php echo esc_html__( 'Create Receipt', 'invoicing-integration-for-wfirma-and-woocommerce' ); ?> 🔒
					</button>
					<br>
					<small style="color:#666; margin-top:5px; display:block;">
						<?php 
						printf(
							/* translators: %s: link to PRO version */
							esc_html__( 'Receipts available in %s', 'invoicing-integration-for-wfirma-and-woocommerce' ),
							'<a href="https://devikit.pl/produkt/wfirma-woocommerce-pro/" target="_blank" style="color:#2271b1; text-decoration:none;">' . esc_html__( 'PRO version', 'invoicing-integration-for-wfirma-and-woocommerce' ) . '</a>'
						);
						?>
					</small>
				</p>
			</div>
			<?php
		}
		?>
		<?php
	}

	/**
	 * AJAX Create Invoice
	 */
	public function ajax_create_invoice() {
		check_ajax_referer( 'wfirma_create_invoice', 'nonce' );
		
		if ( ! current_user_can( 'edit_shop_orders' ) ) {
			wp_send_json_error( [ 'message' => __( 'Unauthorized', 'invoicing-integration-for-wfirma-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-wfirma-and-woocommerce' ) ] );
		}

		$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 Download PDF
	 */
	public function ajax_download_pdf() {
		check_ajax_referer( 'wfirma_download_pdf', 'nonce' );
		
		if ( ! current_user_can( 'edit_shop_orders' ) ) {
			wp_send_json_error( [ 'message' => __( 'Unauthorized', 'invoicing-integration-for-wfirma-and-woocommerce' ) ] );
		}

		$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';
		$document_type = isset( $_POST['document_type'] ) ? sanitize_text_field( wp_unslash( $_POST['document_type'] ) ) : 'invoice';

		if ( ! $invoice_id ) {
			wp_send_json_error( [ 'message' => __( 'Invoice ID missing', 'invoicing-integration-for-wfirma-and-woocommerce' ) ] );
		}

		// Use receipt download method for receipts, invoice method for invoices/proformas
		if ( $document_type === 'receipt' && method_exists( $this->api_client, 'download_receipt_pdf' ) ) {
			$pdf_content = $this->api_client->download_receipt_pdf( $invoice_id );
		} else {
			$pdf_content = $this->api_client->download_invoice_pdf( $invoice_id );
		}

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

		if ( empty( $pdf_content ) ) {
			wp_send_json_error( [ 'message' => __( 'PDF content is empty', 'invoicing-integration-for-wfirma-and-woocommerce' ) ] );
		}

		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() {
		check_ajax_referer( 'wfirma_send_email', 'nonce' );
		
		if ( ! current_user_can( 'edit_shop_orders' ) ) {
			wp_send_json_error( [ 'message' => __( 'Unauthorized', 'invoicing-integration-for-wfirma-and-woocommerce' ) ] );
		}
		
		if ( ! class_exists( 'Devikit\WfirmaPro\Plugin' ) ) {
			wp_send_json_error( [ 'message' => __( 'PRO version required', 'invoicing-integration-for-wfirma-and-woocommerce' ) ] );
		}
		
		WC()->mailer();

		$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-wfirma-and-woocommerce' ) ] );
		}
		
		$invoice_id = $order->get_meta( '_wfirma_invoice_id' );
		$invoice_number = $order->get_meta( '_wfirma_invoice_number' );
		
		if ( ! $invoice_id ) {
			wp_send_json_error( [ 'message' => __( 'Invoice not found', 'invoicing-integration-for-wfirma-and-woocommerce' ) ] );
		}
		
		$invoice_data = [
			'url' => 'https://system.wfirma.pl/invoices/details/id/' . $invoice_id,
			'number' => $invoice_number,
			'id' => $invoice_id
		];
		
		do_action( 'devikit_wfirma_invoice_generated', $order_id, $invoice_data );
		
		$order->add_order_note( __( 'Invoice email sent to customer', 'invoicing-integration-for-wfirma-and-woocommerce' ) );

		wp_send_json_success( [ 'message' => __( 'Email sent successfully', 'invoicing-integration-for-wfirma-and-woocommerce' ) ] );
	}

	/**
	 * Create Invoice for Order
	 * 
	 * @param \WC_Order $order
	 * @param bool $is_automatic Whether invoice is created automatically (for email sending logic)
	 */
	public function create_invoice_for_order( $order, $is_automatic = false ) {
		// Prevent duplicate invoices - return existing ID if invoice already created.
		$existing_invoice_id = $order->get_meta( '_wfirma_invoice_id' );
		if ( ! empty( $existing_invoice_id ) ) {
			return $existing_invoice_id;
		}

		$contractor_id = $this->get_or_create_contractor( $order );
		if ( is_wp_error( $contractor_id ) ) {
			return $contractor_id;
		}

		$invoice_data = $this->prepare_invoice_data( $order, $contractor_id );
		$invoice_data = apply_filters( 'devikit_wfirma_invoice_data', $invoice_data, $order );
		
		$this->api_client->log( 'Invoice data prepared: ' . wp_json_encode( $invoice_data, JSON_UNESCAPED_UNICODE ), 'debug' );

		$response = $this->api_client->create_invoice( $invoice_data );

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

		// Log full API response for debugging
		$this->api_client->log( 'Invoice API response: ' . wp_json_encode( $response, JSON_UNESCAPED_UNICODE ), 'debug' );

		// API response structure: invoices['0']['invoice'] or invoices[0]
		$invoice = null;
		if ( isset( $response['invoices']['0']['invoice'] ) ) {
			$invoice = $response['invoices']['0']['invoice'];
		} elseif ( isset( $response['invoices'][0]['invoice'] ) ) {
			$invoice = $response['invoices'][0]['invoice'];
		} elseif ( isset( $response['invoices'][0] ) ) {
			$invoice = $response['invoices'][0];
		}

		if ( $invoice && isset( $invoice['id'] ) ) {
			$invoice_id = $invoice['id'];
			$invoice_number = $invoice['fullnumber'] ?? $invoice['number'] ?? '';
			
			// Get invoice total from wFirma response
			// Try to get full invoice details if total not in response
			$invoice_total = 0;
			if ( isset( $invoice['price'] ) ) {
				$invoice_total = floatval( $invoice['price'] );
			} elseif ( isset( $invoice['total'] ) ) {
				$invoice_total = floatval( $invoice['total'] );
			} elseif ( isset( $invoice['price_gross'] ) ) {
				$invoice_total = floatval( $invoice['price_gross'] );
			} else {
				// Fetch full invoice details to get total
				$full_invoice = $this->api_client->get_invoice( $invoice_id );
				if ( ! is_wp_error( $full_invoice ) && isset( $full_invoice['invoices'][0]['invoice'] ) ) {
					$full_invoice_data = $full_invoice['invoices'][0]['invoice'];
					if ( isset( $full_invoice_data['price'] ) ) {
						$invoice_total = floatval( $full_invoice_data['price'] );
					} elseif ( isset( $full_invoice_data['total'] ) ) {
						$invoice_total = floatval( $full_invoice_data['total'] );
					} elseif ( isset( $full_invoice_data['price_gross'] ) ) {
						$invoice_total = floatval( $full_invoice_data['price_gross'] );
					}
				}
			}
			
			// Compare with order total (gross total including taxes)
			$order_total = floatval( $order->get_total() );
			$total_difference = abs( $invoice_total - $order_total );
			
			// Any difference, even 0.01 grosz, should be marked as mismatch
			// Use small tolerance (0.001) to account for float precision issues
			$has_total_mismatch = $total_difference >= 0.001;
			
			$order->update_meta_data( '_wfirma_invoice_id', $invoice_id );
			$order->update_meta_data( '_wfirma_invoice_number', $invoice_number );
			
			if ( $has_total_mismatch ) {
				$order->update_meta_data( '_wfirma_invoice_total_mismatch', 'yes' );
				$order->update_meta_data( '_wfirma_invoice_order_total', $order_total );
				$order->update_meta_data( '_wfirma_invoice_wfirma_total', $invoice_total );
			$order->update_meta_data( '_wfirma_invoice_total_difference', $total_difference );
			$order->add_order_note( sprintf( 
				/* translators: 1: Invoice number/ID, 2: Order total, 3: Invoice total */
				__( 'wFirma Invoice created: %1$s (Total mismatch: Order %2$s vs Invoice %3$s)', 'invoicing-integration-for-wfirma-and-woocommerce' ), 
				$invoice_number ?: $invoice_id,
				number_format( $order_total, 2, ',', ' ' ),
					number_format( $invoice_total, 2, ',', ' ' )
				) );
			} else {
				$order->delete_meta_data( '_wfirma_invoice_total_mismatch' );
				$order->delete_meta_data( '_wfirma_invoice_order_total' );
				$order->delete_meta_data( '_wfirma_invoice_wfirma_total' );
			$order->delete_meta_data( '_wfirma_invoice_total_difference' );
			/* translators: %s: Invoice number/ID */
			$order->add_order_note( sprintf( __( 'wFirma Invoice created: %s', 'invoicing-integration-for-wfirma-and-woocommerce' ), $invoice_number ?: $invoice_id ) );
			}
			
			$order->save();
			
			// Only send email if totals match
			if ( ! $has_total_mismatch ) {
				$this->maybe_send_invoice_email( $order, $invoice, $is_automatic );
			}
			
			return $invoice_id;
		}

		return new \WP_Error( 'wfirma_unknown_error', __( 'Unknown response from wFirma API', 'invoicing-integration-for-wfirma-and-woocommerce' ) );
	}
	
	/**
	 * Maybe send invoice email (if automation email is enabled)
	 * 
	 * For automatic invoice creation, the email is delayed by 5 minutes
	 * to allow KSeF (Krajowy System e-Faktur) to process the invoice first.
	 * Manual invoice creation (by admin) sends the email immediately.
	 */
	private function maybe_send_invoice_email( $order, $invoice, $is_automatic = false ) {
		if ( ! class_exists( 'Devikit\WfirmaPro\Plugin' ) ) {
			return;
		}
		
		$pro_settings = get_option( 'devikit_wfirma_pro_settings', [] );
		
		if ( empty( $pro_settings['send_invoice_email'] ) || $pro_settings['send_invoice_email'] !== 'yes' ) {
			return;
		}
		
		$invoice_data = [
			'url' => 'https://system.wfirma.pl/invoices/details/id/' . $invoice['id'],
			'number' => $invoice['fullnumber'] ?? $invoice['number'] ?? '',
			'id' => $invoice['id']
		];
		
		if ( $is_automatic ) {
			// Schedule email with 5-minute delay to allow KSeF processing
			$delay_minutes = apply_filters( 'devikit_wfirma_invoice_email_delay_minutes', 5 );
			
			as_schedule_single_action(
				time() + ( $delay_minutes * 60 ),
				'devikit_wfirma_send_delayed_invoice_email',
				[
					'order_id'     => $order->get_id(),
					'invoice_data' => $invoice_data,
				],
				'devikit-wfirma'
			);
			
			$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-wfirma-and-woocommerce' ),
				$delay_minutes
			) );
		} else {
			// Manual invoice creation — send immediately
			WC()->mailer();
			do_action( 'devikit_wfirma_invoice_generated', $order->get_id(), $invoice_data );
			$order->add_order_note( __( 'Invoice email sent to customer automatically', 'invoicing-integration-for-wfirma-and-woocommerce' ) );
		}
	}
	
	/**
	 * Handle delayed invoice email (called by Action Scheduler)
	 * 
	 * @param int   $order_id     Order ID
	 * @param array $invoice_data Invoice data (url, number, id)
	 */
	public function handle_delayed_invoice_email( $order_id, $invoice_data ) {
		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			return;
		}
		
		WC()->mailer();
		do_action( 'devikit_wfirma_invoice_generated', $order_id, $invoice_data );
		
		$order->add_order_note( __( 'Invoice email sent to customer (delayed — after KSeF processing)', 'invoicing-integration-for-wfirma-and-woocommerce' ) );
	}

	/**
	 * Get or Create Contractor
	 */
	private function get_or_create_contractor( $order ) {
		$nip = $order->get_meta( '_billing_nip' );
		if ( empty( $nip ) ) {
			$nip = $order->get_meta( 'vat_number' );
		}

		$is_company = ! empty( $order->get_billing_company() );
		$country = $order->get_billing_country();
		
		$contractor_data = [
			'name'     => $is_company ? $order->get_billing_company() : trim( $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ),
			'street'   => $order->get_billing_address_1(),
			'zip'      => $order->get_billing_postcode(),
			'city'     => $order->get_billing_city(),
			'country'  => $country,
			'email'    => $order->get_billing_email(),
			'phone'    => $order->get_billing_phone(),
		];

		// Set tax_id_type based on NIP presence and country
		$contractor_data['tax_id_type'] = 'none';
		if ( ! empty( $nip ) ) {
			// For Polish NIP, remove non-numeric characters (no country prefix)
			// For foreign VAT, keep original format with country prefix (e.g., "DE123456789")
			if ( $country === 'PL' ) {
				$contractor_data['nip'] = preg_replace( '/[^0-9]/', '', $nip );
				$contractor_data['tax_id_type'] = 'nip';
			} else {
				// Keep original VAT with country prefix, but remove spaces/dashes for API
				$contractor_data['nip'] = preg_replace( '/[\s\-]/', '', $nip );
				$contractor_data['tax_id_type'] = 'vat';
			}
		}

		// Try to find existing contractor
		$existing = $this->api_client->contractors_find( $contractor_data );
		if ( $existing && isset( $existing['id'] ) ) {
			$this->api_client->log( 'Using existing contractor ID: ' . $existing['id'], 'debug' );
			return intval( $existing['id'] );
		}

		// Create new contractor
		$response = $this->api_client->create_contractor( $contractor_data );

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

		// Handle response structure: contractors[0].contractor.id or contractors[0].id
		if ( isset( $response['contractors'][0]['contractor']['id'] ) ) {
			return intval( $response['contractors'][0]['contractor']['id'] );
		} elseif ( isset( $response['contractors'][0]['id'] ) ) {
			return intval( $response['contractors'][0]['id'] );
		}
		
		return new \WP_Error( 'create_contractor_fail', __( 'Failed to create contractor - no ID in response', 'invoicing-integration-for-wfirma-and-woocommerce' ) );
	}

	/**
	 * Prepare Invoice Data
	 */
	public function prepare_invoice_data( $order, $contractor_id, $type = 'normal' ) {
		$settings = get_option( 'devikit_wfirma_settings', [] );
		
		$invoice_date = current_time( 'Y-m-d' );
		$sale_date = $order->get_date_created()->date( 'Y-m-d' );
		
		$payment_days = isset( $settings['payment_deadline_days'] ) ? intval( $settings['payment_deadline_days'] ) : 7;
		$payment_date = gmdate( 'Y-m-d', strtotime( $invoice_date . ' + ' . $payment_days . ' days' ) );
		
		// Get order currency (default to PLN if not set)
		$currency = $order->get_currency();
		if ( empty( $currency ) ) {
			$currency = 'PLN';
		}
		
		// Determine payment method and paid status
		$wc_payment_method = $order->get_payment_method();
		$wfirma_payment_method = 'transfer'; // default
		
		// For COD (cash on delivery), invoice is never paid (payment happens on delivery)
		$is_paid = 0;
		if ( $wc_payment_method === 'cod' ) {
			$wfirma_payment_method = 'cod';
			$is_paid = 0; // COD is never paid upfront
		} else {
			// For other payment methods, check if order is actually paid
			$order_status = $order->get_status();
			
			// Completed orders are always considered paid (unless COD)
			if ( $order_status === 'completed' ) {
				$is_paid = 1;
			} elseif ( $order_status === 'processing' ) {
				// Processing - only mark as paid if WooCommerce says it's paid
				// This handles cases where payment was received but order is still processing
				if ( $order->is_paid() ) {
					$is_paid = 1;
				}
			} elseif ( $order->is_paid() ) {
				// For other statuses, trust WooCommerce is_paid() method
				$is_paid = 1;
			}
		}
		
		$data = [
			'contractor_id'      => intval( $contractor_id ),
			'date'               => $invoice_date,
			'disposal_date'      => $sale_date,
			'payment_date'       => $payment_date,
			'payment_method'     => $wfirma_payment_method,
			'paid'               => $is_paid,
			'currency'           => $currency,
			'invoicecontents'    => [],
		];

		if ( $type === 'proforma' ) {
			$data['invoice_type'] = 'proforma';
			$data['paid'] = 0;
		} else {
			// For non-VAT businesses in wFirma, invoices are often issued as "bill".
			// We keep backward compatibility (default is normal) and switch type based on selected series type.
			if ( ! empty( $settings['series_type'] ) && is_string( $settings['series_type'] ) ) {
				$series_type = sanitize_key( $settings['series_type'] );
				if ( in_array( $series_type, [ 'bill', 'normal' ], true ) && $series_type !== 'normal' ) {
					$data['invoice_type'] = $series_type;
				}
			}
		}

		if ( ! empty( $settings['series_id'] ) ) {
			$data['series_id'] = intval( $settings['series_id'] );
		}

		// Find account ID by account number from settings (for both paid and unpaid invoices)
		// Always use the account selected in settings
		$company_accounts = $this->api_client->get_company_accounts();
		$found_account = null;
		$account_currency = 'PLN';
		
		// Find account by number from settings
		if ( ! empty( $settings['bank_account'] ) ) {
			$this->api_client->log( sprintf( 'Looking for account with number: %s', $settings['bank_account'] ), 'debug' );
			foreach ( $company_accounts as $account ) {
				$account_number = isset( $account['number'] ) ? $account['number'] : '';
				$this->api_client->log( sprintf( 'Checking account: ID=%s, Number=%s, Currency=%s', 
					isset( $account['id'] ) ? $account['id'] : 'N/A',
					$account_number,
					isset( $account['currency'] ) ? $account['currency'] : 'PLN'
				), 'debug' );
				if ( $account_number === $settings['bank_account'] ) {
					$found_account = $account;
					$this->api_client->log( sprintf( 'Found matching account: ID=%s', $account['id'] ), 'debug' );
					break;
				}
			}
			if ( ! $found_account ) {
				$this->api_client->log( sprintf( 'Account not found for number: %s. Available accounts: %d', $settings['bank_account'], count( $company_accounts ) ), 'warning' );
			}
		}
		
		// Set paymentmethod_name and company_account_id from found account
		if ( $found_account && isset( $found_account['id'] ) ) {
			$data['company_account_id'] = intval( $found_account['id'] );
			$account_currency = isset( $found_account['currency'] ) ? $found_account['currency'] : 'PLN';
			$data['paymentmethod_name'] = $settings['bank_account'];
		} elseif ( ! empty( $settings['bank_account'] ) ) {
			// If account not found but bank_account is set, use it as paymentmethod_name
			$data['paymentmethod_name'] = $settings['bank_account'];
		}
		
		// For paid invoices, we also need alreadypaid_initial
		if ( $data['paid'] == 1 ) {
			// Set alreadypaid_initial
			$data['alreadypaid_initial'] = number_format( (float) $order->get_total(), 2, '.', '' );
			
			// For foreign currency invoices, add payment field with account type
			if ( $currency !== 'PLN' && isset( $data['company_account_id'] ) ) {
				// Determine account type based on account currency
				$account_type = ( $account_currency === $currency ) ? 'currency' : 'pln';
				
				// For paid invoices, payment date should be the invoice date (date of payment)
				$actual_payment_date = $invoice_date; // Date when payment was received
				
				$payment_data = [
					'date' => $actual_payment_date,
					'account' => $account_type,
				];
				
				// If account is PLN, add value_pln (convert EUR to PLN)
				if ( $account_type === 'pln' ) {
					// Get order total in base currency (PLN) if available
					// WooCommerce stores totals in order currency, so we need to get base currency total
					$order_total_pln = $order->get_meta( '_order_total_base_currency' );
					if ( empty( $order_total_pln ) ) {
						// Fallback: use order total (might be in EUR, but wFirma will handle conversion)
						$order_total_pln = $order->get_total();
					}
					$payment_data['value_pln'] = number_format( (float) $order_total_pln, 2, '.', '' );
				}
				
				$data['payment'] = $payment_data;
			}
		}

		$is_moss_order = $this->is_moss_order( $order );

		foreach ( $order->get_items() as $item ) {
			$product = $item->get_product();
			
			$tax_symbol = $this->get_item_tax_symbol( $item, $product, $settings, $is_moss_order );
			
			// First round the total, then divide by quantity, then round again
			$item_total = round( floatval( $item->get_total() ), 2 );
			$unit_price_net = round( $item_total / floatval( $item->get_quantity() ), 2 );
			
			// Get unit of measure
			$unit = isset( $settings['default_product_unit'] ) && ! empty( $settings['default_product_unit'] ) 
				? $settings['default_product_unit'] 
				: 'szt.';
			
			// Check if product has custom unit meta field (PRO feature)
			if ( $product ) {
				$custom_unit = get_post_meta( $product->get_id(), '_wfirma_unit_of_measure', true );
				if ( ! empty( $custom_unit ) ) {
					$unit = $custom_unit;
				}
			}
			
			$content = [
				'name'         => $item->get_name(),
				'count'        => floatval( $item->get_quantity() ),
				'unit'         => $unit,
				'price'        => round( $unit_price_net, 2 ),
				'vat'          => $tax_symbol,
			];
			
			// Add lump sum (ryczałt) code if enabled
			$lump_sum_enabled = isset( $settings['lump_sum_enable'] ) && $settings['lump_sum_enable'] === 'yes';
			if ( $lump_sum_enabled && $product ) {
				$variation_id = null;
				if ( $product->is_type( 'variation' ) ) {
					$variation_id = $product->get_id();
				} elseif ( $item->get_variation_id() ) {
					$variation_id = $item->get_variation_id();
				}
				
				$default_lump_sum = isset( $settings['lump_sum_default_value'] ) ? $settings['lump_sum_default_value'] : 'empty';
				$product_lump_sum = '';
				
				if ( class_exists( 'Devikit\WfirmaPro\Admin\LumpSumManager' ) ) {
					$product_lump_sum = \Devikit\WfirmaPro\Admin\LumpSumManager::get_product_lump_sum( $product, $variation_id, $default_lump_sum );
				} else {
					// Fallback: read meta directly when PRO plugin class not available
					if ( $variation_id ) {
						$product_lump_sum = get_post_meta( $variation_id, '_wfirma_lump_sum', true );
					}
					if ( empty( $product_lump_sum ) || $product_lump_sum === 'empty' ) {
						$product_lump_sum = get_post_meta( $product->get_id(), '_wfirma_lump_sum', true );
					}
					if ( ( empty( $product_lump_sum ) || $product_lump_sum === 'empty' ) && ! empty( $default_lump_sum ) && $default_lump_sum !== 'empty' ) {
						$product_lump_sum = $default_lump_sum;
					}
				}
				
				if ( ! empty( $product_lump_sum ) && $product_lump_sum !== 'empty' ) {
					$content['lumpcode'] = $product_lump_sum;
				}
			}
			
			// Map product to wFirma good if warehouse sync is enabled
			$warehouse_settings = get_option( 'devikit_wfirma_warehouse_settings', [] );
			$warehouse_enabled = isset( $warehouse_settings['enable_warehouse_sync'] ) && $warehouse_settings['enable_warehouse_sync'] === 'yes';
			
			if ( $warehouse_enabled && $product ) {
				try {
					// Get product identifier (SKU or Product Code)
					$woocommerce_id_field = isset( $warehouse_settings['woocommerce_product_id'] ) ? $warehouse_settings['woocommerce_product_id'] : 'sku';
					$product_identifier = '';
					
					if ( $woocommerce_id_field === 'sku' ) {
						$product_identifier = $product->get_sku();
					} else {
						// Product Code - use _wfirma_kod_produktu which is the key used by ProductCodeManager
						$product_identifier = get_post_meta( $product->get_id(), '_wfirma_kod_produktu', true );
					}
					
					if ( ! empty( $product_identifier ) ) {
						// Use transient cache to avoid repeated API calls
						$cache_key = 'wfirma_good_' . md5( $product_identifier );
						$wfirma_good = get_transient( $cache_key );
						
						if ( false === $wfirma_good ) {
						// Find product in wFirma by code (with timeout protection)
						$this->api_client->log( 'Looking for wFirma good with code: ' . $product_identifier, 'debug' );
						
						// Set timeout and error handler
						$old_time_limit = ini_get( 'max_execution_time' );
						// phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Timeout protection for API calls
						@set_time_limit( 10 );
						
						$wfirma_good = $this->api_client->find_good_by_sku( $product_identifier );
					
					// Restore time limit
					if ( $old_time_limit ) {
						// phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged -- Restoring original timeout
						@set_time_limit( $old_time_limit );
					}
					
					$this->api_client->log( 'wFirma good lookup result: ' . wp_json_encode( $wfirma_good ), 'debug' );
							
							// Cache result for 1 hour if found
							if ( ! is_wp_error( $wfirma_good ) && $wfirma_good ) {
								set_transient( $cache_key, $wfirma_good, HOUR_IN_SECONDS );
							}
						}
						
						if ( ! is_wp_error( $wfirma_good ) && $wfirma_good && isset( $wfirma_good['id'] ) ) {
							$content['good'] = [ 'id' => intval( $wfirma_good['id'] ) ];
							$this->api_client->log( 'Mapped product to wFirma good ID: ' . $wfirma_good['id'], 'debug' );
						}
					}
				} catch ( \Exception $e ) {
					// Log error but don't block invoice creation
					$this->api_client->log( 'Error mapping product to wFirma good: ' . $e->getMessage(), 'error' );
				} catch ( \Throwable $e ) {
					// Log error but don't block invoice creation
					$this->api_client->log( 'Error mapping product to wFirma good: ' . $e->getMessage(), 'error' );
				}
			}
			
			$data['invoicecontents'][] = $content;
		}

		// Add notes (uwagi) from settings
		$notes = [];
		$default_notes = isset( $settings['invoice_notes'] ) ? trim( $settings['invoice_notes'] ) : '';
		if ( ! empty( $default_notes ) ) {
			$notes[] = $this->replace_order_variables( $default_notes, $order );
		}
		if ( ! empty( $notes ) ) {
			$data['description'] = implode( "\n", $notes );
		}

		$shipping_items = $order->get_items( 'shipping' );
		foreach ( $shipping_items as $shipping_item ) {
			if ( $shipping_item->get_total() > 0 ) {
				$shipping_tax = $this->get_shipping_tax_symbol( $shipping_item, $settings, $data['invoicecontents'], $is_moss_order );
				
				$content = [
					'name'  => ! empty( $shipping_item->get_name() ) ? $shipping_item->get_name() : __( 'Shipping', 'invoicing-integration-for-wfirma-and-woocommerce' ),
					'count' => 1,
					'unit'  => 'usł.',
					'price' => round( $shipping_item->get_total(), 2 ),
					'vat'   => $shipping_tax,
				];

				$lump_sum_enabled = isset( $settings['lump_sum_enable'] ) && $settings['lump_sum_enable'] === 'yes';
				if ( $lump_sum_enabled ) {
					$max_lumpcode = $this->get_highest_lumpcode( $data['invoicecontents'] );
					if ( $max_lumpcode ) {
						$content['lumpcode'] = $max_lumpcode;
					}
				}
				
				$data['invoicecontents'][] = $content;
			}
		}

		return $data;
	}

	/**
	 * Replace order variables in text
	 *
	 * @param string $text Text with placeholders
	 * @param \WC_Order $order Order object
	 * @return string Text with replaced variables
	 */
	public function replace_order_variables( $text, $order ) {
		if ( ! $order ) {
			return $text;
		}

		$replacements = [
			'{order_id}'              => $order->get_id(),
			'{order_number}'          => $order->get_order_number(),
			'{order_date}'            => $order->get_date_created() ? $order->get_date_created()->date_i18n( get_option( 'date_format' ) ) : '',
			'{order_date_raw}'        => $order->get_date_created() ? $order->get_date_created()->date( 'Y-m-d' ) : '',
			'{customer_name}'         => trim( $order->get_billing_first_name() . ' ' . $order->get_billing_last_name() ),
			'{customer_first_name}'   => $order->get_billing_first_name(),
			'{customer_last_name}'    => $order->get_billing_last_name(),
			'{customer_email}'        => $order->get_billing_email(),
			'{customer_phone}'        => $order->get_billing_phone(),
			'{billing_company}'       => $order->get_billing_company(),
			'{billing_nip}'           => $order->get_meta( '_billing_nip' ) ?: $order->get_meta( 'vat_number' ),
			'{billing_address}'       => $order->get_formatted_billing_address(),
			'{shipping_address}'      => $order->get_formatted_shipping_address(),
			'{order_total}'           => $order->get_total(),
			'{order_total_formatted}' => wc_price( $order->get_total(), [ 'currency' => $order->get_currency() ] ),
			'{payment_method}'        => $order->get_payment_method_title(),
			'{shipping_method}'       => $order->get_shipping_method(),
		];

		return str_replace( array_keys( $replacements ), array_values( $replacements ), $text );
	}

	/**
	 * Check if order should be treated as OSS/MOSS (PRO feature).
	 *
	 * @param \WC_Order $order Order object.
	 * @return bool
	 */
	private function is_moss_order( $order ) {
		if ( ! class_exists( '\Devikit\WfirmaPro\Core\MossManager' ) ) {
			return false;
		}

		$moss_manager = new \Devikit\WfirmaPro\Core\MossManager();

		return $moss_manager->is_moss_order( $order );
	}

	/**
	 * Get tax symbol for item
	 *
	 * @param \WC_Order_Item_Product $item         Order line item.
	 * @param \WC_Product|null       $product      Product.
	 * @param array                  $settings     Plugin settings.
	 * @param bool                   $is_moss_order Whether order is OSS/MOSS.
	 * @return string
	 */
	private function get_item_tax_symbol( $item, $product, $settings, $is_moss_order = false ) {
		if ( ! $product ) {
			return '23';
		}
		
		$tax_class = $product->get_tax_class();
		
		if ( ! empty( $tax_class ) ) {
			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';
			}
		}

		if ( $is_moss_order ) {
			return $this->get_order_line_vat_rate_symbol( $item );
		}
		
		$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';
			if ( $rate >= 7 && $rate <= 9 ) return '8';
			if ( $rate >= 4 && $rate <= 6 ) return '5';
			if ( $rate < 1 ) return '0';
		} elseif ( $total > 0 && $tax == 0 ) {
			return '0';
		}
		
		return '23';
	}

	/**
	 * Resolve VAT rate symbol from WooCommerce order line taxes (for OSS/MOSS).
	 *
	 * @param \WC_Order_Item $item Order line item.
	 * @return string
	 */
	private function get_order_line_vat_rate_symbol( $item ) {
		$taxes = $item->get_taxes();
		if ( ! empty( $taxes['total'] ) && is_array( $taxes['total'] ) ) {
			foreach ( $taxes['total'] as $tax_id => $tax_amount ) {
				if ( empty( $tax_amount ) ) {
					continue;
				}

				$tax_rate = \WC_Tax::get_rate_percent( $tax_id );
				if ( $tax_rate ) {
					$rate = (float) str_replace( '%', '', $tax_rate );
					return $this->format_vat_rate_symbol( $rate );
				}
			}
		}

		$total = (float) $item->get_total();
		$tax   = (float) $item->get_total_tax();

		if ( $total > 0 && $tax > 0 ) {
			return $this->format_vat_rate_symbol( ( $tax / $total ) * 100 );
		}

		if ( $total > 0 && $tax == 0 ) {
			return '0';
		}

		return '23';
	}

	/**
	 * Format VAT rate for invoice payload (supports decimal OSS rates, e.g. 25.5).
	 *
	 * @param float $rate VAT rate percent.
	 * @return string
	 */
	private function format_vat_rate_symbol( $rate ) {
		$rate = (float) $rate;

		if ( abs( $rate - round( $rate ) ) < 0.001 ) {
			return (string) (int) round( $rate );
		}

		return rtrim( rtrim( number_format( $rate, 1, '.', '' ), '0' ), '.' );
	}

	/**
	 * Get tax symbol for shipping
	 *
	 * @param \WC_Order_Item_Shipping $item              Shipping item.
	 * @param array                   $settings          Plugin settings.
	 * @param array                   $product_contents  Product lines already on invoice.
	 * @param bool                    $is_moss_order     Whether order is OSS/MOSS.
	 * @return string
	 */
	private function get_shipping_tax_symbol( $item, $settings, $product_contents, $is_moss_order = false ) {
		if ( ! empty( $product_contents ) ) {
			$tax_symbols = [];
			$has_standard = false;
			
			foreach ( $product_contents as $content ) {
				if ( isset( $content['vat'] ) ) {
					$tax = $content['vat'];
					$tax_symbols[] = $tax;
					
					if ( in_array( $tax, [ '23', '8', '5' ], true ) ) {
						$has_standard = true;
					}
				}
			}

			if ( $is_moss_order ) {
				$unique = array_unique( $tax_symbols );
				if ( count( $unique ) === 1 ) {
					return (string) $unique[0];
				}
			}
			
			if ( $has_standard ) {
				if ( in_array( '23', $tax_symbols, true ) ) return '23';
				if ( in_array( '8', $tax_symbols, true ) ) return '8';
				if ( in_array( '5', $tax_symbols, true ) ) return '5';
			}
			
			$unique = array_unique( $tax_symbols );
			if ( count( $unique ) === 1 ) {
				$rate = $unique[0];
				if ( in_array( $rate, [ 'zw', 'np', '0' ], true ) ) {
					return $rate;
				}
			}
		}

		if ( $is_moss_order ) {
			return $this->get_order_line_vat_rate_symbol( $item );
		}
		
		$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';
			if ( $rate >= 7 && $rate <= 9 ) return '8';
			if ( $rate >= 4 && $rate <= 6 ) return '5';
			if ( $rate < 1 ) return '0';
		} elseif ( $total > 0 && $tax == 0 ) {
			return '0';
		}
		
		return '23';
	}

	/**
	 * Find the highest lumpcode among already-added invoice contents.
	 *
	 * @param array $contents Invoice contents array (each element has optional 'lumpcode' key).
	 * @return string|null Highest lumpcode value or null if none found.
	 */
	private function get_highest_lumpcode( $contents ) {
		$max = null;

		foreach ( $contents as $item ) {
			if ( isset( $item['lumpcode'] ) && is_numeric( $item['lumpcode'] ) ) {
				$val = (float) $item['lumpcode'];
				if ( null === $max || $val > $max ) {
					$max = $val;
				}
			}
		}

		return null !== $max ? (string) $max : null;
	}

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

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

		$invoice_id = $order->get_meta( '_wfirma_invoice_id' );
		$invoice_number = $order->get_meta( '_wfirma_invoice_number' );

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

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

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

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

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

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

		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			wp_die( esc_html__( 'Order not found', 'invoicing-integration-for-wfirma-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-wfirma-and-woocommerce' ) );
		}

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

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

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

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

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

