<?php

use includes\WTV_Plugin;

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

class WTV_Promo_Notice {

	private $plugin_version;

	const WETAIL_OPTION_VER = 'wetail_plugin_version';
	const WETAIL_OPTION_SHOW_AFTER_UPDATE = 'wetail_show_after_update';
	const WETAIL_UMETA_DISMISS_OTHER = 'wetail_dismiss_notice_other';
	const WETAIL_UMETA_DISMISS_DASH = 'wetail_dismiss_notice_dashboard';
	const WETAIL_DASH_WIDGET_ID = 'wetail_shipping_toggle_widget';
	const WETAIL_SHIPPING_PLUGIN_SLUG = 'wetail-shipping';

	public function __construct( $plugin_version ) {
		$this->plugin_version = $plugin_version;
		add_action( 'wp_ajax_wetail_toggle_dashboard_widget', array( $this, 'ajax_toggle_dashboard_widget' ) );
		add_action( 'admin_init', array( $this, 'check_version' ) );
		add_action( 'admin_notices', array( $this, 'show_promo_notice' ) );
		add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widget' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_notice_script' ) );
		add_action( 'wp_ajax_wetail_dismiss_promo_notice', array( $this, 'ajax_dismiss_promo_notice' ) );
	}

	/**
	 * Checks the current version of the plugin and updates version-related options if necessary.
	 *
	 * @return void
	 */
	public function check_version() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$prev = get_option( self::WETAIL_OPTION_VER );
		if ( $prev === $this->plugin_version ) {
			return;
		}

		update_option( self::WETAIL_OPTION_VER, $this->plugin_version );
		update_option( self::WETAIL_OPTION_SHOW_AFTER_UPDATE, 1 );
	}


	/**
	 * Enqueues the promo notice script for specific admin pages.
	 *
	 * @param string $hook The current admin page hook suffix. Determines if scripts should be enqueued.
	 *
	 * @return void
	 */
	public function enqueue_notice_script( $hook ) {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		wp_enqueue_script( 'plugin-install' );
		wp_enqueue_script( 'updates' );

		wp_enqueue_script(
			'wetail-promo-notice',
			plugins_url( 'assets/scripts/promo.js', dirname( __FILE__ ) ),
			array(
				'jquery',
				'plugin-install',
				'updates'
			),
			$this->plugin_version,
			true
		);

		wp_enqueue_style( 'wetail-promo-notice', plugins_url( 'assets/styles/promo.css', dirname( __FILE__ ) ) );

		wp_add_inline_style( 'wetail-promo-notice', '.postbox#' . self::WETAIL_DASH_WIDGET_ID . ' { opacity: 0; visibility: hidden; overflow: hidden; width: 1px; height: 1px; margin: 0; padding: 0; border: 0; position: absolute; }' );
	}

	/**
	 * Handles the AJAX request to dismiss the promo notice.
	 *
	 * Validates the current user's permissions and nonce, then updates metadata
	 * to track dismissed promo notices based on the specified location.
	 *
	 * @return void
	 */
	public function ajax_dismiss_promo_notice() {
		try {
			if ( ! current_user_can( 'manage_options' ) ) {
				throw new Exception( 'User does not have permission to dismiss promo notice.' );
			}

			$nonce = isset( $_POST[ 'nonce' ] ) ? sanitize_text_field( wp_unslash( $_POST[ 'nonce' ] ) ) : '';
			if ( ! wp_verify_nonce( $nonce, 'wetail_dismiss_promo_notice' ) ) {
				throw new Exception( 'Invalid nonce.' );
			}

			$location = isset( $_POST[ 'location' ] ) ? sanitize_key( $_POST[ 'location' ] ) : '';
			$user_id  = get_current_user_id();

			if ( 'dashboard' === $location ) {
				update_user_meta( $user_id, self::WETAIL_UMETA_DISMISS_DASH, 1 );

				$hidden = (array) get_user_meta( $user_id, 'metaboxhidden_dashboard', true );
				if ( ! in_array( self::WETAIL_DASH_WIDGET_ID, $hidden, true ) ) {
					$hidden[] = self::WETAIL_DASH_WIDGET_ID;
					update_user_meta( $user_id, 'metaboxhidden_dashboard', $hidden );
				}
			} else {
				update_user_meta( $user_id, self::WETAIL_UMETA_DISMISS_OTHER, $this->plugin_version );
			}

			wp_send_json_success();
		} catch ( Exception $e ) {
			$error_message = $e->getMessage();
			if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
				$error_message .= ' in ' . $e->getFile() . ' on line ' . $e->getLine();
			}
			wp_send_json_error( [ 'message' => $error_message ] );
		}
	}


	/**
	 * Displays a promotional notice for the Wetail Shipping plugin.
	 *
	 * The notice includes plugin-related information, such as activation or installation actions,
	 * promotional features, and a dismiss option for the user. The visibility of the notice is
	 * determined by user permissions, screen context, plugin state, and user-specific metadata.
	 *
	 * @return void
	 */
	public function show_promo_notice() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
		if ( ! $screen ) {
			return;
		}

		if ( ! get_option( self::WETAIL_OPTION_SHOW_AFTER_UPDATE ) ) {
			return;
		}

		$plugin_info = $this->get_wetail_shipping_plugin_info();

		if ( 'active' === $plugin_info[ 'state' ] ) {
			return;
		}

		$button_text = 'installed' === $plugin_info[ 'state' ]
			? __( 'Activate plugin', WTV_Plugin::TEXTDOMAIN )
			: __( 'Install plugin', WTV_Plugin::TEXTDOMAIN );

		$button_href = $plugin_info[ 'activate_url' ];

		$button_classes = array(
			'button',
			'button-primary',
			'wtv-promo-notice-button',
		);

		if ( 'not_installed' === $plugin_info[ 'state' ] ) {
			$button_classes[] = 'wtv-promo-notice-button--ready';
		}

		$user_id = get_current_user_id();
		$hidden_class = '';

		if ( 'dashboard' === $screen->id ) {
			$dismissed      = (bool) get_user_meta( $user_id, self::WETAIL_UMETA_DISMISS_DASH, true );
			$widget_enabled = $this->is_dash_widget_enabled_for_user( $user_id );

			if ( $dismissed && ! $widget_enabled ) {
				$hidden_class = 'wtv-promo-notice-banner--hidden';
			}

			$location = 'dashboard';
		} else {
			$dismissed_version = get_user_meta( $user_id, self::WETAIL_UMETA_DISMISS_OTHER, true );
			if ( $dismissed_version === $this->plugin_version ) {
				return;
			}

			$location = 'other';
		}

		$nonce = wp_create_nonce( 'wetail_dismiss_promo_notice' );
		?>
		<div
			class="notice notice-info is-dismissible wtv-promo-notice-banner <?php echo esc_attr( $hidden_class ); ?> <?php echo esc_attr( 'wtv-promo-notice-' . $location ); ?> wetail-enhancements-do-not-move"
			data-nonce="<?php echo esc_attr( $nonce ); ?>" data-location="<?php echo esc_attr( $location ); ?>">
			<div class="wtv-promo-notice-inner">
				<div class="wtv-promo-notice-content">
					<div class="wtv-promo-notice-text">
						<h2 class="wtv-promo-notice-title"><?php
							esc_html_e( 'Save money with Wetail Shipping', WTV_Plugin::TEXTDOMAIN );
							?></h2>
						<p class="wtv-promo-notice-description"><?php
							esc_html_e( 'Modern shipping service. Designed for WooCommerce.', WTV_Plugin::TEXTDOMAIN );
							?></p>
					</div>
					<div class="wtv-promo-notice-usps">
						<div
							class="wtv-promo-notice-usps__item"><?php esc_html_e( 'No fixed monthly cost', WTV_Plugin::TEXTDOMAIN ); ?></div>
						<div
							class="wtv-promo-notice-usps__item"><?php esc_html_e( 'From 0.67 SEK/waybill', WTV_Plugin::TEXTDOMAIN ); ?></div>
						<div
							class="wtv-promo-notice-usps__item"><?php esc_html_e( 'Return portal included', WTV_Plugin::TEXTDOMAIN ); ?></div>
						<div
							class="wtv-promo-notice-usps__item"><?php esc_html_e( 'Free plugin for WooCommerce', WTV_Plugin::TEXTDOMAIN ); ?></div>
					</div>
					<div class="wtv-promo-notice-actions">
						<a class="<?php echo esc_attr( implode( ' ', $button_classes ) ); ?>"
						   href="<?php echo esc_url( $button_href ); ?>"
						   data-plugin-slug="<?php echo esc_attr( self::WETAIL_SHIPPING_PLUGIN_SLUG ); ?>"
						   data-installing="<?php esc_attr_e( 'Installing', WTV_Plugin::TEXTDOMAIN ); ?>"
						   data-installed="<?php esc_attr_e( 'Installed', WTV_Plugin::TEXTDOMAIN ); ?>"
						   data-error="<?php esc_attr_e( 'Error', WTV_Plugin::TEXTDOMAIN ); ?>"
						   data-activate="<?php esc_attr_e( 'Activate', WTV_Plugin::TEXTDOMAIN ); ?>">
							<span class="dashicons dashicons-wordpress-alt"></span>
							<span class="wtv-promo-notice-button__text"><?php echo esc_html( $button_text ); ?></span>
						</a>
						<a class="button-link wtv-promo-notice-more"
						   target="_blank"
						   href="https://wetail.io/integrationer/wetail-shipping/">
							<?php esc_html_e( 'Read more', WTV_Plugin::TEXTDOMAIN ); ?>
						</a>
					</div>
				</div>
				<div class="wtv-promo-notice-image-wrapper">
					<img class="wtv-promo-notice-image"
					     src="<?php echo esc_url( WTV_Plugin::get_url( 'assets/images/wetail-shipping-promo.png' ) ); ?>"
					     alt="<?php esc_attr_e( 'Wetail Shipping', WTV_Plugin::TEXTDOMAIN ); ?>">
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Handles the AJAX request to toggle the visibility of the dashboard widget.
	 *
	 * This method updates the user's dashboard settings to either show or hide a specific dashboard widget
	 * based on the provided AJAX request. It validates the nonce, checks user permissions, and modifies
	 * the `metaboxhidden_dashboard` user metadata to reflect the widget's desired visibility state.
	 *
	 * @return void
	 */
	public function ajax_toggle_dashboard_widget() {
		check_ajax_referer( 'wetail_dismiss_promo_notice', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( 'Permission denied.' );
		}

		$user_id = get_current_user_id();
		$checked = isset( $_POST[ 'checked' ] ) && 'true' === $_POST[ 'checked' ];
		$hidden  = (array) get_user_meta( $user_id, 'metaboxhidden_dashboard', true );

		if ( $checked ) {
			$hidden = array_diff( $hidden, array( self::WETAIL_DASH_WIDGET_ID ) );
		} else {
			if ( ! in_array( self::WETAIL_DASH_WIDGET_ID, $hidden, true ) ) {
				$hidden[] = self::WETAIL_DASH_WIDGET_ID;
			}
		}

		update_user_meta( $user_id, 'metaboxhidden_dashboard', $hidden );
		wp_send_json_success();
	}

	/**
	 * Retrieves information about the Wetail Shipping plugin, including its installation state,
	 * the corresponding plugin file, and the activation URL (if applicable).
	 *
	 * The method caches the result to optimize performance, avoiding repeated calls to plugin functions.
	 *
	 * @return array An associative array containing the following keys:
	 *               - 'state': A string indicating the plugin's current state. Possible values: 'not_installed', 'installed', 'active'.
	 *               - 'plugin_file': A string representing the plugin file path, or null if the plugin is not installed.
	 *               - 'activate_url': A string containing the URL to activate or install the plugin, or null if no action is applicable.
	 */
	private function get_wetail_shipping_plugin_info() {
		static $cache = null;

		if ( null !== $cache ) {
			return $cache;
		}

		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$cache = array(
			'state'        => 'not_installed',
			'plugin_file'  => null,
			'activate_url' => null,
		);

		$plugins = get_plugins();

		foreach ( $plugins as $plugin_file => $plugin_data ) {
			if ( 0 === strpos( $plugin_file, self::WETAIL_SHIPPING_PLUGIN_SLUG . '/' ) ) {
				$cache[ 'plugin_file' ] = $plugin_file;
				$cache[ 'state' ]       = is_plugin_active( $plugin_file ) ? 'active' : 'installed';

				if ( 'installed' === $cache[ 'state' ] ) {
					$plugin_basename         = plugin_basename( $plugin_file );
					$cache[ 'activate_url' ] = wp_nonce_url(
						admin_url( 'plugins.php?action=activate&plugin=' . urlencode( $plugin_basename ) ),
						'activate-plugin_' . $plugin_basename
					);
				}

				return $cache;
			}
		}

		$cache[ 'activate_url' ] = admin_url( 'plugin-install.php?tab=plugin-information&plugin=' . self::WETAIL_SHIPPING_PLUGIN_SLUG . '&TB_iframe=true&width=600&height=550' );

		return $cache;
	}

	/**
	 * Adds a custom dashboard widget to the WordPress admin dashboard.
	 *
	 * @return void
	 */
	public function add_dashboard_widget() {
		wp_add_dashboard_widget(
			self::WETAIL_DASH_WIDGET_ID,
			'Wetail Shipping',
			function () {
				echo '<p>' . esc_html__( 'You can toggle the top banner via Screen Options.', WTV_Plugin::TEXTDOMAIN ) . '</p>';
			}
		);
	}

	/**
	 * Checks if the dashboard widget is enabled for a given user.
	 *
	 * @param int $user_id The ID of the user to check.
	 *
	 * @return bool True if the dashboard widget is enabled, false otherwise.
	 */
	private function is_dash_widget_enabled_for_user( $user_id ) {
		$hidden = (array) get_user_meta( $user_id, 'metaboxhidden_dashboard', true );

		return ! in_array( self::WETAIL_DASH_WIDGET_ID, $hidden, true );
	}

	/**
	 * Stops showing specific content after an update by deleting the associated option.
	 *
	 * @return void
	 */
	public static function stop_showing_after_update() {
		delete_option( self::WETAIL_OPTION_SHOW_AFTER_UPDATE );
	}
}
