<?php

namespace Simplyin\Simplyin_W_Plugin\Admin;

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

/**
 * Displays a dismissable notice when Block Checkout is active on WooCommerce older than 8.9.
 *
 * Notice appears in two places:
 * - WordPress admin (all pages) — uses native WP admin notice style.
 * - Frontend checkout page — uses a fixed banner visible only while on the checkout.
 *
 * Shown only to logged-in users with the manage_woocommerce capability (not buyers).
 * Dismissed permanently per user via an AJAX-backed user meta flag.
 *
 * @since 5.5.36
 */
class Block_Checkout_Notice {

	private const WC_MIN_VERSION = '8.9';
	private const NONCE_ACTION = 'simplyin_dismiss_block_checkout_notice';
	private const AJAX_ACTION = 'simplyin_dismiss_block_checkout_notice';
	private const USER_META_KEY = 'simplyin_block_checkout_notice_dismissed';
	private const NOTICE_HTML_ID = 'simplyin-block-checkout-wc-notice';

	/**
	 * Registers WordPress hooks for admin notice, frontend notice, and AJAX dismiss handler.
	 *
	 * @return void
	 */
	public function register(): void {
		add_action( 'admin_init', array( $this, 'maybe_enqueue_admin' ) );
		add_action( 'wp', array( $this, 'maybe_enqueue_frontend' ) );
		add_action( 'wp_ajax_' . self::AJAX_ACTION, array( $this, 'handle_dismiss' ) );
	}

	/**
	 * Registers admin notice hooks when all display conditions are met.
	 *
	 * @return void
	 */
	public function maybe_enqueue_admin(): void {
		if ( ! $this->passes_common_conditions() ) {
			return;
		}

		add_action( 'admin_notices', array( $this, 'render_admin_notice' ) );
		add_action( 'admin_footer', array( $this, 'render_admin_dismiss_script' ) );
	}

	/**
	 * Registers frontend footer notice hook when on the checkout page and all conditions are met.
	 *
	 * @return void
	 */
	public function maybe_enqueue_frontend(): void {
		if ( ! function_exists( 'is_checkout' ) || ! is_checkout() ) {
			return;
		}
		if ( ! $this->passes_common_conditions() ) {
			return;
		}
		add_action( 'wp_footer', array( $this, 'render_frontend_notice' ) );
	}

	/**
	 * Renders the WP-native dismissable admin notice.
	 *
	 * @return void
	 */
	public function render_admin_notice(): void {
		$nonce = wp_create_nonce( self::NONCE_ACTION );
		?>
		<div class="notice notice-error is-dismissible" id="<?php echo esc_attr( self::NOTICE_HTML_ID ); ?>"
			 data-nonce="<?php echo esc_attr( $nonce ); ?>">
			<p>
				<strong>Simply.IN:</strong>
				<?php echo esc_html( $this->get_notice_message() ); ?>
			</p>
		</div>
		<?php
	}

	/**
	 * Outputs inline JavaScript that fires the AJAX dismiss request when the WP notice X is clicked.
	 *
	 * Relies on ajaxurl, available on all wp-admin pages.
	 *
	 * @return void
	 */
	public function render_admin_dismiss_script(): void {
		$notice_id   = self::NOTICE_HTML_ID;
		$ajax_action = self::AJAX_ACTION;
		?>
		<script>
			(function () {
				document.addEventListener('DOMContentLoaded', function () {
					var notice = document.getElementById('<?php echo esc_js( $notice_id ); ?>');
					if (!notice) {
						return;
					}
					notice.addEventListener('click', function (e) {
						if (!e.target.classList.contains('notice-dismiss')) {
							return;
						}
						var data = new FormData();
						data.append('action', '<?php echo esc_js( $ajax_action ); ?>');
						data.append('nonce', notice.getAttribute('data-nonce'));
						fetch(ajaxurl, {method: 'POST', body: data});
					});
				});
			}());
		</script>
		<?php
	}

	/**
	 * Renders the fixed-position frontend banner with an inline dismiss button and script.
	 *
	 * ajaxurl is not available on the frontend, so admin-ajax.php is output directly.
	 *
	 * @return void
	 */
	public function render_frontend_notice(): void {
		$nonce       = wp_create_nonce( self::NONCE_ACTION );
		$notice_id   = self::NOTICE_HTML_ID;
		$ajax_action = self::AJAX_ACTION;
		$ajax_url    = admin_url( 'admin-ajax.php' );
		?>
		<div id="<?php echo esc_attr( $notice_id ); ?>" data-nonce="<?php echo esc_attr( $nonce ); ?>"
			 style="position:fixed;top:0;left:0;right:0;z-index:99999;background:#fff3cd;border-bottom:3px solid #ffc107;padding:12px 48px 12px 16px;font-size:14px;line-height:1.5;box-shadow:0 2px 6px rgba(0,0,0,.15);">
			<strong>Simply.IN:</strong>
			<?php echo esc_html( $this->get_notice_message() ); ?>
			<button type="button" id="<?php echo esc_attr( $notice_id . '-dismiss' ); ?>"
					aria-label="<?php esc_attr_e( 'Dismiss this notice', 'simplyin' ); ?>"
					style="position:absolute;top:50%;right:12px;transform:translateY(-50%);background:none;border:none;cursor:pointer;font-size:20px;line-height:1;padding:0;">
				&times;
			</button>
		</div>
		<script>
			(function () {
				var notice = document.getElementById('<?php echo esc_js( $notice_id ); ?>');
				var btn = document.getElementById('<?php echo esc_js( $notice_id . '-dismiss' ); ?>');
				if (!notice || !btn) {
					return;
				}
				btn.addEventListener('click', function () {
					notice.remove();
					var data = new FormData();
					data.append('action', '<?php echo esc_js( $ajax_action ); ?>');
					data.append('nonce', notice.getAttribute('data-nonce'));
					fetch('<?php echo esc_js( $ajax_url ); ?>', {method: 'POST', body: data});
				});
			}());
		</script>
		<?php
	}

	/**
	 * Handles the AJAX request to permanently dismiss the notice for the current user.
	 *
	 * Verifies the nonce and manage_woocommerce capability before writing the dismissal
	 * flag to user meta.
	 *
	 * @return void
	 */
	public function handle_dismiss(): void {
		$nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
		if ( ! wp_verify_nonce( $nonce, self::NONCE_ACTION ) || ! current_user_can( 'manage_woocommerce' ) ) {
			wp_die( '', '', array( 'response' => 403 ) );
		}
		update_user_meta( get_current_user_id(), self::USER_META_KEY, '1' );
		wp_send_json_success();
	}

	/**
	 * Returns the translated notice message string.
	 *
	 * @return string
	 */
	private function get_notice_message(): string {
		return __( 'Simply.IN works on your store\'s Classic Checkout. To also enable additional Simply.IN fields in Block Checkout, please update WooCommerce to version 8.9 or newer.', 'simplyin' );
	}

	/**
	 * Checks all shared display conditions: capability, dismissed flag, WC version, block checkout.
	 *
	 * @return bool True when the notice should be displayed.
	 */
	private function passes_common_conditions(): bool {
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
			return false;
		}
		if ( get_user_meta( get_current_user_id(), self::USER_META_KEY, true ) ) {
			return false;
		}
		if ( ! defined( 'WC_VERSION' ) || version_compare( WC_VERSION, self::WC_MIN_VERSION, '>=' ) ) {
			return false;
		}

		return $this->checkout_page_uses_blocks();
	}

	/**
	 * Checks whether the WooCommerce checkout page uses the block checkout.
	 *
	 * Uses wc_get_page_id() so it works correctly in both admin and frontend context.
	 *
	 * @return bool True when the checkout page contains the woocommerce/checkout block.
	 */
	private function checkout_page_uses_blocks(): bool {
		if ( ! function_exists( 'wc_get_page_id' ) || ! function_exists( 'has_block' ) ) {
			return false;
		}
		$checkout_page_id = wc_get_page_id( 'checkout' );
		if ( 0 >= $checkout_page_id ) {
			return false;
		}
		$content = (string) get_post_field( 'post_content', $checkout_page_id );

		return '' !== $content && has_block( 'woocommerce/checkout', $content );
	}
}
