<?php
/**
 * Manage the MonsterInsights Dashboard Widget
 *
 * @since 7.1
 *
 * @package MonsterInsights
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class MonsterInsights_Dashboard_Widget
 */
class MonsterInsights_Dashboard_Widget {

	const WIDGET_KEY = 'monsterinsights_reports_widget';
	/**
	 * The default options for the widget.
	 *
	 * @var array $default_options
	 */
	public static $default_options = array(
		'width'    => 'regular',
		'interval' => '30',
		'compact'  => false,
		'reports'  => array(
			'overview'    => array(
				'toppages'    => true,
				'newvsreturn' => true,
				'devices'     => true,
			),
			'publisher'   => array(
				'landingpages'   => false,
				'exitpages'      => false,
				'outboundlinks'  => false,
				'affiliatelinks' => false,
				'downloadlinks'  => false,
			),
			'ecommerce'   => array(
				'infobox'            => false, // E-commerce Overview.
				'products'           => false, // Top Products.
				'conversions'        => false, // Top Products.
				'addremove'          => false, // Total Add/Remove.
				'days'               => false, // Time to purchase.
				'sessions'           => false, // Sessions to purchase.
				'newcustomers'       => false,
				'abandonedcheckouts' => false,
			),
			'notice30day' => false,
		),
	);
	/**
	 * The widget options.
	 *
	 * @var array $options
	 */
	public $options;

	/**
	 * MonsterInsights_Dashboard_Widget constructor.
	 */
	public function __construct() {
		// Allow dashboard widget to be hidden on multisite installs
		$show_widget = is_multisite() ? apply_filters( 'monsterinsights_show_dashboard_widget', true ) : true;
		if ( ! $show_widget ) {
			return false;
		}

		// Check if reports should be visible.
		$dashboards_disabled = monsterinsights_get_option( 'dashboards_disabled', false );
		if ( ! current_user_can( 'monsterinsights_view_dashboard' ) || 'disabled' === $dashboards_disabled ) {
			return false;
		}

		add_action( 'wp_dashboard_setup', array( $this, 'register_dashboard_widget' ) );

		add_action( 'admin_enqueue_scripts', array( $this, 'widget_scripts' ) );

		add_action( 'wp_ajax_monsterinsights_save_widget_state', array( $this, 'save_widget_state' ) );

		// Reminder notice.
//		add_action( 'admin_footer', array( $this, 'load_notice' ) );

		add_action( 'wp_ajax_monsterinsights_mark_notice_closed', array( $this, 'mark_notice_closed' ) );
	}

	/**
	 * Register the dashboard widget.
	 */
	public function register_dashboard_widget() {
		global $wp_meta_boxes;

		wp_add_dashboard_widget(
			self::WIDGET_KEY,
			esc_html__( 'MonsterInsights', 'google-analytics-for-wordpress' ),
			array( $this, 'dashboard_widget_content' )
		);

		// Attempt to place the widget at the top.
		$normal_dashboard = $wp_meta_boxes['dashboard']['normal']['core'];
		$widget_instance  = array( self::WIDGET_KEY => $normal_dashboard[ self::WIDGET_KEY ] );
		unset( $normal_dashboard[ self::WIDGET_KEY ] );
		$sorted_dashboard                             = array_merge( $widget_instance, $normal_dashboard );
		$wp_meta_boxes['dashboard']['normal']['core'] = $sorted_dashboard; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Nothing to see here...
	}

	/**
	 * Load the widget content.
	 */
	public function dashboard_widget_content() {
		$is_authed = ( MonsterInsights()->auth->is_authed() || MonsterInsights()->auth->is_network_authed() );

		if ( ! $is_authed ) {
			$this->widget_content_no_auth();
		} else {
			monsterinsights_settings_error_page( 'monsterinsights-dashboard-widget', '', '0' );
			monsterinsights_settings_inline_js();
		}

	}

	/**
	 * Message to display when the plugin is not authenticated.
	 */
	public function widget_content_no_auth() {

		?>
		<div class="mi-dw-not-authed">
			<?php
			$message = sprintf(
				/* translators: %1$s: Opening wizard link tag, %2$s: Closing wizard link tag. */
				esc_html__( 'Your website analytics dashboard is not currently configured. Please use our %1$ssetup wizard%2$s to get started.', 'google-analytics-for-wordpress' ),
				'<a class="monsterinsights-setup-wizard-link">',
				'</a>'
			);
			?>
			<h2><?php echo $message; // phpcs:ignore ?></h2>
			<?php if ( current_user_can( 'monsterinsights_save_settings' ) ) { ?>
				<p><?php esc_html_e( 'To see your website stats, please connect MonsterInsights to Google Analytics.', 'google-analytics-for-wordpress' ); ?></p>
				<a class="mi-dw-btn-large monsterinsights-setup-wizard-link"><?php esc_html_e( 'Setup Website Analytics', 'google-analytics-for-wordpress' ); ?></a>
				<p><?php esc_html_e( 'Note: You will be transfered to MonsterInsights.com to complete the setup wizard.', 'google-analytics-for-wordpress' ); ?></p>
			<?php } else { ?>
				<p><?php esc_html_e( 'To see your website stats, please ask your site administrator to connect MonsterInsights to Google Analytics.', 'google-analytics-for-wordpress' ); ?></p>
			<?php } ?>
		</div>
		<?php
	}


	/**
	 * Load widget-specific scripts.
	 */
	public function widget_scripts() {
		$version_path = 'lite';
		$screen       = get_current_screen();

		if ( isset( $screen->id ) && 'dashboard' === $screen->id ) {
			$handle    = 'monsterinsights-vue3-widget';
			$entry_key = 'src/modules/widget/main.js';

			if ( ! defined( 'MONSTERINSIGHTS_V3_DEV_URL' ) || ! MONSTERINSIGHTS_V3_DEV_URL ) {
				MonsterInsights_Admin_Assets::enqueue_vue3_asset_css( $entry_key, 'monsterinsights-vue3-widget-style' );
			}

			if ( defined( 'MONSTERINSIGHTS_V3_DEV_URL' ) && MONSTERINSIGHTS_V3_DEV_URL ) {
				$widget_js_url = trailingslashit( MONSTERINSIGHTS_V3_DEV_URL ) . $entry_key;
			} else {
				$widget_js_url = MonsterInsights_Admin_Assets::get_vue3_asset_url( $entry_key );
			}

			if ( empty( $widget_js_url ) ) {
				return;
			}

			wp_register_script( $handle, $widget_js_url, array( 'wp-i18n', 'wp-util' ), monsterinsights_get_asset_version(), true );
			wp_enqueue_script( $handle );

			$plugins                = get_plugins();
			$wp_forms_url           = false;
			$wpforms_installed      = false;
			$userfeedback_url       = false;
			$userfeedback_installed = false;
			$formidableforms_installed = false;

			if ( monsterinsights_can_install_plugins() ) {
				$wpforms_key = 'wpforms-lite/wpforms.php';
				if ( array_key_exists( $wpforms_key, $plugins ) ) {
					$wp_forms_url      = wp_nonce_url( self_admin_url( 'plugins.php?action=activate&plugin=' . $wpforms_key ), 'activate-plugin_' . $wpforms_key );
					$wpforms_installed = true;
				} else {
					$wp_forms_url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=wpforms-lite' ), 'install-plugin_wpforms-lite' );
				}

				$userfeedback_keys     = array ( 'userfeedback-lite/userfeedback.php' => 1, 'userfeedback/userfeedback.php' => 2 );
				$userfeedback_versions = array_intersect_key($userfeedback_keys, $plugins);

				// Route both the Install and Activate CTAs to the in-plugin
				// UserFeedback screen, which walks the user through installing,
				// activating, and setup in one guided flow.
				$userfeedback_url = self_admin_url( 'admin.php?page=monsterinsights_settings#/userfeedback' );

				if ( ! empty( $userfeedback_versions ) ) {
					$userfeedback_installed = true;
				}

				if ( array_key_exists( 'formidable/formidable.php', $plugins ) ) {
					$formidableforms_installed = true;
				}
			}

			$auth      = MonsterInsights()->auth;
			$is_authed = ( $auth->is_authed() || $auth->is_network_authed() );

			$auth_data = array(
				'v4'                => $auth->get_v4_id(),
				'network_v4'        => is_multisite() ? $auth->get_network_v4_id() : '',
				'manual_v4'         => $auth->get_manual_v4_id(),
				'network_manual_v4' => is_multisite() ? $auth->get_network_manual_v4_id() : '',
				'viewname'          => $auth->get_viewname(),
				'network_viewname'  => is_multisite() ? $auth->get_network_viewname() : '',
			);

			$license_info = array(
				'key'         => '',
				'type'        => 'lite',
				'is_expired'  => false,
				'is_disabled' => false,
				'is_invalid'  => true,
				'is_agency'   => false,
			);

			$reporting_api = array(
				'url'      => apply_filters( 'monsterinsights_api_url_custom_dashboard', 'https://app.monsterinsights.com/' ),
				'license'  => '',
				'key'      => is_network_admin() ? $auth->get_network_key() : $auth->get_key(),
				'token'    => is_network_admin() ? $auth->get_network_token() : $auth->get_token(),
				'site_url' => is_network_admin() ? network_admin_url() : home_url(),
			);

			$bearer_token   = '';
			$bearer_expires = 0;
			if ( class_exists( 'MonsterInsights_API_Token' ) ) {
				$bearer_token_data = MonsterInsights_API_Token::get_token( is_network_admin() );
				if ( ! is_wp_error( $bearer_token_data ) ) {
					$bearer_token   = $bearer_token_data['token'];
					$bearer_expires = $bearer_token_data['expires_at'];
				}
			}

			wp_localize_script(
				$handle,
				'monsterinsights',
				apply_filters( 'monsterinsights_localize_script_data', array(
					'ajax'                      => admin_url( 'admin-ajax.php' ),
					'nonce'                     => wp_create_nonce( 'mi-admin-nonce' ),
					'network'                   => is_network_admin(),
					'assets_url'                => apply_filters( 'monsterinsights_vue3_assets_url', plugins_url( $version_path . '/assets/vue3', MONSTERINSIGHTS_PLUGIN_FILE ) ),
					'plugin_assets_url'         => plugins_url( 'assets/', MONSTERINSIGHTS_PLUGIN_FILE ),
					'shareasale_id'             => monsterinsights_get_shareasale_id(),
					'shareasale_url'            => monsterinsights_get_shareasale_url( monsterinsights_get_shareasale_id(), '' ),
					'addons_url'                => is_multisite() ? network_admin_url( 'admin.php?page=monsterinsights_network#/addons' ) : admin_url( 'admin.php?page=monsterinsights_settings#/addons' ),
					'widget_state'              => $this->get_options(),
					'wpforms_enabled'           => function_exists( 'wpforms' ),
					'wpforms_installed'         => $wpforms_installed,
					'wpforms_url'               => $wp_forms_url,
					'userfeedback_enabled'      => class_exists( 'UserFeedback_Base' ),
					'userfeedback_installed'    => $userfeedback_installed,
					'userfeedback_url'          => $userfeedback_url,
					'authed'                    => $is_authed,
					'can_view_reports'          => current_user_can( 'monsterinsights_view_dashboard' ),
					'versions'                  => monsterinsights_get_php_wp_version_warning_data(),
					'plugin_version'            => MONSTERINSIGHTS_VERSION,
					'is_admin'                  => true,
					'reports_url'               => add_query_arg( 'page', 'monsterinsights_reports', admin_url( 'admin.php' ) ),
					'overview_reports_url'      => add_query_arg( 'page', 'monsterinsights_overview_report', admin_url( 'admin.php' ) ),
					'getting_started_url'       => is_multisite() ? network_admin_url( 'admin.php?page=monsterinsights_network#/about/getting-started' ) : admin_url( 'admin.php?page=monsterinsights_settings#/about/getting-started' ),
					'wizard_url'                => monsterinsights_can_install_plugins() ? monsterinsights_get_onboarding_url() : '',
					'formidableforms_installed' => $formidableforms_installed,
					// Vue 3 reporting plumbing — same shape Custom Dashboard/Overview Reports use.
					'license'                   => $license_info,
					'auth'                      => $auth_data,
					'reporting_api'             => $reporting_api,
					'relay_api_url'             => apply_filters( 'monsterinsights_api_url_custom_dashboard', 'https://app.monsterinsights.com/' ),
					'bearer_token'              => $bearer_token,
					'bearer_expires'            => $bearer_expires,
					'sample_data_enabled'       => apply_filters( 'monsterinsights_sample_data_enabled', false ),
					// eCommerce store currency for widget value formatting; without this
					// the formatter falls back to USD (getMiGlobal('currency', 'USD')).
					'currency'                  => monsterinsights_get_ecommerce_currency(),
				) )
			);

			$this->remove_conflicting_asset_files();

			wp_set_script_translations( $handle, 'google-analytics-for-wordpress' );

			$text_domain = monsterinsights_get_plugin_textdomain();

			wp_scripts()->add_inline_script(
				$handle,
				monsterinsights_get_printable_translations( $text_domain ),
				'translation'
			);
		}
	}

	/**
	 * Remove assets added by other plugins which conflict.
	 */
	public function remove_conflicting_asset_files() {
		$scripts = array(
			'jetpack-onboarding-vendor', // Jetpack Onboarding Bluehost.
		);

		if ( ! empty( $scripts ) ) {
			foreach ( $scripts as $script ) {
				wp_dequeue_script( $script ); // Remove JS file.
				wp_deregister_script( $script );
			}
		}
	}

	/**
	 * Store the widget state in the db using an Ajax call.
	 */
	public function save_widget_state() {

		check_ajax_referer( 'mi-admin-nonce', 'nonce' );

		$default         = self::$default_options;
		$current_options = $this->get_options();

		$reports = $default['reports'];
		if ( isset( $_POST['reports'] ) ) {
			$reports = json_decode( sanitize_text_field( wp_unslash( $_POST['reports'] ) ), true );
		}

		$options = array(
			'width'       => ! empty( $_POST['width'] ) ? sanitize_text_field( wp_unslash( $_POST['width'] ) ) : $default['width'],
			'interval'    => ! empty( $_POST['interval'] ) ? absint( wp_unslash( $_POST['interval'] ) ) : $default['interval'],
			'compact'     => ! empty( $_POST['compact'] ) ? 'true' === sanitize_text_field( wp_unslash( $_POST['compact'] ) ) : $default['compact'],
			'reports'     => $reports,
			'notice30day' => $current_options['notice30day'],
		);

		array_walk( $options, 'sanitize_text_field' );
		update_user_meta( get_current_user_id(), 'monsterinsights_user_preferences', $options );

		wp_send_json_success();

	}

	/**
	 * Load & store the dashboard widget settings.
	 *
	 * @return array
	 */
	public function get_options() {
		if ( ! isset( $this->options ) ) {
			$this->options = self::wp_parse_args_recursive( get_user_meta( get_current_user_id(), 'monsterinsights_user_preferences', true ), self::$default_options );
		}

		// Set interval fixed to last30days on lite plugin.
		$this->options['interval'] = 'last30days';

		return apply_filters( 'monsterinsights_dashboard_widget_options', $this->options );

	}

	/**
	 * Recursive wp_parse_args.
	 *
	 * @param string|array|object $a Value to merge with $b.
	 * @param array $b The array with the default values.
	 *
	 * @return array
	 */
	public static function wp_parse_args_recursive( $a, $b ) {
		$a      = (array) $a;
		$b      = (array) $b;
		$result = $b;
		foreach ( $a as $k => &$v ) {
			if ( is_array( $v ) && isset( $result[ $k ] ) ) {
				$result[ $k ] = self::wp_parse_args_recursive( $v, $result[ $k ] );
			} else {
				$result[ $k ] = $v;
			}
		}

		return $result;
	}

	/**
	 * Reminder notice markup.
	 */
	public function load_notice() {

		$screen = get_current_screen();
		$tracking_id     = monsterinsights_get_v4_id();
		if ( isset( $screen->id ) && 'dashboard' === $screen->id && ! empty( $tracking_id ) ) {
			?>
			<div id="monsterinsights-reminder-notice"></div>
			<?php
		}

	}

	/**
	 * Mark notice as dismissed.
	 */
	public function mark_notice_closed() {

		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
		$options                = $this->get_options();
		$options['notice30day'] = time();
		update_user_meta( get_current_user_id(), 'monsterinsights_user_preferences', $options );

		wp_send_json_success();
	}
}
