<?php
/**
 * Class Noesia Cs Public.
 *
 * @package Noesia_Commerce_Suite
 */

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

/**
 * Class implementation.
 */
class Noesia_CS_Public {
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $passport_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $warranty_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $impact_map_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $email_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $reorder_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $care_action_service;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $checkout_reorder_request_rendered = false;
	/**
	 * Runtime dependency or state value.
	 *
	 * @var mixed
	 */
	private $customer_qr_blocks_rendered = array();

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $passport_service Passport service.
	 * @param mixed $warranty_service Warranty service.
	 * @param mixed $impact_map_service Impact map service.
	 * @param mixed $email_service Email service.
	 * @param mixed $reorder_service Reorder service.
	 * @param mixed $care_action_service Care action service.
	 */
	public function __construct( Noesia_CS_Passport_Service $passport_service, Noesia_CS_Warranty_Service $warranty_service, Noesia_CS_Impact_Map_Service $impact_map_service, Noesia_CS_Email_Service $email_service, Noesia_CS_Reorder_Service $reorder_service, Noesia_CS_Care_Action_Service $care_action_service ) {
		$this->passport_service   = $passport_service;
		$this->warranty_service   = $warranty_service;
		$this->impact_map_service = $impact_map_service;
		$this->email_service      = $email_service;
		$this->reorder_service    = $reorder_service;
		$this->care_action_service = $care_action_service;
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function hooks() {
		add_action( 'wp_enqueue_scripts', array( $this, 'register_assets' ) );
		add_action( 'template_redirect', array( $this, 'maybe_render_reorder_opt_out' ), 8 );
		add_action( 'template_redirect', array( $this, 'maybe_handle_care_action' ), 9 );
		add_action( 'template_redirect', array( $this, 'maybe_render_care_page' ) );
		add_shortcode( 'noesia_impact_map', array( $this, 'impact_map_shortcode' ) );
		add_shortcode( 'noesia_cs_impact_map', array( $this, 'impact_map_shortcode' ) );
		add_shortcode( 'noesia_cs_reorder_reminder_request', array( $this, 'reorder_reminder_request_shortcode' ) );

		if ( class_exists( 'WooCommerce' ) ) {
			add_action( 'woocommerce_thankyou', array( $this, 'thankyou_qr_block' ), 30 );
			add_action( 'woocommerce_order_details_after_order_table', array( $this, 'my_account_qr_block' ), 30 );
			add_action( 'woocommerce_email_after_order_table', array( $this, 'email_order_care_block' ), 20, 4 );
			add_action( 'woocommerce_after_order_notes', array( $this, 'checkout_reorder_request_field' ), 20 );
			add_action( 'woocommerce_checkout_process', array( $this, 'validate_checkout_reorder_request' ) );
			add_action( 'woocommerce_checkout_create_order', array( $this, 'save_checkout_reorder_request_meta' ), 20, 2 );
			add_action( 'woocommerce_store_api_checkout_update_order_from_request', array( $this, 'save_store_api_checkout_reorder_request_meta' ), 20, 2 );
			add_action( 'woocommerce_checkout_order_created', array( $this, 'queue_checkout_reorder_request_from_created_order' ), 30, 1 );
			add_action( 'woocommerce_checkout_order_processed', array( $this, 'queue_checkout_reorder_request' ), 30, 3 );
			add_action( 'woocommerce_thankyou', array( $this, 'queue_checkout_reorder_request' ), 35, 1 );
			add_action( 'woocommerce_order_status_processing', array( $this, 'queue_checkout_reorder_request' ), 35, 1 );
			add_action( 'woocommerce_order_status_completed', array( $this, 'queue_checkout_reorder_request' ), 35, 1 );
		}
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function register_assets() {
		$this->register_public_assets();
	}


	/**
	 * Handles the related plugin operation.
	 */
	private function checkout_reorder_request_enabled() {
		return 'yes' === Noesia_CS_Settings::get( 'reorder_checkout_request_enabled', 'no' ) && 'yes' === Noesia_CS_Settings::get( 'reorder_reminders_enabled', 'no' );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $key Key.
	 */
	private function checkout_post_value( $key ) {
		if ( ! is_string( $key ) || '' === $key ) {
			return '';
		}

		$key          = sanitize_key( $key );
		$allowed_keys = array( 'noesia_cs_reorder_request', 'noesia_cs_reorder_date' );

		if ( ! in_array( $key, $allowed_keys, true ) ) {
			return '';
		}

		// WooCommerce validates the checkout nonce before order processing. This helper reads
		// the plugin's optional checkout fields during WooCommerce checkout hooks. The cookie
		// fallback covers page builders or checkout layouts where the visible field is rendered
		// outside the real WooCommerce checkout form. Values are still validated before saving.
		// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Checkout nonce is handled by WooCommerce before order processing.
		if ( isset( $_POST[ $key ] ) && ! is_array( $_POST[ $key ] ) ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Missing -- Checkout nonce is handled by WooCommerce before order processing.
			return sanitize_text_field( wp_unslash( $_POST[ $key ] ) );
		}

		$cookie_key = 'noesia_cs_reorder_request' === $key ? 'noesia_cs_reorder_request' : 'noesia_cs_reorder_date';
		if ( isset( $_COOKIE[ $cookie_key ] ) && ! is_array( $_COOKIE[ $cookie_key ] ) ) {
			return sanitize_text_field( wp_unslash( $_COOKIE[ $cookie_key ] ) );
		}

		return '';
	}

	/**
	 * Handles the related plugin operation.
	 */
	private function get_min_checkout_reminder_date() {
		$timezone  = function_exists( 'wp_timezone' ) ? wp_timezone() : new DateTimeZone( 'UTC' );
		$date      = new DateTimeImmutable( 'tomorrow', $timezone );
		return $date->format( 'Y-m-d' );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $date Date.
	 */
	private function parse_checkout_reminder_date( $date ) {
		$date = is_scalar( $date ) ? sanitize_text_field( wp_unslash( $date ) ) : '';
		if ( ! preg_match( '/^\d{4}-\d{2}-\d{2}$/', $date ) ) {
			return false;
		}

		$timezone = function_exists( 'wp_timezone' ) ? wp_timezone() : new DateTimeZone( 'UTC' );
		try {
			$selected  = new DateTimeImmutable( $date . ' 09:00:00', $timezone );
			$minimum   = new DateTimeImmutable( $this->get_min_checkout_reminder_date() . ' 00:00:00', $timezone );
		} catch ( Exception $exception ) {
			return false;
		}

		if ( $selected < $minimum ) {
			return false;
		}

		return $selected;
	}

	/**
	 * Returns the validated checkout reminder date selected by the customer.
	 *
	 * @return DateTimeImmutable|false
	 */
	private function get_checkout_reorder_request_due() {
		$requested = 'yes' === $this->checkout_post_value( 'noesia_cs_reorder_request' );
		if ( ! $requested ) {
			return false;
		}

		return $this->parse_checkout_reminder_date( $this->checkout_post_value( 'noesia_cs_reorder_date' ) );
	}

	/**
	 * Stores the validated checkout reminder request on the WooCommerce order.
	 *
	 * @param WC_Order          $order WooCommerce order.
	 * @param DateTimeImmutable $due Reminder due date.
	 */
	private function persist_checkout_reorder_request_meta( $order, $due ) {
		if ( ! $order || ! is_a( $order, 'WC_Order' ) || ! $due ) {
			return;
		}

		$order->update_meta_data( '_noesia_cs_reorder_requested', 'yes' );
		$order->update_meta_data( '_noesia_cs_reorder_requested_date', $due->format( 'Y-m-d' ) );
		$order->update_meta_data( '_noesia_cs_reorder_requested_due_at', $due->getTimestamp() );
		$order->update_meta_data( '_noesia_cs_reorder_requested_at', time() );
	}

	/**
	 * Handles the related plugin operation.
	 */
	private function get_checkout_reorder_request_markup() {
		if ( ! $this->checkout_reorder_request_enabled() || $this->checkout_reorder_request_rendered ) {
			return '';
		}

		$this->checkout_reorder_request_rendered = true;

		$settings = Noesia_CS_Settings::get_all();
		$this->register_public_assets();
		wp_enqueue_style( 'noesia-cs-public' );
		wp_enqueue_script( 'noesia-cs-public' );

		$badge_label        = ! empty( $settings['reorder_checkout_badge_label'] ) ? $settings['reorder_checkout_badge_label'] : __( 'Reorder Reminder', 'noesia-commerce-suite' );
		$checkbox_label     = ! empty( $settings['reorder_checkout_label'] ) ? $settings['reorder_checkout_label'] : __( 'Remind me to reorder later', 'noesia-commerce-suite' );
		$checkout_style     = sanitize_key( $settings['reorder_checkout_style'] ?? 'clean' );
		$checkout_style     = in_array( $checkout_style, array( 'clean', 'dark', 'glamour' ), true ) ? $checkout_style : 'clean';
		$default_info_text  = __( 'Choose this if you want to receive a scheduled reorder reminder email on the date you select.', 'noesia-commerce-suite' );
		$legacy_info_text   = __( 'Choose this only if you want a scheduled reminder for replacement, refill or repeat purchase.', 'noesia-commerce-suite' );
		$info_text          = ! empty( $settings['reorder_checkout_info_text'] ) ? $settings['reorder_checkout_info_text'] : $default_info_text;
		if ( $legacy_info_text === $info_text ) {
			$info_text = $default_info_text;
		}
		$date_label  = ! empty( $settings['reorder_checkout_date_label'] ) ? $settings['reorder_checkout_date_label'] : __( 'Reminder date', 'noesia-commerce-suite' );
		$min_date    = $this->get_min_checkout_reminder_date();
		$requested  = 'yes' === $this->checkout_post_value( 'noesia_cs_reorder_request' );
		$date_value = $this->checkout_post_value( 'noesia_cs_reorder_date' );

		ob_start();
		?>
		<div class="noesia-cs-checkout-reorder-request noesia-cs-checkout-reorder-request--<?php echo esc_attr( $checkout_style ); ?>" data-noesia-cs-checkout-reorder data-noesia-cs-badge-label="<?php echo esc_attr( $badge_label ); ?>">
			<label class="noesia-cs-checkout-reorder-request__checkbox">
				<input type="checkbox" name="noesia_cs_reorder_request" value="yes" <?php checked( $requested ); ?> data-noesia-cs-checkout-reorder-toggle>
				<span><?php echo esc_html( $checkbox_label ); ?></span>
			</label>
			<?php if ( $info_text ) : ?>
				<p><?php echo esc_html( $info_text ); ?></p>
			<?php endif; ?>
			<div class="noesia-cs-checkout-reorder-request__date" data-noesia-cs-checkout-reorder-date <?php echo $requested ? '' : 'hidden'; ?>>
				<label for="noesia-cs-reorder-date"><?php echo esc_html( $date_label ); ?></label>
				<input id="noesia-cs-reorder-date" type="date" name="noesia_cs_reorder_date" value="<?php echo esc_attr( $date_value ); ?>" min="<?php echo esc_attr( $min_date ); ?>">
			</div>
		</div>
		<?php
		return ob_get_clean();
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $checkout Checkout.
	 */
	public function checkout_reorder_request_field( $checkout ) {
		echo $this->get_checkout_reorder_request_markup(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Markup is escaped inside get_checkout_reorder_request_markup().
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function reorder_reminder_request_shortcode() {
		if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) {
			return '';
		}

		return $this->get_checkout_reorder_request_markup();
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function validate_checkout_reorder_request() {
		if ( ! $this->checkout_reorder_request_enabled() ) {
			return;
		}

		if ( 'yes' !== $this->checkout_post_value( 'noesia_cs_reorder_request' ) ) {
			return;
		}

		if ( ! $this->get_checkout_reorder_request_due() ) {
			wc_add_notice( __( 'Please choose a valid future reorder reminder date.', 'noesia-commerce-suite' ), 'error' );
		}
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 * @param mixed $data Data.
	 */
	public function save_checkout_reorder_request_meta( $order, $data ) {
		if ( ! $this->checkout_reorder_request_enabled() || ! $order || ! is_a( $order, 'WC_Order' ) ) {
			return;
		}

		$due = $this->get_checkout_reorder_request_due();
		if ( ! $due ) {
			return;
		}

		$this->persist_checkout_reorder_request_meta( $order, $due );
	}

	/**
	 * Stores checkout reminder meta for WooCommerce Checkout Block / Store API orders.
	 *
	 * @param WC_Order $order WooCommerce order.
	 * @param mixed    $request Store API request.
	 */
	public function save_store_api_checkout_reorder_request_meta( $order, $request = null ) {
		$this->save_checkout_reorder_request_meta( $order, array() );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order_id Order id.
	 * @param mixed $posted_data Posted data.
	 * @param mixed $order Order.
	 */
	public function queue_checkout_reorder_request( $order_id, $posted_data = array(), $order = null ) {
		if ( ! $order && function_exists( 'wc_get_order' ) ) {
			$order = wc_get_order( absint( $order_id ) );
		}

		if ( ! $this->checkout_reorder_request_enabled() || ! $order || ! is_a( $order, 'WC_Order' ) ) {
			return;
		}

		$due_at = absint( $order->get_meta( '_noesia_cs_reorder_requested_due_at', true ) );

		if ( ! $due_at ) {
			$due = $this->get_checkout_reorder_request_due();
			if ( $due ) {
				$due_at = $due->getTimestamp();
				$this->persist_checkout_reorder_request_meta( $order, $due );
				$order->save();
			}
		}

		if ( ! $due_at ) {
			return;
		}

		if ( $this->reorder_service && method_exists( $this->reorder_service, 'queue_customer_requested_reminder' ) ) {
			$this->reorder_service->queue_customer_requested_reminder( $order, $due_at );
		}
	}

	/**
	 * Queue checkout reminder after WooCommerce has created the order object.
	 *
	 * @param WC_Order $order WooCommerce order.
	 */
	public function queue_checkout_reorder_request_from_created_order( $order ) {
		if ( ! $order || ! is_a( $order, 'WC_Order' ) ) {
			return;
		}

		$this->queue_checkout_reorder_request( $order->get_id(), array(), $order );
	}

	/**
	 * Handles the related plugin operation.
	 */
	private function register_public_assets() {
		if ( ! wp_script_is( 'noesia-cs-qrcode', 'registered' ) ) {
			wp_register_script( 'noesia-cs-qrcode', NOESIA_CS_URL . 'assets/libs/qrcode/noesia-cs-qrcode.js', array(), NOESIA_CS_VERSION, true );
		}
		if ( ! wp_script_is( 'noesia-cs-public', 'registered' ) ) {
			$public_js_file    = NOESIA_CS_PATH . 'assets/js/noesia-cs-public.js';
			$public_js_version = file_exists( $public_js_file ) ? (string) filemtime( $public_js_file ) : NOESIA_CS_VERSION;
			wp_register_script( 'noesia-cs-public', NOESIA_CS_URL . 'assets/js/noesia-cs-public.js', array( 'noesia-cs-qrcode' ), $public_js_version, true );
			wp_localize_script(
				'noesia-cs-public',
				'noesiaCommerceSuitePublic',
				array(
					'qr'         => array(
						'size'        => max( 80, min( 420, absint( Noesia_CS_Settings::get( 'qr_size', 160 ) ) ) ),
						'foreground'  => Noesia_CS_Settings::get( 'qr_foreground_color', '#111827' ),
						'background'  => Noesia_CS_Settings::get( 'qr_background_color', '#ffffff' ),
					),
				)
			);
		}
		if ( ! wp_style_is( 'noesia-cs-public', 'registered' ) ) {
			wp_register_style( 'noesia-cs-public', NOESIA_CS_URL . 'assets/css/noesia-cs-public.css', array(), NOESIA_CS_VERSION );
		}
	}


	/**
	 * Handles the related plugin operation.
	 */
	public function maybe_handle_care_action() {
		$token   = sanitize_text_field( wp_unslash( get_query_var( 'noesia_cs_care_action_token' ) ) );
		$action  = sanitize_key( wp_unslash( get_query_var( 'noesia_cs_care_action_type' ) ) );
		if ( empty( $token ) || empty( $action ) ) {
			return;
		}

		$order = $this->passport_service->find_order_by_token( $token );
		if ( ! $order || ! $this->care_action_service->is_valid_action( $action ) ) {
			status_header( 404 );
			nocache_headers();
			$this->render_simple_error( __( 'Care action not found.', 'noesia-commerce-suite' ) );
			exit;
		}

		$destination = $this->resolve_care_action_destination( $order, sanitize_key( $action ) );
		if ( empty( $destination['url'] ) ) {
			status_header( 404 );
			nocache_headers();
			$this->render_simple_error( __( 'Care action destination is not configured.', 'noesia-commerce-suite' ) );
			exit;
		}

		$this->care_action_service->record_action( $order, sanitize_key( $action ), $destination['context'] );

		nocache_headers();
		header( 'X-Robots-Tag: noindex, nofollow', true );
		if ( ! empty( $destination['is_mailto'] ) ) {
			$this->render_action_redirect_page( $destination['url'], $destination['label'] );
			exit;
		}

		$this->safe_redirect_to_destination_url( $destination['url'] );
		exit;
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $url Url.
	 */
	private function safe_redirect_to_destination_url( $url ) {
		$url = esc_url_raw( $url );
		if ( '' === $url ) {
			return false;
		}

		$host = wp_parse_url( $url, PHP_URL_HOST );
		if ( $host ) {
			$allow_host = static function ( $hosts ) use ( $host ) {
				$hosts[] = $host;
				return array_unique( array_filter( $hosts ) );
			};
			add_filter( 'allowed_redirect_hosts', $allow_host );
			wp_safe_redirect( $url, 302 );
			remove_filter( 'allowed_redirect_hosts', $allow_host );
			return true;
		}

		wp_safe_redirect( $url, 302 );
		return true;
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 * @param mixed $action Action.
	 */
	private function resolve_care_action_destination( $order, $action ) {
		$settings = Noesia_CS_Settings::get_all();
		$context  = array( 'source' => 'care_page' );
		$label    = __( 'Continue', 'noesia-commerce-suite' );

		switch ( $action ) {
			case 'support':
				if ( 'url' === ( $settings['support_action_type'] ?? 'email' ) && ! empty( $settings['support_url'] ) ) {
					return array(
						'url'        => esc_url_raw( $settings['support_url'] ),
						'label'      => $settings['support_button_label'],
						'context'    => $context,
						'is_mailto'  => false,
					);
				}
				if ( ! empty( $settings['support_email'] ) ) {
					return array(
						'url'        => $this->get_support_mailto_url( $settings['support_email'], $order ),
						'label'      => $settings['support_button_label'],
						'context'    => $context,
						'is_mailto'  => true,
					);
				}
				if ( ! empty( $settings['support_url'] ) ) {
					return array(
						'url'        => esc_url_raw( $settings['support_url'] ),
						'label'      => $settings['support_button_label'],
						'context'    => $context,
						'is_mailto'  => false,
					);
				}
				break;
			case 'review_google':
				return array(
					'url'        => esc_url_raw( $settings['google_review_url'] ),
					'label'      => __( 'Google Review', 'noesia-commerce-suite' ),
					'context'    => $context,
					'is_mailto'  => false,
				);
			case 'review_trustpilot':
				return array(
					'url'        => esc_url_raw( $settings['trustpilot_url'] ),
					'label'      => __( 'Trustpilot', 'noesia-commerce-suite' ),
					'context'    => $context,
					'is_mailto'  => false,
				);
			case 'review_store':
				return array(
					'url'        => esc_url_raw( $settings['store_review_url'] ),
					'label'      => $settings['review_button_label'],
					'context'    => $context,
					'is_mailto'  => false,
				);
			case 'reorder':
				// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Public care-action URL is protected by the order token and only accepts an integer item ID.
				$item_id = isset( $_GET['item_id'] ) ? absint( wp_unslash( $_GET['item_id'] ) ) : 0;
				foreach ( $order->get_items() as $item ) {
					if ( absint( $item->get_id() ) !== $item_id ) {
						continue;
					}
					$product                = method_exists( $item, 'get_product' ) ? $item->get_product() : null;
					$context['item_id']     = $item_id;
					$context['product_id']  = $product ? absint( $product->get_id() ) : 0;
					return array(
						'url'        => esc_url_raw( $this->passport_service->get_reorder_url_for_item( $item ) ),
						'label'      => __( 'Reorder', 'noesia-commerce-suite' ),
						'context'    => $context,
						'is_mailto'  => false,
					);
				}
				break;
		}

		return array(
			'url'        => '',
			'label'      => $label,
			'context'    => $context,
			'is_mailto'  => false,
		);
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $url Url.
	 * @param mixed $label Label.
	 */
	private function render_action_redirect_page( $url, $label ) {
		$this->register_public_assets();
		wp_enqueue_style( 'noesia-cs-public' );
		Noesia_CS_Template_Loader::render(
			'public/action-redirect.php',
			array(
				'url'       => $url,
				'settings'  => Noesia_CS_Settings::get_all(),
				'label'     => $label,
			)
		);
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function maybe_render_reorder_opt_out() {
		$token = sanitize_text_field( wp_unslash( get_query_var( 'noesia_cs_reorder_optout_token' ) ) );
		if ( empty( $token ) ) {
			return;
		}

		if ( 'yes' !== Noesia_CS_Settings::get( 'reorder_opt_out_enabled', 'yes' ) ) {
			status_header( 404 );
			nocache_headers();
			exit;
		}

		$order = $this->passport_service->find_order_by_token( $token );
		if ( ! $order ) {
			status_header( 404 );
			nocache_headers();
			$this->render_simple_error( __( 'Reorder reminder opt-out link not found.', 'noesia-commerce-suite' ) );
			exit;
		}

		$this->reorder_service->opt_out_order( $order, 'public link' );
		nocache_headers();
		header( 'X-Robots-Tag: noindex, nofollow', true );
		$this->render_opt_out_page();
		exit;
	}

	/**
	 * Handles the related plugin operation.
	 */
	private function render_opt_out_page() {
		$this->register_public_assets();
		wp_enqueue_style( 'noesia-cs-public' );
		Noesia_CS_Template_Loader::render( 'public/opt-out-page.php' );
	}

	/**
	 * Handles the related plugin operation.
	 */
	public function maybe_render_care_page() {
		$token = sanitize_text_field( wp_unslash( get_query_var( 'noesia_cs_care_token' ) ) );
		if ( empty( $token ) ) {
			return;
		}

		if ( 'yes' !== Noesia_CS_Settings::get( 'enable_care_page', 'yes' ) ) {
			status_header( 404 );
			nocache_headers();
			exit;
		}

		$order = $this->passport_service->find_order_by_token( $token );
		if ( ! $order ) {
			status_header( 404 );
			nocache_headers();
			$this->render_simple_error( __( 'Order care page not found.', 'noesia-commerce-suite' ) );
			exit;
		}

		if ( 'yes' === Noesia_CS_Settings::get( 'require_login_care_page', 'no' ) ) {
			if ( ! is_user_logged_in() ) {
				auth_redirect();
			}
			if ( ! $this->current_user_can_view_order( $order ) ) {
				status_header( 403 );
				nocache_headers();
				$this->render_simple_error( __( 'You do not have permission to view this order care page.', 'noesia-commerce-suite' ) );
				exit;
			}
		}

		nocache_headers();
		if ( 'yes' === Noesia_CS_Settings::get( 'privacy_noindex', 'yes' ) ) {
			header( 'X-Robots-Tag: noindex, nofollow', true );
		}
		$this->render_care_page( $order );
		exit;
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order_id Order id.
	 */
	public function thankyou_qr_block( $order_id ) {
		if ( 'yes' !== Noesia_CS_Settings::get( 'enable_care_page', 'yes' ) || 'yes' !== Noesia_CS_Settings::get( 'thankyou_integration', 'yes' ) || 'yes' !== Noesia_CS_Settings::get( 'show_qr_thankyou', 'yes' ) || 'yes' !== Noesia_CS_Settings::get( 'enable_product_passport_qr', 'yes' ) ) {
			return;
		}
		$order = wc_get_order( $order_id );
		$this->render_customer_qr_block( $order, __( 'Order Care Hub', 'noesia-commerce-suite' ) );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 */
	public function my_account_qr_block( $order ) {
		if ( 'yes' !== Noesia_CS_Settings::get( 'enable_care_page', 'yes' ) || 'yes' !== Noesia_CS_Settings::get( 'my_account_integration', 'yes' ) || 'yes' !== Noesia_CS_Settings::get( 'show_qr_my_account', 'yes' ) || 'yes' !== Noesia_CS_Settings::get( 'enable_product_passport_qr', 'yes' ) ) {
			return;
		}
		if ( ! is_a( $order, 'WC_Order' ) ) {
			return;
		}
		$this->render_customer_qr_block( $order, __( 'Order Care Hub', 'noesia-commerce-suite' ) );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 * @param mixed $sent_to_admin Sent to admin.
	 * @param mixed $plain_text Plain text.
	 * @param mixed $email Email.
	 */
	public function email_order_care_block( $order, $sent_to_admin = false, $plain_text = false, $email = null ) {
		if ( is_numeric( $order ) && function_exists( 'wc_get_order' ) ) {
			$order = wc_get_order( absint( $order ) );
		}

		if ( $plain_text || $sent_to_admin ) {
			return;
		}

		try {
			$this->email_service->render_order_email_block( $order );
		} catch ( Throwable $exception ) {
			if ( method_exists( $this->email_service, 'log_order_email_block_failure' ) ) {
				$this->email_service->log_order_email_block_failure( $order, $exception->getMessage() );
			}
			return;
		}
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 * @param mixed $title Title.
	 */
	private function render_customer_qr_block( $order, $title ) {
		if ( 'yes' !== Noesia_CS_Settings::get( 'enable_care_page', 'yes' ) || 'yes' !== Noesia_CS_Settings::get( 'enable_product_passport_qr', 'yes' ) ) {
			return;
		}
		if ( ! $order || ! is_a( $order, 'WC_Order' ) ) {
			return;
		}

		$order_id = absint( $order->get_id() );
		if ( $order_id && isset( $this->customer_qr_blocks_rendered[ $order_id ] ) ) {
			return;
		}

		$url = $this->passport_service->get_care_url_for_order( $order );
		if ( ! $url ) {
			return;
		}

		if ( $order_id ) {
			$this->customer_qr_blocks_rendered[ $order_id ] = true;
		}

		$this->register_public_assets();
		wp_enqueue_script( 'noesia-cs-qrcode' );
		wp_enqueue_script( 'noesia-cs-public' );
		wp_enqueue_style( 'noesia-cs-public' );
		Noesia_CS_Template_Loader::render(
			'public/customer-qr-block.php',
			array(
				'order'     => $order,
				'title'     => $title,
				'url'       => $url,
				'settings'  => Noesia_CS_Settings::get_all(),
			)
		);
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 */
	private function render_care_page( $order ) {
		$settings  = Noesia_CS_Settings::get_all();
		$logo      = ! empty( $settings['company_logo'] ) ? $settings['company_logo'] : '';
		$style     = sprintf( '--noesia-cs-primary:%s;--noesia-cs-accent:%s;', esc_attr( $settings['primary_color'] ), esc_attr( $settings['accent_color'] ) );
		$hub       = $this->get_order_care_hub_context( $order, $settings );
		$this->register_public_assets();
		wp_enqueue_style( 'noesia-cs-public' );
		wp_enqueue_script( 'noesia-cs-public' );

		Noesia_CS_Template_Loader::render(
			'public/order-care-page.php',
			array(
				'order'     => $order,
				'settings'  => $settings,
				'logo'      => $logo,
				'style'     => $style,
				'hub'       => $hub,
			)
		);
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 * @param mixed $settings Settings.
	 */
	private function get_order_care_hub_context( $order, $settings ) {
		$items           = $this->get_order_hub_items( $order );
		$review_actions  = $this->get_order_hub_review_actions( $order, $settings );
		$review       = ! empty( $review_actions ) ? $review_actions[0] : array(
			'url'    => '',
			'label'  => '',
		);
		$support        = $this->get_order_hub_support_action( $order, $settings );
		$smart_links    = $this->get_order_hub_smart_links( $settings, $order );
		$first_item     = ! empty( $items ) ? $items[0] : array();
		$product_name   = ! empty( $first_item['name'] ) ? $first_item['name'] : __( 'Purchased item', 'noesia-commerce-suite' );
		$product_image  = ! empty( $first_item['image'] ) ? $first_item['image'] : '';

		return array(
			'items'           => $items,
			'first_item'      => $first_item,
			'product_name'    => $product_name,
			'product_image'   => $product_image,
			'item_count'      => count( $items ),
			'review'          => $review,
			'review_actions'  => $review_actions,
			'support'         => $support,
			'smart_links'     => $smart_links,
			'show_review'     => ! empty( $review_actions ),
			'show_support'    => ! empty( $support['url'] ),
		);
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 */
	private function get_order_hub_items( $order ) {
		$items = array();
		if ( ! $order || ! is_a( $order, 'WC_Order' ) ) {
			return $items;
		}

		foreach ( $order->get_items() as $item ) {
			$product  = method_exists( $item, 'get_product' ) ? $item->get_product() : null;
			$image    = $this->get_order_care_product_image_url( $product );

			$reorder_url = '';
			if ( $product ) {
				$reorder_url = $this->care_action_service->is_enabled() ? $this->care_action_service->get_action_url( $order, 'reorder', array( 'item_id' => $item->get_id() ) ) : $this->passport_service->get_reorder_url_for_item( $item );
			}

			$items[] = array(
				'id'           => absint( $item->get_id() ),
				'product_id'   => $product ? absint( $product->get_id() ) : 0,
				'name'         => $item->get_name(),
				'quantity'     => absint( $item->get_quantity() ),
				'image'        => $image,
				'reorder_url'  => $reorder_url,
			);
		}

		return $items;
	}

	/**
	 * Returns a clear product image for the public Order Care page.
	 *
	 * @param WC_Product|null $product Product object.
	 * @return string
	 */
	private function get_order_care_product_image_url( $product ) {
		if ( ! $product || ! method_exists( $product, 'get_image_id' ) ) {
			return function_exists( 'wc_placeholder_img_src' ) ? esc_url_raw( wc_placeholder_img_src( 'woocommerce_single' ) ) : '';
		}

		$image_id = absint( $product->get_image_id() );

		if ( ! $image_id && method_exists( $product, 'get_parent_id' ) ) {
			$parent_id = absint( $product->get_parent_id() );
			if ( $parent_id ) {
				$parent = wc_get_product( $parent_id );
				if ( $parent && method_exists( $parent, 'get_image_id' ) ) {
					$image_id = absint( $parent->get_image_id() );
				}
			}
		}

		if ( $image_id ) {
			foreach ( array( 'woocommerce_single', 'large', 'full' ) as $size ) {
				$image = wp_get_attachment_image_url( $image_id, $size );
				if ( $image ) {
					return esc_url_raw( $image );
				}
			}
		}

		return function_exists( 'wc_placeholder_img_src' ) ? esc_url_raw( wc_placeholder_img_src( 'woocommerce_single' ) ) : '';
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 * @param mixed $settings Settings.
	 */
	private function get_order_hub_review_actions( $order, $settings ) {
		if ( 'yes' !== ( $settings['show_review_button'] ?? 'yes' ) || 'yes' !== ( $settings['enable_review_block'] ?? 'yes' ) || ! $this->order_status_allows_review( $order ) ) {
			return array();
		}

		$destinations = array(
			array( 'key'   => 'google_review_url', 'action' => 'review_google', 'label' => __( 'Rate us on Google', 'noesia-commerce-suite' ) ),
			array( 'key'   => 'trustpilot_url', 'action' => 'review_trustpilot', 'label' => __( 'Rate us on Trustpilot', 'noesia-commerce-suite' ) ),
			array( 'key'   => 'store_review_url', 'action' => 'review_store', 'label' => ! empty( $settings['review_button_label'] ) ? $settings['review_button_label'] : __( 'Leave a Review', 'noesia-commerce-suite' ) ),
		);

		$actions = array();
		foreach ( $destinations as $destination ) {
			if ( empty( $settings[ $destination['key'] ] ) ) {
				continue;
			}
			$url = $this->care_action_service->is_enabled() ? $this->care_action_service->get_action_url( $order, $destination['action'] ) : esc_url_raw( $settings[ $destination['key'] ] );
			if ( empty( $url ) ) {
				continue;
			}
			$actions[] = array(
				'url'    => $url,
				'label'  => $destination['label'],
			);
		}

		return $actions;
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 * @param mixed $settings Settings.
	 */
	private function get_order_hub_review_action( $order, $settings ) {
		$actions = $this->get_order_hub_review_actions( $order, $settings );
		return ! empty( $actions ) ? $actions[0] : array(
			'url'    => '',
			'label'  => '',
		);
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 * @param mixed $settings Settings.
	 */
	private function get_order_hub_support_action( $order, $settings ) {
		if ( 'yes' !== ( $settings['show_support_button'] ?? 'yes' ) || 'yes' !== ( $settings['enable_support_block'] ?? 'yes' ) ) {
			return array(
				'url'    => '',
				'label'  => '',
			);
		}

		$type = $settings['support_action_type'] ?? 'email';
		if ( 'url' === $type && ! empty( $settings['support_url'] ) ) {
			$url = $this->care_action_service->is_enabled() ? $this->care_action_service->get_action_url( $order, 'support' ) : esc_url_raw( $settings['support_url'] );
			return array(
				'url'    => $url,
				'label'  => $settings['support_button_label'] ?? __( 'Need Help?', 'noesia-commerce-suite' ),
			);
		}

		if ( ! empty( $settings['support_email'] ) ) {
			$url = $this->care_action_service->is_enabled() ? $this->care_action_service->get_action_url( $order, 'support' ) : $this->get_support_mailto_url( $settings['support_email'], $order );
			return array(
				'url'    => $url,
				'label'  => $settings['support_button_label'] ?? __( 'Need Help?', 'noesia-commerce-suite' ),
			);
		}

		if ( ! empty( $settings['support_url'] ) ) {
			$url = $this->care_action_service->is_enabled() ? $this->care_action_service->get_action_url( $order, 'support' ) : esc_url_raw( $settings['support_url'] );
			return array(
				'url'    => $url,
				'label'  => $settings['support_button_label'] ?? __( 'Need Help?', 'noesia-commerce-suite' ),
			);
		}

		return array(
			'url'    => '',
			'label'  => '',
		);
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $settings Settings.
	 * @param mixed $order    WooCommerce order.
	 */
	private function get_order_hub_smart_links( $settings, $order = null ) {
		$links = array();
		$definitions = array(
			'warranty' => array(
				'enabled'   => 'order_care_warranty_enabled',
				'title'     => 'order_care_warranty_title',
				'text'      => 'order_care_warranty_text',
				'button'    => 'order_care_warranty_button_label',
				'url'       => 'order_care_warranty_url',
				'icon'      => '🛡️',
			),
			'documents' => array(
				'enabled'    => 'order_care_documents_enabled',
				'title'      => 'order_care_documents_title',
				'text'       => 'order_care_documents_text',
				'button'     => 'order_care_documents_button_label',
				'url'        => 'order_care_documents_url',
				'icon'       => '📄',
			),
			'video'   => array(
				'enabled'  => 'order_care_video_enabled',
				'title'    => 'order_care_video_title',
				'text'     => 'order_care_video_text',
				'button'   => 'order_care_video_button_label',
				'url'      => 'order_care_video_url',
				'icon'     => '▶️',
			),
		);

		foreach ( $definitions as $key => $definition ) {
			if ( 'yes' !== ( $settings[ $definition['enabled'] ] ?? 'no' ) || empty( $settings[ $definition['url'] ] ) ) {
				continue;
			}
			$links[] = array(
				'key'     => $key,
				'icon'    => $definition['icon'],
				'title'   => $settings[ $definition['title'] ] ?? '',
				'text'    => $settings[ $definition['text'] ] ?? '',
				'button'  => $settings[ $definition['button'] ] ?? __( 'Open', 'noesia-commerce-suite' ),
				'url'     => esc_url_raw( $settings[ $definition['url'] ] ),
			);
		}

		if ( 'yes' === ( $settings['order_care_promo_enabled'] ?? 'no' ) && ( ! empty( $settings['order_care_promo_text'] ) || ! empty( $settings['order_care_promo_code'] ) ) ) {
			$links[] = array(
				'key'     => 'promo',
				'icon'    => '🎁',
				'title'   => $settings['order_care_promo_title'] ?? __( 'Thank you offer', 'noesia-commerce-suite' ),
				'text'    => $settings['order_care_promo_text'] ?? '',
				'code'    => $settings['order_care_promo_code'] ?? '',
				'button'  => $settings['order_care_promo_button_label'] ?? __( 'Shop again', 'noesia-commerce-suite' ),
				'url'     => ! empty( $settings['order_care_promo_url'] ) ? esc_url_raw( $settings['order_care_promo_url'] ) : '',
			);
		}

		/**
		 * Allows Pro/add-on modules to append safe, privacy-friendly smart links to the public Order Care Hub.
		 *
		 * @param array<int,array<string,mixed>> $links    Existing smart links.
		 * @param mixed                         $order    WooCommerce order object.
		 * @param array<string,mixed>           $settings Public hub settings.
		 */
		return apply_filters( 'noesia_cs_order_care_smart_links', $links, $order, $settings );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 */
	private function order_status_allows_review( $order ) {
		if ( ! $order || ! is_a( $order, 'WC_Order' ) ) {
			return false;
		}

		$blocked_statuses = array( 'cancelled', 'refunded', 'failed', 'checkout-draft' );
		return ! in_array( $order->get_status(), $blocked_statuses, true );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $email Email.
	 * @param mixed $order Order.
	 */
	private function get_support_mailto_url( $email, $order = null ) {
		$email = sanitize_email( $email );
		if ( ! $email ) {
			return '';
		}

		$order_reference  = ( $order && is_a( $order, 'WC_Order' ) ) ? '#' . $order->get_order_number() : '';
		$subject          = $order_reference ? sprintf( /* translators: %s: dynamic value. */ __( 'Support Request for Order %s', 'noesia-commerce-suite' ), $order_reference ) : __( 'Support Request', 'noesia-commerce-suite' );
		$body             = $order_reference ? sprintf( /* translators: %s: dynamic value. */ __( 'Hello, I need help with order %s.', 'noesia-commerce-suite' ), $order_reference ) : __( 'Hello, I need help with my order.', 'noesia-commerce-suite' );

		return 'mailto:' . $email . '?subject=' . rawurlencode( $subject ) . '&body=' . rawurlencode( $body );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $settings Settings.
	 * @param mixed $order Order.
	 */
	public function render_support_buttons( $settings, $order = null ) {
		if ( 'yes' !== $settings['show_support_button'] || 'yes' !== $settings['enable_support_block'] ) {
			return;
		}
		if ( $settings['support_intro_text'] ) {
			echo '<p class="noesia-cs-care-action-note">' . esc_html( $settings['support_intro_text'] ) . '</p>';
		}
		if ( 'url' === ( $settings['support_action_type'] ?? 'email' ) && $settings['support_url'] ) {
			$support_href = ( $order && $this->care_action_service->is_enabled() ) ? $this->care_action_service->get_action_url( $order, 'support' ) : $settings['support_url'];
			echo '<a class="noesia-cs-care-button" href="' . esc_url( $support_href ) . '" target="_blank" rel="noopener noreferrer nofollow">' . esc_html( $settings['support_button_label'] ) . '</a>';
			return;
		}
		if ( $settings['support_email'] ) {
			$support_href = ( $order && $this->care_action_service->is_enabled() ) ? $this->care_action_service->get_action_url( $order, 'support' ) : $this->get_support_mailto_url( $settings['support_email'], $order );
			echo '<a class="noesia-cs-care-button" href="' . esc_url( $support_href ) . '">' . esc_html( $settings['support_button_label'] ) . '</a>';
			return;
		}
		if ( $settings['support_url'] ) {
			$support_href = ( $order && $this->care_action_service->is_enabled() ) ? $this->care_action_service->get_action_url( $order, 'support' ) : $settings['support_url'];
			echo '<a class="noesia-cs-care-button" href="' . esc_url( $support_href ) . '" target="_blank" rel="noopener noreferrer nofollow">' . esc_html( $settings['support_button_label'] ) . '</a>';
		}
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $settings Settings.
	 * @param mixed $order Order.
	 */
	public function render_review_buttons( $settings, $order = null ) {
		if ( 'yes' !== $settings['show_review_button'] || 'yes' !== $settings['enable_review_block'] || ( $order && ! $this->order_status_allows_review( $order ) ) ) {
			return;
		}
		$links = array(
			'google_review_url'   => array( 'label' => __( 'Google Review', 'noesia-commerce-suite' ), 'action' => 'review_google' ),
			'trustpilot_url'      => array( 'label' => __( 'Trustpilot', 'noesia-commerce-suite' ), 'action' => 'review_trustpilot' ),
			'store_review_url'    => array( 'label' => $settings['review_button_label'], 'action' => 'review_store' ),
		);
		$printed = false;
		foreach ( $links as $key => $link ) {
			if ( empty( $settings[ $key ] ) ) {
				continue;
			}
			if ( ! $printed && $settings['review_intro_text'] ) {
				echo '<p class="noesia-cs-care-action-note">' . esc_html( $settings['review_intro_text'] ) . '</p>';
				$printed = true;
			}
			$review_href = ( $order && $this->care_action_service->is_enabled() ) ? $this->care_action_service->get_action_url( $order, $link['action'] ) : $settings[ $key ];
			echo '<a class="noesia-cs-care-button secondary" href="' . esc_url( $review_href ) . '" target="_blank" rel="noopener noreferrer nofollow">' . esc_html( $link['label'] ) . '</a>';
		}
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $order Order.
	 */
	private function current_user_can_view_order( $order ) {
		if ( current_user_can( NOESIA_CS_CAPABILITY ) || current_user_can( 'manage_options' ) ) {
			return true;
		}
		$user_id = get_current_user_id();
		return $user_id && absint( $order->get_customer_id() ) === absint( $user_id );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $message Message.
	 */
	private function render_simple_error( $message ) {
		Noesia_CS_Template_Loader::render( 'public/simple-error.php', array( 'message' => $message ) );
	}

	/**
	 * Handles the related plugin operation.
	 *
	 * @param mixed $atts Atts.
	 */
	public function impact_map_shortcode( $atts ) {
		if ( 'yes' !== Noesia_CS_Settings::get( 'enable_impact_map_shortcode', 'yes' ) || 'yes' !== Noesia_CS_Settings::get( 'impact_map_cache_enabled', 'yes' ) ) {
			return '';
		}

		$this->register_public_assets();
		wp_enqueue_style( 'noesia-cs-public' );
		$snapshot  = $this->impact_map_service->get_snapshot();
		$settings  = Noesia_CS_Settings::get_all();

		ob_start();
		Noesia_CS_Template_Loader::render(
			'public/impact-map.php',
			array(
				'snapshot'  => $snapshot,
				'settings'  => $settings,
			)
		);
		return ob_get_clean();
	}
}
