<?php
/**
 * Order edit screen integration for invoice download.
 *
 * @package PDFDraft_WooCommerce
 */

namespace PDFDraft\Woocommerce\Admin;

use PDFDraft\Woocommerce\Abstracts\AbstractIntegration;
use PDFDraft\Woocommerce\Core\Assets;

/**
 * Adds an invoice download meta box to the WooCommerce order edit screen.
 */
class OrderEdit extends AbstractIntegration {

	/**
	 * Assets service instance.
	 *
	 * @var Assets
	 */
	private Assets $assets;

	/**
	 * Initialize the OrderEdit integration.
	 *
	 * @param Assets $assets Assets service.
	 */
	public function __construct( Assets $assets ) {
		$this->assets = $assets;
	}

	/**
	 * Register WordPress hooks for the order edit screen.
	 *
	 * @return void
	 */
	public function initHooks() {
		if ( ! $this->hasActiveDesign() ) {
			return;
		}
		$this->addAction( 'add_meta_boxes', array( $this, 'addMetaBox' ) );
		$this->addAction( 'edit_post_shop_order', array( $this, 'enqueueScriptStyle' ) );
		$screen_id = $this->getOrderScreen();
		if ( $screen_id ) {
			$this->addAction( 'load-' . $screen_id, array( $this, 'enqueueScriptStyle' ) );
		}
		// Reliable: load-* is not fired for legacy shop_order CPT screens; edit_post_* runs on save, not on load.
		$this->addAction( 'admin_enqueue_scripts', array( $this, 'enqueueScriptStyleOnOrderEditScreen' ) );
	}

	/**
	 * Register the invoice download meta box.
	 *
	 * @return void
	 */
	public function addMetaBox() {
		$screen = $this->getOrderScreen();

		add_meta_box(
			'pdfdraft-invoice-download-button',
			__( 'Invoice Download', 'pdfdraft-pdf-invoices-for-woocommerce' ),
			array( $this, 'renderMetaBoxContent' ),
			$screen,
			'side',
			'high'
		);
	}

	/**
	 * Render the invoice download button inside the meta box.
	 *
	 * @param \WP_Post|\WC_Order|object $post_or_order The post or order object.
	 * @param array                     $box           Meta box arguments.
	 * @return void
	 */
	public function renderMetaBoxContent( $post_or_order, $box = array() ) {
		$order = $this->getOrderFromMetaBox( $post_or_order );
		if ( ! $order instanceof \WC_Order ) {
			return;
		}
		$order_id     = $order->get_id();
		$download_url = rest_url( 'pdfdraft-pdf-invoices-for-woocommerce/v1/orders/' . $order_id . '/invoice' );
		$download_url = apply_filters( 'pdfdraft_pdf_invoices_for_woocommerce_invoice_download_url', $download_url, $order_id );
		$args         = array(
			'order_id'            => $order_id,
			'context'             => 'order-edit',
			'type'                => 'both',
			'text'                => __( 'Download Invoice', 'pdfdraft-pdf-invoices-for-woocommerce' ),
			'size'                => 'medium',
			'download_url'        => $download_url,
			'show_delete_invoice' => (bool) apply_filters( 'pdfdraft_pdf_invoices_for_woocommerce_invoice_show_delete_button', true, $order ),
			'delete_url'          => esc_url( rest_url( 'pdfdraft-pdf-invoices-for-woocommerce/v1/orders/' . $order_id . '/invoice' ) ),
		);
		$args         = apply_filters( 'pdfdraft_pdf_invoices_for_woocommerce_invoice_download_button_args', $args, $order );
		$this->renderTemplate( 'invoice-download-button.php', $args );
	}

	/**
	 * Get WC_Order from the meta box callback first argument (post or order object).
	 *
	 * @param \WP_Post|\WC_Order|object $post_or_order Meta box first argument.
	 * @return \WC_Order|null
	 */
	private function getOrderFromMetaBox( $post_or_order ) {
		if ( $post_or_order instanceof \WC_Order ) {
			return $post_or_order;
		}
		if ( is_object( $post_or_order ) && isset( $post_or_order->ID ) ) {
			return \wc_get_order( (int) $post_or_order->ID );
		}
		return null;
	}

	/**
	 * Get the admin screen id for the order edit screen (HPOS or legacy).
	 *
	 * @return string Screen id for add_meta_box / load- hook.
	 */
	private function getOrderScreen() {
		if ( ! class_exists( \Automattic\WooCommerce\Utilities\OrderUtil::class ) ) {
			return 'shop_order';
		}
		return \Automattic\WooCommerce\Utilities\OrderUtil::get_order_admin_screen();
	}

	/**
	 * Enqueue invoice download scripts and styles.
	 *
	 * @return void
	 */
	public function enqueueScriptStyle() {
		$this->assets->enqueueInvoiceDownloadScriptStyle();
	}

	/**
	 * Enqueue on admin_enqueue_scripts so invoice CSS always prints with other admin assets.
	 *
	 * @return void
	 */
	public function enqueueScriptStyleOnOrderEditScreen(): void {
		if ( ! $this->isOrderEditAdminScreen() ) {
			return;
		}
		$this->assets->enqueueInvoiceDownloadScriptStyle();
	}

	/**
	 * Whether we are on the order edit UI (HPOS or legacy CPT).
	 *
	 * @return bool
	 */
	private function isOrderEditAdminScreen(): bool {
		if ( ! function_exists( 'get_current_screen' ) ) {
			return false;
		}
		$screen = get_current_screen();
		if ( ! $screen ) {
			return false;
		}
		// HPOS: single order edit.
		if ( 'woocommerce_page_wc-orders' === $screen->id ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- screen detection only.
			return isset( $_GET['action'], $_GET['id'] ) && 'edit' === $_GET['action'] && (int) $_GET['id'] > 0;
		}
		// Legacy: orders stored as shop_order posts.
		if ( 'shop_order' === $screen->post_type && 'post' === $screen->base ) {
			return true;
		}
		return false;
	}

	/**
	 * Check whether an active WooCommerce invoice design is configured.
	 *
	 * @return bool True if an active design slug is set.
	 */
	private function hasActiveDesign(): bool {
		$slug = get_option( 'pdfdraft_pdf_invoices_for_woocommerce_active_design_slug', '' );
		return is_string( $slug ) && '' !== $slug;
	}
}
