<?php

namespace Devikit\Sellsy;

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

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

class InvoiceManager {

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

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

	/**
	 * @var TaxMapper
	 */
	private $tax_mapper;

	/**
	 * @var CustomerSync
	 */
	private $customer_sync;

	/**
	 * @var DocumentBuilder
	 */
	private $document_builder;

	/**
	 * @param Client    $api_client
	 * @param Settings  $settings
	 * @param TaxMapper $tax_mapper
	 */
	public function __construct( Client $api_client, Settings $settings, TaxMapper $tax_mapper ) {
		$this->api_client       = $api_client;
		$this->settings         = $settings;
		$this->tax_mapper       = $tax_mapper;
		$this->customer_sync    = new CustomerSync( $api_client );
		$this->document_builder = new DocumentBuilder( $api_client, $settings, $tax_mapper );

		add_action( 'add_meta_boxes', [ $this, 'add_order_meta_box' ] );
		add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_metabox_scripts' ] );

		add_action( 'wp_ajax_devikit_sellsy_create_invoice', [ $this, 'ajax_create_invoice' ] );
		add_action( 'wp_ajax_devikit_sellsy_download_pdf', [ $this, 'ajax_download_pdf' ] );

		add_action( 'woocommerce_view_order', [ $this, 'display_invoice_download_button' ], 20 );
		add_action( 'template_redirect', [ $this, 'handle_invoice_download' ] );
	}

	public function add_order_meta_box() {
		$screens = [ 'shop_order' ];

		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()
		) {
			$screens[] = wc_get_page_screen_id( 'shop_order' );
		}

		foreach ( $screens as $screen ) {
			add_meta_box(
				'devikit_sellsy_invoice',
				__( 'Sellsy', 'invoicing-integration-for-sellsy-and-woocommerce' ),
				[ $this, 'render_meta_box' ],
				$screen,
				'side',
				'high'
			);
		}
	}

	/**
	 * @param string $hook_suffix
	 */
	public function enqueue_metabox_scripts( $hook_suffix ) {
		if ( ! in_array( $hook_suffix, [ 'post.php', 'woocommerce_page_wc-orders' ], true ) ) {
			return;
		}

		if ( ! current_user_can( 'edit_shop_orders' ) && ! current_user_can( 'manage_woocommerce' ) ) {
			return;
		}

		global $post;
		$order_id = null;

		if ( $post && $post->post_type === 'shop_order' ) {
			$order_id = $post->ID;
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- admin screen context only; no data mutation.
		} elseif ( isset( $_GET['id'] ) ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- admin screen context only; no data mutation.
			$order_id = absint( $_GET['id'] );
		}

		if ( ! $order_id || ( ! current_user_can( 'edit_shop_order', $order_id ) && ! current_user_can( 'edit_shop_orders' ) ) ) {
			return;
		}

		wp_enqueue_style(
			'devikit-sellsy-admin',
			DEVIKIT_SELLSY_URL . 'assets/css/admin.css',
			[],
			DEVIKIT_SELLSY_VERSION
		);

		wp_enqueue_script(
			'devikit-sellsy-admin-order',
			DEVIKIT_SELLSY_URL . 'assets/js/admin-order.js',
			[ 'jquery' ],
			DEVIKIT_SELLSY_VERSION,
			true
		);

		wp_localize_script(
			'devikit-sellsy-admin-order',
			'devikitSellsyOrder',
			[
				'ajaxUrl' => admin_url( 'admin-ajax.php' ),
				'nonces'  => [
					'create' => wp_create_nonce( 'sellsy_create_invoice' ),
					'pdf'    => wp_create_nonce( 'sellsy_download_pdf' ),
				],
				'i18n'    => [
					'creating'    => __( 'Creating invoice...', 'invoicing-integration-for-sellsy-and-woocommerce' ),
					'createFail'  => __( 'Failed to create invoice.', 'invoicing-integration-for-sellsy-and-woocommerce' ),
					'downloading' => __( 'Downloading...', 'invoicing-integration-for-sellsy-and-woocommerce' ),
					'pdfFail'     => __( 'Failed to download PDF.', 'invoicing-integration-for-sellsy-and-woocommerce' ),
				],
			]
		);
	}

	/**
	 * @param \WP_Post|\WC_Order|int $post_or_order
	 */
	public function render_meta_box( $post_or_order ) {
		if ( is_numeric( $post_or_order ) ) {
			$order = wc_get_order( $post_or_order );
		} elseif ( $post_or_order instanceof \WC_Order ) {
			$order = $post_or_order;
		} else {
			$order = wc_get_order( $post_or_order->ID );
		}

		if ( ! $order ) {
			return;
		}

		$invoice_id     = $order->get_meta( '_sellsy_invoice_id' );
		$invoice_number = $order->get_meta( '_sellsy_invoice_number' );
		$invoice_status = $order->get_meta( '_sellsy_invoice_status' );
		$last_error     = $order->get_meta( '_sellsy_last_error' );

		$pro_installed = class_exists( 'Devikit\SellsyPro\Plugin' );
		$pro_url       = 'https://devikit.fr/produit/sellsy-woocommerce-pro/';

		?>
		<div class="devikit-sellsy-metabox">
			<?php if ( $invoice_id ) : ?>
				<p>
					<strong><?php esc_html_e( 'Invoice Created:', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?></strong><br>
					<?php echo esc_html( $invoice_number ? $invoice_number : $invoice_id ); ?>
				</p>
				<?php if ( $invoice_status ) : ?>
					<p>
						<strong><?php esc_html_e( 'Status:', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?></strong>
						<?php echo esc_html( $this->get_invoice_status_label( $invoice_status ) ); ?>
					</p>
				<?php endif; ?>

				<?php
				$has_total_mismatch = $order->get_meta( '_sellsy_invoice_total_mismatch' ) === 'yes';
				if ( $has_total_mismatch ) :
					$mismatch_order_total    = (float) $order->get_meta( '_sellsy_invoice_order_total' );
					$mismatch_invoice_total  = (float) $order->get_meta( '_sellsy_invoice_sellsy_total' );
					$mismatch_difference     = (float) $order->get_meta( '_sellsy_invoice_total_difference' );
					?>
					<div class="devikit-sellsy-total-mismatch">
						<p class="devikit-sellsy-total-mismatch__title">
							<?php esc_html_e( 'Total Mismatch Detected', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?>
						</p>
						<p class="devikit-sellsy-total-mismatch__amounts">
							<?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-sellsy-and-woocommerce' ),
								esc_html( number_format_i18n( $mismatch_order_total, 2 ) ),
								esc_html( number_format_i18n( $mismatch_invoice_total, 2 ) ),
								esc_html( number_format_i18n( $mismatch_difference, 2 ) )
							);
							?>
						</p>
						<p class="devikit-sellsy-total-mismatch__hint">
							<?php esc_html_e( 'Totals differ between WooCommerce and sellsy. Review the invoice in sellsy before sending it to the customer.', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?>
						</p>
					</div>
				<?php endif; ?>

				<p class="devikit-sellsy-metabox-actions">
					<a class="button" target="_blank" rel="noopener noreferrer" href="<?php echo esc_url( \Devikit\Sellsy\Api\Client::get_app_document_url( $invoice_id, 'invoice' ) ); ?>"><?php esc_html_e( 'Open in Sellsy', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?></a>
					<button type="button" class="button" id="devikit-sellsy-download-pdf" data-invoice-id="<?php echo esc_attr( $invoice_id ); ?>" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
						<?php esc_html_e( 'Download PDF', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?>
					</button>
				</p>

				<?php if ( ! $pro_installed ) : ?>
					<div class="devikit-sellsy-pro-teaser">
						<p class="devikit-sellsy-metabox-actions">
							<button type="button" class="button" disabled>
								<?php esc_html_e( 'Send Invoice by Email', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?> &#128274;
							</button>
						</p>
						<small style="color:#666;margin-top:5px;display:block;">
							<?php
							printf(
								/* translators: %s: PRO version link */
								esc_html__( 'Customer email delivery is included in %s', 'invoicing-integration-for-sellsy-and-woocommerce' ),
								'<a href="' . esc_url( $pro_url ) . '" target="_blank" rel="noopener noreferrer" style="color:#2271b1;">' . esc_html__( 'PRO version', 'invoicing-integration-for-sellsy-and-woocommerce' ) . '</a>'
							);
							?>
						</small>
					</div>
				<?php endif; ?>
			<?php else : ?>
				<?php if ( $last_error ) : ?>
					<div class="devikit-sellsy-error-notice">
						<strong><?php esc_html_e( 'Last error:', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?></strong><br>
						<?php echo esc_html( $last_error ); ?>
					</div>
				<?php endif; ?>

				<p><?php esc_html_e( 'No sellsy invoice has been created for this order yet.', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?></p>

				<p class="devikit-sellsy-metabox-actions">
					<button type="button" class="button button-primary" id="devikit-sellsy-create-invoice" data-order-id="<?php echo esc_attr( $order->get_id() ); ?>">
						<?php esc_html_e( 'Create Invoice', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?>
					</button>
				</p>
				<span id="devikit-sellsy-loading" class="devikit-sellsy-loading"><?php esc_html_e( 'Creating invoice...', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?></span>
				<p id="devikit-sellsy-error" class="devikit-sellsy-inline-error"></p>
			<?php endif; ?>

			<?php
			/**
			 * PRO hooks (send email, credit note) render here when PRO is active.
			 *
			 * @param \WC_Order $order Order object.
			 */
			do_action( 'devikit_sellsy_metabox_after_invoice', $order );
			?>

			<?php if ( ! $pro_installed ) : ?>
				<div class="devikit-sellsy-pro-teaser">
					<h4><?php esc_html_e( 'Credit Note', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?></h4>
					<p class="devikit-sellsy-metabox-actions">
						<button type="button" class="button" disabled>
							<?php esc_html_e( 'Create Credit Note', 'invoicing-integration-for-sellsy-and-woocommerce' ); ?> &#128274;
						</button>
					</p>
					<small style="color:#666;margin-top:5px;display:block;">
						<?php
						printf(
							/* translators: %s: PRO version link */
							esc_html__( 'Credit notes are available in %s', 'invoicing-integration-for-sellsy-and-woocommerce' ),
							'<a href="' . esc_url( $pro_url ) . '" target="_blank" rel="noopener noreferrer" style="color:#2271b1;">' . esc_html__( 'PRO version', 'invoicing-integration-for-sellsy-and-woocommerce' ) . '</a>'
						);
						?>
					</small>
				</div>
			<?php endif; ?>
		</div>
		<?php
	}

	public function ajax_create_invoice() {
		check_ajax_referer( 'sellsy_create_invoice', 'nonce' );

		$order_id = isset( $_POST['order_id'] ) ? absint( $_POST['order_id'] ) : 0;
		if ( ! $this->user_can_manage_order( $order_id ) ) {
			wp_send_json_error( [ 'message' => __( 'Unauthorized.', 'invoicing-integration-for-sellsy-and-woocommerce' ) ] );
		}

		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			wp_send_json_error( [ 'message' => __( 'Order not found.', 'invoicing-integration-for-sellsy-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( [ 'invoice_id' => $result ] );
	}

	public function ajax_download_pdf() {
		check_ajax_referer( 'sellsy_download_pdf', 'nonce' );

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

		if ( ! $this->user_can_manage_order( $order_id ) ) {
			wp_send_json_error( [ 'message' => __( 'Unauthorized.', 'invoicing-integration-for-sellsy-and-woocommerce' ) ] );
		}

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

		$order = wc_get_order( $order_id );
		if ( ! $order || (string) $order->get_meta( '_sellsy_invoice_id' ) !== (string) $invoice_id ) {
			wp_send_json_error( [ 'message' => __( 'Invoice does not belong to this order.', 'invoicing-integration-for-sellsy-and-woocommerce' ) ] );
		}

		$pdf = $this->fetch_invoice_pdf( $invoice_id, $order_id );
		if ( is_wp_error( $pdf ) ) {
			wp_send_json_error( [ 'message' => $pdf->get_error_message() ] );
		}

		wp_send_json_success(
			[
				'pdf'      => base64_encode( $pdf ),
				'filename' => $this->build_invoice_pdf_filename( $order, $invoice_id ),
			]
		);
	}

	/**
	 * @param int $order_id
	 * @return bool
	 */
	private function user_can_manage_order( $order_id ) {
		$order_id = absint( $order_id );
		if ( ! $order_id ) {
			return false;
		}

		return current_user_can( 'manage_woocommerce' )
			|| current_user_can( 'edit_shop_orders' )
			|| current_user_can( 'edit_shop_order', $order_id );
	}

	/**
	 * @param \WC_Order $order
	 * @param string    $invoice_id
	 * @return string
	 */
	private function build_invoice_pdf_filename( $order, $invoice_id ) {
		$number = $order instanceof \WC_Order ? (string) $order->get_meta( '_sellsy_invoice_number' ) : '';
		if ( $number !== '' ) {
			return sanitize_file_name( $number ) . '.pdf';
		}

		return 'invoice-' . sanitize_file_name( (string) $invoice_id ) . '.pdf';
	}

	/**
	 * @param \WC_Order $order
	 * @return string|\WP_Error Invoice id on success.
	 */
	public function create_invoice_for_order( $order ) {
		$existing = $order->get_meta( '_sellsy_invoice_id' );
		if ( ! empty( $existing ) ) {
			return new \WP_Error(
				'sellsy_invoice_exists',
				__( 'A Sellsy invoice already exists for this order.', 'invoicing-integration-for-sellsy-and-woocommerce' )
			);
		}

		$validated = $this->document_builder->validate_billing_address( $order );
		if ( is_wp_error( $validated ) ) {
			$this->store_error( $order, $validated );
			return $validated;
		}

		$related = $this->customer_sync->get_or_create_customer( $order );
		if ( is_wp_error( $related ) ) {
			$this->store_error( $order, $related );
			return $related;
		}

		$payload = $this->document_builder->build_invoice_payload( $order, $related );
		if ( is_wp_error( $payload ) ) {
			$this->store_error( $order, $payload );
			return $payload;
		}

		$response = $this->api_client->create_document( $payload );
		if ( is_wp_error( $response ) ) {
			$this->store_error( $order, $response );
			return $response;
		}

		$invoice_id = isset( $response['id'] ) ? (string) (int) $response['id'] : '';
		if ( $invoice_id === '' || $invoice_id === '0' ) {
			$error = new \WP_Error(
				'sellsy_invoice_unknown_response',
				__( 'Unexpected response from sellsy API.', 'invoicing-integration-for-sellsy-and-woocommerce' )
			);
			$this->store_error( $order, $error );
			return $error;
		}

		$details = $response;

		if ( $this->settings->get_option( 'finalize_mode', 'draft' ) === 'finalized' ) {
			$done = $this->api_client->complete_document( $invoice_id );
			if ( is_wp_error( $done ) ) {
				$this->store_error( $order, $done );
				return $done;
			}
			if ( is_array( $done ) ) {
				$details = $done;
			}
		}

		$fresh = $this->api_client->get_document( $invoice_id );
		if ( ! is_wp_error( $fresh ) && is_array( $fresh ) ) {
			$details = $fresh;
		}

		$order->update_meta_data( '_sellsy_invoice_id', $invoice_id );
		$order->delete_meta_data( '_sellsy_last_error' );

		if ( is_array( $details ) ) {
			if ( ! empty( $details['number'] ) ) {
				$order->update_meta_data( '_sellsy_invoice_number', sanitize_text_field( (string) $details['number'] ) );
			}
			$status = $this->resolve_document_status( $details );
			$order->update_meta_data( '_sellsy_invoice_status', $status );
			$this->store_total_mismatch_meta( $order, $details );
		} else {
			$this->clear_total_mismatch_meta( $order );
			$details = [];
		}

		$order->save();

		$has_mismatch = $order->get_meta( '_sellsy_invoice_total_mismatch' ) === 'yes';
		if ( $has_mismatch ) {
			$order->add_order_note(
				sprintf(
					/* translators: 1: sellsy invoice number, 2: order total, 3: invoice total */
					__( 'Sellsy invoice created: %1$s (Total mismatch: Order %2$s vs Invoice %3$s)', 'invoicing-integration-for-sellsy-and-woocommerce' ),
					$order->get_meta( '_sellsy_invoice_number' ) ?: $invoice_id,
					wc_format_decimal( (float) $order->get_meta( '_sellsy_invoice_order_total' ), 2 ),
					wc_format_decimal( (float) $order->get_meta( '_sellsy_invoice_sellsy_total' ), 2 )
				)
			);
		} else {
			$order->add_order_note(
				sprintf(
					/* translators: %s: sellsy invoice number or id */
					__( 'Sellsy invoice created: %s', 'invoicing-integration-for-sellsy-and-woocommerce' ),
					$order->get_meta( '_sellsy_invoice_number' ) ?: $invoice_id
				)
			);
		}

		do_action( 'devikit_sellsy_invoice_generated', $order, $invoice_id, $details );

		return (string) $invoice_id;
	}

	/**
	 * @param array $details
	 * @return string draft|finalized|paid
	 */
	private function resolve_document_status( array $details ) {
		$status = isset( $details['status'] ) ? strtolower( (string) $details['status'] ) : '';
		if ( in_array( $status, [ 'paid', 'cancelledpaid' ], true ) ) {
			return 'paid';
		}
		if ( $status === '' || $status === 'draft' ) {
			return 'draft';
		}
		// due / partial / late / stored etc. after validate.
		return 'finalized';
	}

	/**
	 * @param \WC_Order $order
	 * @param array     $details
	 */
	private function store_total_mismatch_meta( $order, array $details ) {
		$invoice_total      = $this->resolve_invoice_document_gross( $details );
		$order_total        = (float) $order->get_total();
		$total_difference   = abs( $invoice_total - $order_total );
		$has_total_mismatch = $total_difference >= 0.02; // 2 cents tolerance.

		if ( $has_total_mismatch ) {
			$order->update_meta_data( '_sellsy_invoice_total_mismatch', 'yes' );
			$order->update_meta_data( '_sellsy_invoice_order_total', $order_total );
			$order->update_meta_data( '_sellsy_invoice_sellsy_total', $invoice_total );
			$order->update_meta_data( '_sellsy_invoice_total_difference', $total_difference );
		} else {
			$this->clear_total_mismatch_meta( $order );
		}
	}

	/**
	 * Sellsy returns amounts.total_incl_tax as a decimal string.
	 *
	 * @param array $details
	 * @return float
	 */
	private function resolve_invoice_document_gross( array $details ) {
		if ( isset( $details['amounts']['total_incl_tax'] ) ) {
			return (float) $details['amounts']['total_incl_tax'];
		}
		if ( isset( $details['amounts']['total_remaining_due_incl_tax'] ) ) {
			return (float) $details['amounts']['total_remaining_due_incl_tax'];
		}
		return 0.0;
	}

	/**
	 * @param \WC_Order $order
	 */
	private function clear_total_mismatch_meta( $order ) {
		$order->delete_meta_data( '_sellsy_invoice_total_mismatch' );
		$order->delete_meta_data( '_sellsy_invoice_order_total' );
		$order->delete_meta_data( '_sellsy_invoice_sellsy_total' );
		$order->delete_meta_data( '_sellsy_invoice_total_difference' );
	}

	/**
	 * @param string|int $status
	 * @return string
	 */
	private function get_invoice_status_label( $status ) {
		$labels = [
			'draft'     => __( 'Draft', 'invoicing-integration-for-sellsy-and-woocommerce' ),
			'finalized' => __( 'Completed', 'invoicing-integration-for-sellsy-and-woocommerce' ),
			'paid'      => __( 'Paid', 'invoicing-integration-for-sellsy-and-woocommerce' ),
		];

		$key = strtolower( trim( (string) $status ) );
		return isset( $labels[ $key ] ) ? $labels[ $key ] : (string) $status;
	}

	/**
	 * @param \WC_Order $order
	 */
	public function display_invoice_download_button( $order ) {
		if ( ! $order instanceof \WC_Order ) {
			$order = wc_get_order( $order );
		}
		if ( ! $order || ! is_user_logged_in() ) {
			return;
		}

		$invoice_id = $order->get_meta( '_sellsy_invoice_id' );
		if ( empty( $invoice_id ) ) {
			return;
		}

		$download_url = add_query_arg(
			[
				'devikit_sellsy_download' => 1,
				'order_id'                 => $order->get_id(),
				'nonce'                    => wp_create_nonce( 'sellsy_customer_download_' . $order->get_id() ),
			],
			wc_get_endpoint_url( 'view-order', $order->get_id(), wc_get_page_permalink( 'myaccount' ) )
		);

		echo '<p class="devikit-sellsy-myaccount-download">';
		echo '<a class="button" href="' . esc_url( $download_url ) . '">';
		esc_html_e( 'Download Invoice', 'invoicing-integration-for-sellsy-and-woocommerce' );
		echo '</a></p>';
	}

	public function handle_invoice_download() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce verified below.
		if ( empty( $_GET['devikit_sellsy_download'] ) ) {
			return;
		}

		if ( ! is_user_logged_in() ) {
			wp_die( esc_html__( 'You are not allowed to download this invoice.', 'invoicing-integration-for-sellsy-and-woocommerce' ) );
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce verified below.
		$order_id = isset( $_GET['order_id'] ) ? absint( $_GET['order_id'] ) : 0;
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce verified below.
		$nonce    = isset( $_GET['nonce'] ) ? sanitize_text_field( wp_unslash( $_GET['nonce'] ) ) : '';

		if ( ! $order_id || ! wp_verify_nonce( $nonce, 'sellsy_customer_download_' . $order_id ) ) {
			wp_die( esc_html__( 'Invalid download request.', 'invoicing-integration-for-sellsy-and-woocommerce' ) );
		}

		$order = wc_get_order( $order_id );
		if ( ! $order || (int) $order->get_customer_id() !== get_current_user_id() ) {
			wp_die( esc_html__( 'You are not allowed to download this invoice.', 'invoicing-integration-for-sellsy-and-woocommerce' ) );
		}

		$invoice_id = $order->get_meta( '_sellsy_invoice_id' );
		if ( empty( $invoice_id ) ) {
			wp_die( esc_html__( 'Invoice not found.', 'invoicing-integration-for-sellsy-and-woocommerce' ) );
		}

		$pdf = $this->fetch_invoice_pdf( $invoice_id, $order_id );
		if ( is_wp_error( $pdf ) ) {
			wp_die( esc_html( $pdf->get_error_message() ) );
		}

		$filename = $this->build_invoice_pdf_filename( $order, $invoice_id );
		header( 'Content-Type: application/pdf' );
		header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
		header( 'Content-Length: ' . strlen( $pdf ) );
		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo $pdf;
		exit;
	}

	/**
	 * @param string $invoice_id
	 * @param int    $order_id
	 * @return string|\WP_Error
	 */
	public function fetch_invoice_pdf( $invoice_id, $order_id = 0 ) {
		unset( $order_id );
		return $this->api_client->get_document_pdf( $invoice_id );
	}

	/**
	 * @param \WC_Order $order
	 * @param \WP_Error $error
	 */
	private function store_error( $order, $error ) {
		$message = Client::humanize_business_error( $error->get_error_message() );
		$order->update_meta_data( '_sellsy_last_error', $message );
		$order->save();
		$order->add_order_note( __( 'Sellsy invoice error: ', 'invoicing-integration-for-sellsy-and-woocommerce' ) . $message );
	}
}
