<?php
if (!defined('ABSPATH')) {
	exit;
}

/********************************************************************
 * Copyright (C) 2025 Upvimeo.com (https://upvimeo.com)
 *
 * This file is part of Upvimeo
 *
 * Upvimeo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * Upvimeo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Upvimeo. If not, see <https://www.gnu.org/licenses/>.
 **********************************************************************/

/**
 * Class UpVimeo_Admin
 *
 * Main class for initializing the admin functionality
 *
 * @license GPLv2
 * @copyright Upvimeo.com (https://upvimeo.com)
 * @since 1.0.0
 */
class UpVimeo_Admin
{

	const PAGE_VIMEO = 'upvimeo-library';
	const PAGE_EDIT = 'upvimeo-editor';
	const PAGE_SETTINGS = 'upvimeo-settings';
	const PAGE_DOCUMENTATION = 'upvimeo-documentation';

	/**
	 * @var UpVimeo_Settings_Helper
	 */
	public $settings_helper;

	/**
	 * The vimeo api helper
	 * @var UpVimeo_Api_Helper
	 */
	public $api_helper = null;

	/**
	 * The database helper
	 * @var null
	 */
	public $db_helper = null;

	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string $plugin_name The ID of this plugin.
	 */
	private $plugin_name;

	/**
	 * The version of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string $version The current version of this plugin.
	 */
	private $version;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @param string $plugin_name The name of this plugin.
	 * @param string $version The version of this plugin.
	 *
	 * @since    1.0.0
	 */
	public function __construct($plugin_name, $version)
	{
		$this->plugin_name = $plugin_name;
		$this->version = $version;
		$this->api_helper = new UpVimeo_Api_Helper();
		$this->db_helper = new UpVimeo_Db_Helper();
		$this->settings_helper = new UpVimeo_Settings_Helper();

		// Prevent Freemius from adding unwanted submenus at the source
		add_filter('upvimeo_is_submenu_visible', array($this, 'filter_freemius_submenus'), 10, 2);
	}

	/**
	 * Register the stylesheets for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_styles()
	{
		// Critical Conflict Fix: Do NOT load our main admin CSS on Freemius native pages (Pricing/Account)
		// This prevents layout breakage on the Checkout page
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['page']) && in_array(sanitize_text_field(wp_unslash($_GET['page'])), array('upvimeo-library-pricing', 'upvimeo-library-account'))) {
			// Ensure basic WP styles are there if needed, but skip ours
			return;
		}

		wp_enqueue_style('upvimeo-admin');
	}

	/**
	 * Register the JavaScript for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_scripts()
	{


		// Critical Fix: Prevent loading general admin scripts on Tutor LMS Course Builder
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['page']) && sanitize_text_field(wp_unslash($_GET['page'])) === 'create-course') {
			return;
		}


		// ---------------------------------------------------------
		// Elementor Safety Guard
		// ---------------------------------------------------------
		// Elementor's visual editor can get stuck in an infinite loading loop if our scripts conflict.
		// We detect if we are in Elementor's edit mode and bail out early.
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$is_elementor_preview = isset($_GET['elementor-preview']);
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$is_elementor_action = isset($_GET['action']) && sanitize_text_field(wp_unslash($_GET['action'])) === 'elementor';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$is_elementor_ajax = isset($_REQUEST['action']) && sanitize_text_field(wp_unslash($_REQUEST['action'])) === 'elementor_ajax';
		$is_elementor_editor_mode = false;

		// Check strictly if the class exists to avoid fatal errors
		if (defined('ELEMENTOR_VERSION') && class_exists('\Elementor\Plugin')) {
			if (\Elementor\Plugin::$instance->editor->is_edit_mode()) {
				$is_elementor_editor_mode = true;
			}
		}

		if ($is_elementor_preview || $is_elementor_action || $is_elementor_editor_mode || $is_elementor_ajax) {
			return;
		}

		// Validate the current screen
		if ( ! function_exists( 'get_current_screen' ) ) {
			require_once ABSPATH . 'wp-admin/includes/screen.php';
		}
		$current_screen = get_current_screen();
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$is_edit_screen = isset($_GET['post']) && is_numeric(sanitize_text_field(wp_unslash($_GET['post'])));
		$is_create_screen = $current_screen && $current_screen->action === 'add' && $current_screen->base === 'post';
		$is_nav_menu_screen = $current_screen && $current_screen->base === 'nav-menus';
		$is_widget_screen = $current_screen && $current_screen->base === 'widgets';
		$is_gutenberg_active = upvimeo_is_gutenberg_active();
		$is_create_or_edit_screen = $is_create_screen || $is_edit_screen || $is_nav_menu_screen || $is_widget_screen || $current_screen->base === 'upload';


		// Only load if on Upvimeo pages OR content creation/upload screens
		// Native Freemius pages will handle their own scripts, so we don't need to check for them here explicitly for our own scripts
		if (!$this->is_any_page() && !$is_create_or_edit_screen) {
			return;
		}

		// Conflict Fix: Do NOT load our scripts on Freemius native pages (Pricing/Account) as they might have JS conflicts
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['page']) && in_array(sanitize_text_field(wp_unslash($_GET['page'])), array('upvimeo-library-pricing', 'upvimeo-library-account'))) {
			// Ensure jQuery and Postbox are loaded for Freemius checks
			wp_enqueue_script('jquery');
			wp_enqueue_script('postbox');
			return;
		}

		// Sweet alert
		$this->enqueue_sweetalert();

		// Uploader
		$this->enqueue_vimeo_uploader();
		$this->enqueue_vimeo_upload_modal();

		// Admin
		$this->enqueue_admin_scripts();

		// Add dynamic inline styles and scripts previously from hook_admin_head_style
		$css_data = '
			#toplevel_page_upvimeo-library .wp-menu-image img,
			#toplevel_page_upvimeo .wp-menu-image img {
				padding-top: 0 !important;
				margin: 8px auto 0 auto !important; /* Vertically centered */
				width: auto !important;
				height: auto !important;
				max-width: 24px !important;
				max-height: 20px !important;
				opacity: 1 !important;
				display: block !important;
				transition: filter 0.2s ease;
			}
			#toplevel_page_upvimeo-library:hover .wp-menu-image img,
			#toplevel_page_upvimeo:hover .wp-menu-image img {
				/* Filter to turn white into #00adef (Vimeo Blue-ish) */
				filter: brightness(0) saturate(100%) invert(56%) sepia(39%) saturate(4978%) hue-rotate(167deg) brightness(101%) contrast(102%) !important;
			}
			#toplevel_page_upvimeo-library .wp-menu-image,
			#toplevel_page_upvimeo .wp-menu-image {
				width: 36px !important;
				text-align: center;
				overflow: visible !important;
			}
			/* Custom Style for the Upgrade menu item */
			li.wp-has-submenu ul.wp-submenu li a[href*="page=upvimeo-library-pricing"],
			li.wp-has-submenu ul.wp-submenu li a[href*="page=upvimeo-pricing"] {
				color: #2271b1 !important;
				font-weight: bold !important;
			}
			
			/* VISUAL HACK: Hide Duplicate Freemius Menus */
			/* We use a robust selector to find links to the auto-generated pages */
			li.wp-has-submenu ul.wp-submenu li a[href*="page=upvimeo-library-contact"],
			li.wp-has-submenu ul.wp-submenu li a[href*="page=upvimeo-library-support"],
			li.wp-has-submenu ul.wp-submenu li a[href*="page=upvimeo-library-pricing"] {
				display: none !important;
			}
		';
		wp_add_inline_style('upvimeo-admin', $css_data);

		$hide_upsell_tabs = function_exists('upvimeo_fs') && upvimeo_fs()->is_paying();
		if ( function_exists('upvimeo_fs') && upvimeo_fs()->is__premium_only() ) {
			if (defined('UPVIMEO_IS_PRO') && UPVIMEO_IS_PRO) {
				$hide_upsell_tabs = true;
			}
		}

		$bad_slugs = array(
			'page=upvimeo-library-contact',
			'page=upvimeo-library-support',
			'page=upvimeo-library-pricing'
		);

		$js_data = '
		jQuery(document).ready(function($){
			var badSlugs = ' . wp_json_encode($bad_slugs) . ';
			$(".wp-submenu li").each(function(){
				var $link = $(this).find("a");
				var href = $link.attr("href");
				if(href) {
					for(var i=0; i<badSlugs.length; i++) {
						if(href.indexOf(badSlugs[i]) !== -1) {
							// Check if this is also NOT one of our allowed custom pages?
							// Our custom pages are: upvimeo-account (NO library in slug)
							// So searching for "upvimeo-library-account" is SAFE.
							$(this).addClass("upvimeo-hidden-duplicate").hide();
							$(this).css("display", "none !important");
						}
					}
				}
			});
			
			// Fix Freemius trial banner links
			$("a[href*=\'page=upvimeo-library-pricing\']").attr("href", function(i, h) {
				return h.replace("page=upvimeo-library-pricing", "page=upvimeo-pricing");
			});
		});';
		wp_add_inline_script('upvimeo-admin', $js_data, 'after');

		if ($is_gutenberg_active && $is_create_or_edit_screen) {
			$this->enqueue_gutenberg_block();
			wp_enqueue_style('upvimeo-dropzone');
		}
	}

	/**
	 * Enqueue Sweet alert
	 */
	public function enqueue_sweetalert()
	{
		wp_enqueue_script('upvimeo-swal');
	}

	/**
	 * Enqueue Vimeo Uploader
	 */
	public function enqueue_vimeo_uploader()
	{
		wp_enqueue_script('upvimeo-tus');
		wp_enqueue_script('upvimeo-uploader');
	}

	/**
	 * Enqueue the Upload modal
	 */
	public function enqueue_vimeo_upload_modal()
	{
		wp_enqueue_script('upvimeo-upload-modal');
		wp_enqueue_style('upvimeo-upload-modal');
	}

	/**
	 * Enqueue gutenberg block
	 */
	public function enqueue_gutenberg_block()
	{


		$current_user_uploads = !current_user_can('administrator') && (int) $this->settings_helper->get('upvimeo_local_current_user_only');

		if (is_null($this->db_helper)) {
			$this->db_helper = new UpVimeo_Db_Helper();
		}

		$uploads = ($this->db_helper instanceof UpVimeo_Db_Helper) ? $this->db_helper->get_uploaded_videos($current_user_uploads) : array();

		wp_enqueue_script('wvv-vimeo-upload-block');
		wp_localize_script('wvv-vimeo-upload-block', 'UPVIMEO_GTB', array(
			'nonce' => wp_create_nonce('upvimeo_ajax_nonce'),
			'icon_url' => UPVIMEO_URL . 'assets/images/branding/upv-icon-blue.png',
			'enable_vimeo_search' => $this->settings_helper->get('upvimeo_gtb_enable_account_search'),
			'default_privacy' => $this->settings_helper->get_default_admin_view_privacy(),
			'ajax_url' => admin_url('admin-ajax.php'),
			'uploads' => $uploads,
			'methods' => upvimeo_get_editor_insert_methods(),
			'words' => array(
				'block_name' => esc_html__('UpVimeo', 'upvimeo-direct-uploads'),
				'title' => esc_html__('Title', 'upvimeo-direct-uploads'),
				'desc' => esc_html__('Description', 'upvimeo-direct-uploads'),
				'file' => esc_html__('File', 'upvimeo-direct-uploads'),
				'uploading3d' => esc_html__('Uploading...', 'upvimeo-direct-uploads'),
				'upload' => esc_html__('Upload', 'upvimeo-direct-uploads'),
				'search' => esc_html__('Search', 'upvimeo-direct-uploads'),
				'sorry' => esc_html__('Sorry', 'upvimeo-direct-uploads'),
				'privacy_view' => esc_html__('Who can view this video?', 'upvimeo-direct-uploads'),
			),
			'phrases' => array(
				'upload_invalid_file' => esc_html__('Please select valid video file.', 'upvimeo-direct-uploads'),
				'invalid_search_phrase' => esc_html__('Invalid search phrase. Please enter valid search phrase.', 'upvimeo-direct-uploads'),
				'enter_phrase' => esc_html__('Enter phrase', 'upvimeo-direct-uploads'),
				'select_video' => esc_html__('Select video', 'upvimeo-direct-uploads'),
				'upload_success' => esc_html__('Video uploaded successfully!', 'upvimeo-direct-uploads'),
				'block_title' => esc_html__('Insert Vimeo Video', 'upvimeo-direct-uploads'),
				'existing_not_visible_current_user' => esc_html__('= Uploaded by someone else, not visible to you =', 'upvimeo-direct-uploads')
			),
			'upload_form_options' => array(
				'enable_privacy_option' => (int) $this->settings_helper->get('upvimeo_enable_privacy_option_gt', 0),
				'privacy_view' => $this->api_helper->get_view_privacy_options_for_forms('admin'),
			)
		));

		wp_enqueue_style('wvv-vimeo-upload-block');
		wp_enqueue_style('upvimeo-dropzone');
	}

	/**
	 * Enqueue admin scripts
	 */
	public function enqueue_admin_scripts()
	{
		// Only enqueue on Upvimeo pages
		if (!$this->is_any_page()) {
			return;
		}

		if (!wp_script_is('select2', 'enqueued')) {
			wp_enqueue_script('upvimeo-select2');
		}
		if (!wp_style_is('select2', 'enqueued')) {
			wp_enqueue_style('upvimeo-select2');
		}


		wp_enqueue_script('upvimeo-admin');

		wp_localize_script('upvimeo-admin', 'upvimeo_vars', array(
			'nonce' => wp_create_nonce('upvimeo_ajax_nonce'),
		));

		wp_localize_script('upvimeo-admin', 'upvimeo', array(
			'nonce' => wp_create_nonce('upvimeo_ajax_nonce'),
			'ajax_url' => admin_url('admin-ajax.php'),
			'default_privacy' => $this->settings_helper->get_default_admin_view_privacy(),
			'sorry' => esc_html__('Sorry', 'upvimeo-direct-uploads'),
			'upload_invalid_file' => esc_html__('Please select valid video file.', 'upvimeo-direct-uploads'),
			'delete_not_allowed' => esc_html__('Delete is not allowed because your account doesn\'t have the correct delete scope required by Vimeo.', 'upvimeo-direct-uploads'),
			'delete_confirm_title' => esc_html__('Are you sure?', 'upvimeo-direct-uploads'),
			'delete_confirm_desc' => esc_html__('Are you sure you want to delete this video? This action deletes the video from the Vimeo and can not be reversed.', 'upvimeo-direct-uploads'),
			'delete_whitelist_domain_error' => esc_html__('Sorry, the domain could not be deleted.', 'upvimeo-direct-uploads'),
			'http_error' => esc_html__('Sorry there was a HTTP error. Please check the server logs or contact support.', 'upvimeo-direct-uploads'),
			'success' => esc_html__('Success', 'upvimeo-direct-uploads'),
			'cancel' => esc_html__('Cancel', 'upvimeo-direct-uploads'),
			'confirm' => esc_html__('Confirm', 'upvimeo-direct-uploads'),
			'close' => esc_html__('Close', 'upvimeo-direct-uploads'),
			'remove_lower' => esc_html__('remove', 'upvimeo-direct-uploads'),
			'delete_confirmation' => esc_html__('Are you sure you want to delete this video?', 'upvimeo-direct-uploads'),
			'delete_confirmation_yes' => esc_html__('Yes, please', 'upvimeo-direct-uploads'),
			'title' => esc_html__('Title', 'upvimeo-direct-uploads'),
			'description' => esc_html__('Description', 'upvimeo-direct-uploads'),
			'upload' => esc_html__('Upload', 'upvimeo-direct-uploads'),
			'upload_to_vimeo' => esc_html__('Upload to vimeo', 'upvimeo-direct-uploads'),
			'correct_errors' => esc_html__('Please correct the following errors', 'upvimeo-direct-uploads'),
			'privacy_view' => esc_html__('Who can view this video?', 'upvimeo-direct-uploads'),
			'problem_solution' => esc_html__('Problem solution', 'upvimeo-direct-uploads'),
			'loading' => esc_html__('Loading...', 'upvimeo-direct-uploads'),
			'stats' => esc_html__('Statistics', 'upvimeo-direct-uploads'),
			'explanation' => esc_html__('Explanation', 'upvimeo-direct-uploads'),
			'upload_form_options' => array(
				'enable_privacy_option' => (int) $this->settings_helper->get('upvimeo_enable_privacy_option_media', 0),
				'privacy_view' => $this->api_helper->get_view_privacy_options_for_forms('admin'),
			)
		));
	}

	/**
	 * Register the admin menus
	 *
	 * @since 1.0.0
	 */
	public function register_admin_menu()
	{
		add_menu_page(
			esc_html__('Upvimeo', 'upvimeo-direct-uploads'),
			esc_html__('Upvimeo', 'upvimeo-direct-uploads'),
			'upload_files',
			self::PAGE_VIMEO,
			array(
				$this,
				'render_vimeo_page'
			),
			'data:image/svg+xml;base64, ',
			85
		);

		add_submenu_page(
			self::PAGE_VIMEO,
			esc_html__('Manage Videos', 'upvimeo-direct-uploads'),
			esc_html__('Manage Videos', 'upvimeo-direct-uploads'),
			'upload_files',
			self::PAGE_VIMEO,
			array(
				$this,
				'render_vimeo_page'
			)
		);

		add_submenu_page(
			self::PAGE_VIMEO,
			esc_html__('Video Editor', 'upvimeo-direct-uploads'),
			esc_html__('Video Editor', 'upvimeo-direct-uploads'),
			'upload_files',
			self::PAGE_EDIT,
			array(
				$this,
				'render_editor_page'
			)
		);

		add_submenu_page(
			self::PAGE_VIMEO,
			esc_html__('Vimeo Settings', 'upvimeo-direct-uploads'),
			esc_html__('Settings', 'upvimeo-direct-uploads'),
			apply_filters('UPVIMEO_manage_options_capability', 'manage_options'),
			self::PAGE_SETTINGS,
			array(
				$this,
				'render_settings_page'
			)
		);

		add_submenu_page(
			self::PAGE_VIMEO,
			esc_html__('Upvimeo Documentation', 'upvimeo-direct-uploads'),
			esc_html__('Documentation', 'upvimeo-direct-uploads'),
			apply_filters('UPVIMEO_manage_options_capability', 'manage_options'),
			self::PAGE_DOCUMENTATION,
			array(
				$this,
				'render_documentation_page'
			)
		);
	}

	public function remove_freemius_menus()
	{
		global $submenu;

		if (!isset($submenu[self::PAGE_VIMEO]) || !is_array($submenu[self::PAGE_VIMEO])) {
			return;
		}

		$parent_slug = self::PAGE_VIMEO;

		// Whitelist of allowed custom slugs
		$allowed_slugs = array(
			self::PAGE_VIMEO, // The main page itself
			'upvimeo-library',
			'upvimeo-editor',
			'upvimeo-settings',
			'upvimeo-documentation',
			'upvimeo-account', // Our manual account page
			'upvimeo-pricing', // Our manual pricing page
		);


		if (!isset($submenu[$parent_slug]) || !is_array($submenu[$parent_slug])) {
			return;
		}

		// Check if we are Pro or Free to decide visibility
		// WE CONSIDER 'PAYING' USERS AS PRO FOR MENU PURPOSES (Hiding Upgrade)
		// even if files are missing (handled by notice)
		$hide_upsell_tabs = false;
		if (function_exists('upvimeo_fs') && upvimeo_fs()->is_paying()) {
			$hide_upsell_tabs = true;
		}
		if ( function_exists('upvimeo_fs') && upvimeo_fs()->is__premium_only() ) {
			if ( defined('UPVIMEO_IS_PRO') && UPVIMEO_IS_PRO ) {
				$hide_upsell_tabs = true;
			}
		}

		$pricing_found = false;

		foreach ($submenu[$parent_slug] as $index => $item) {
			$slug = $item[2];

			// If the slug is in our whitelist, keep it.
			if (in_array($slug, $allowed_slugs)) {
				continue;
			}

			// Freemius native slugs are usually:
			// upvimeo-library-pricing
			// upvimeo-library-account

			// Rename 'Upgrade' to 'Upgrade to Pro'
			if (strpos($slug, 'pricing') !== false) {
				$pricing_found = true;
				if ($hide_upsell_tabs) {
					// Hide Upgrade menu if Pro is active
					// We DO NOT unset it because that breaks access to the page (e.g. Change Plan button).
					// We will hide it via CSS/JS instead in hook_admin_head_style.
					// unset($submenu[$parent_slug][$index]);
				} else {
					// We DO NOT unset the native Freemius pricing page here because unsetting it from $submenu 
					// causes a 403 error when accessing the Trial banner link. We hide it via CSS/JS instead.
					// unset($submenu[$parent_slug][$index]);

					// Add our own custom pricing page using a fresh slug 'upvimeo-pricing'
					if ( is_admin() && current_user_can( apply_filters('UPVIMEO_manage_options_capability', 'manage_options') ) ) {
						add_submenu_page(
							self::PAGE_VIMEO,
							esc_html__('Upgrade to Pro', 'upvimeo-direct-uploads'),
							esc_html__('Upgrade &rarr;', 'upvimeo-direct-uploads'),
							apply_filters('UPVIMEO_manage_options_capability', 'manage_options'),
							'upvimeo-pricing',
							array($this, 'render_custom_pricing_page')
						);
					}
				}
				continue;
			}

			// Handle Account menu
			if (strpos($slug, 'account') !== false) {
				if (!$hide_upsell_tabs) {
					// Hide Account menu if Free (optional, but requested logic was to show Upgrade for Free)
					// Actually, Freemius might show Account for Free users too (profile), but user wanted distinct logic.
					// Let's stick strictly to user's previous logic: PRO=Account, FREE=Upgrade
					unset($submenu[$parent_slug][$index]);
				}
				continue;
			}

			// Hide other Freemius menus we don't want (Contact, Support) if they appear
			if (strpos($slug, 'contact') !== false || strpos($slug, 'support') !== false) {
				unset($submenu[$parent_slug][$index]);
			}
		}

		// Fallback: If Free version and Pricing menu NOT found (Freemius didn't add it for some reason), add it manually pointing to FS Upgrade URL
		if (!$hide_upsell_tabs && !$pricing_found) {
			// use a dynamic URL if possible, otherwise use the pricing page slug
			if ( is_admin() && current_user_can( apply_filters('UPVIMEO_manage_options_capability', 'manage_options') ) ) {
				add_submenu_page(
					self::PAGE_VIMEO,
					esc_html__('Upgrade to Pro', 'upvimeo-direct-uploads'),
					esc_html__('Upgrade &rarr;', 'upvimeo-direct-uploads'),
					apply_filters('UPVIMEO_manage_options_capability', 'manage_options'),
					'upvimeo-pricing',
					array($this, 'render_custom_pricing_page')
				);
			}
		}
	}

	/**
	 * Renders the upgrade page (Pricing)
	 */
	public function render_upgrade_page()
	{
		if (function_exists('upvimeo_fs')) {
			if (method_exists(upvimeo_fs(), '_pricing_page_render')) {
				upvimeo_fs()->_pricing_page_render();
			} else {
				// Fallback to redirect if method missing
				$url = upvimeo_fs()->get_upgrade_url();
				wp_enqueue_script('upvimeo-admin');
				wp_add_inline_script('upvimeo-admin', 'window.location.href="' . esc_url($url) . '";');
				/* translators: %s: URL to the pricing page */
				/* translators: %s: [URL address] */
				echo '<div class="wrap"><h1>' . esc_html__('Redirecting to Pricing...', 'upvimeo-direct-uploads') . '</h1><p>' . wp_kses_post(sprintf(__('If you are not redirected, <a href="%s" target="_blank">click here</a>.', 'upvimeo-direct-uploads'), esc_url($url))) . '</p></div>';
			}
		}
	}

	/**
	 * Get allowed HTML for admin forms
	 *
	 * @return array
	 */
	private function get_allowed_html() {
		return array_merge( wp_kses_allowed_html( 'post' ), array(
			'form'     => array( 'id' => true, 'class' => true, 'action' => true, 'method' => true, 'enctype' => true, 'name' => true ),
			'input'    => array( 'id' => true, 'class' => true, 'type' => true, 'name' => true, 'value' => true, 'placeholder' => true, 'checked' => true, 'disabled' => true, 'readonly' => true, 'required' => true, 'accept' => true, 'min' => true, 'max' => true, 'step' => true ),
			'select'   => array( 'id' => true, 'class' => true, 'name' => true, 'multiple' => true, 'disabled' => true, 'required' => true, 'data-action' => true, 'data-placeholder' => true ),
			'option'   => array( 'value' => true, 'selected' => true, 'disabled' => true ),
			'button'   => array( 'id' => true, 'class' => true, 'type' => true, 'name' => true, 'value' => true, 'disabled' => true ),
			'label'    => array( 'for' => true, 'class' => true ),
			'textarea' => array( 'id' => true, 'class' => true, 'name' => true, 'rows' => true, 'cols' => true, 'placeholder' => true, 'disabled' => true, 'readonly' => true, 'required' => true ),
			'a'        => array( 'href' => true, 'class' => true, 'id' => true, 'target' => true, 'rel' => true, 'onclick' => true, 'data-info' => true, 'style' => true, 'title' => true ),
			'div'      => array( 'class' => true, 'id' => true, 'style' => true, 'title' => true ),
			'span'     => array( 'class' => true, 'id' => true, 'style' => true, 'title' => true ),
			'iframe'   => array( 'src' => true, 'width' => true, 'height' => true, 'frameborder' => true, 'allow' => true, 'allowfullscreen' => true, 'title' => true, 'class' => true, 'id' => true ),
			'svg'      => array( 'class' => true, 'aria-hidden' => true, 'aria-labelledby' => true, 'role' => true, 'xmlns' => true, 'width' => true, 'height' => true, 'viewBox' => true, 'fill' => true ),
			'path'     => array( 'd' => true, 'fill' => true, 'fill-rule' => true ),
		) );
	}

	/**
	 * Renders our custom pricing page dynamically fetching SDK plans
	 */
	public function render_custom_pricing_page()
	{
		echo wp_kses( upvimeo_get_view('admin/partials/pricing', array()), $this->get_allowed_html() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	/**
	 * Renders the license page (Freemius Account)
	 */
	public function render_license_page()
	{
		if (function_exists('upvimeo_fs')) {
			upvimeo_fs()->_account_page_render();
		} else {
			echo '<div class="wrap"><h1>' . esc_html__('License', 'upvimeo-direct-uploads') . '</h1><p>' . esc_html__('Freemius SDK not initialized.', 'upvimeo-direct-uploads') . '</p></div>';
		}
	}

	/**
	 * Renders the vimeo pages
	 */
	public function render_vimeo_page()
	{
		echo wp_kses(upvimeo_get_view('admin/partials/library', array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			'upvimeo_helper' => $this->api_helper,
			'db_helper' => $this->db_helper,
			'settings_helper' => $this->settings_helper,
		)), $this->get_allowed_html());
	}

	/**
	 * Renders the editor page
	 */
	public function render_editor_page()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (!isset($_GET['id'])) {
			/* translators: %s: URL to Manage Videos page */
			/* translators: %s: [Link path] */
			echo '<div class="wrap"><h1>' . esc_html__('Video Editor', 'upvimeo-direct-uploads') . '</h1><p>' . wp_kses_post(sprintf(__('Please select a video from the <a href="%s">Manage Videos</a> page to edit.', 'upvimeo-direct-uploads'), 'admin.php?page=upvimeo-library')) . '</p></div>';
			return;
		}

		echo wp_kses( upvimeo_get_view('admin/partials/library-edit', array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			'upvimeo_helper' => $this->api_helper,
			'db_helper' => $this->db_helper,
			'settings_helper' => $this->settings_helper,
		)), $this->get_allowed_html() );
	}

	/**
	 * Unset third party notices.
	 */
	public function do_admin_notices()
	{
		if ($this->is_any_page()) {
			\remove_all_actions('admin_notices');
		}

		// Suppress Freemius trial promotional notice entirely for the free version
		if ( function_exists('upvimeo_fs') && ! upvimeo_fs()->is_paying() ) {
			if ( class_exists('FS_Admin_Notice_Manager') ) {
				$fs_notice_manager = FS_Admin_Notice_Manager::instance( 'upvimeo' );
				if ( $fs_notice_manager ) {
					remove_action( 'admin_notices', array( $fs_notice_manager, 'admin_notices' ) );
					remove_action( 'network_admin_notices', array( $fs_notice_manager, 'admin_notices' ) );
				}
			}
		}

		// Check for Pro Files Missing state
		if ( function_exists('upvimeo_fs') && upvimeo_fs()->is__premium_only() ) {
			if (function_exists('upvimeo_fs') && upvimeo_fs()->is_paying()) {
				if (!defined('UPVIMEO_IS_PRO') || !UPVIMEO_IS_PRO) {
					echo '<div class="notice notice-error"><p>' .
						wp_kses_post(__('<strong>Upvimeo Attention:</strong> You have an active Pro license, but the Pro plugin files are missing. You may be running the Free version codebase. Please download and install the distinct <strong>Upvimeo Pro</strong> plugin from the <a href="https://upvimeo.com/account" target="_blank">client dashboard</a> or Freemius account to unlock all features.', 'upvimeo-direct-uploads')) .
						'</p></div>';
				}
			}
		}

		do_action('UPVIMEO_admin_notices');
		$this->instructions();
	}

	/**
	 * Renders the settings page
	 */
	public function render_settings_page()
	{
		echo wp_kses( upvimeo_get_view('admin/partials/settings', array( // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			'upvimeo_helper' => $this->api_helper,
			'db_helper' => $this->db_helper,
			'settings_helper' => $this->settings_helper,
		)), $this->get_allowed_html() );
	}

	/**
	 * Renders the documentation page
	 */
	public function render_documentation_page()
	{
		echo wp_kses( upvimeo_get_view('admin/partials/documentation', array()), $this->get_allowed_html() ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
	}

	/**
	 * Registers the Media Library Integration Button
	 */
	public function register_media_library_upload_metabox()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['post']) && 'attachment' === get_post_type(absint(sanitize_text_field(wp_unslash($_GET['post']))))) {
			add_meta_box(
				// phpcs:ignore WordPress.Security.NonceVerification.Recommended
				'upvimeo_info_metabox_' . absint(sanitize_text_field(wp_unslash($_GET['post']))),
				esc_html__('WP Vimeo', 'upvimeo-direct-uploads'),
				array($this, 'render_media_library_upload_metabox'),
				null,
				'side'
			);
		}
		// phpcs:enable
	}

	/**
	 * Renders the Media Library Integration Button
	 */
	public function render_media_library_upload_metabox()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$attachment_id = isset($_GET['post']) ? absint(sanitize_text_field(wp_unslash($_GET['post']))) : null;
		if (!is_null($attachment_id) && 'attachment' === get_post_type($attachment_id)) {
			echo '<div id="upvimeo-mlmb-' . esc_attr($attachment_id) . '">';
			echo wp_kses(upvimeo_render_media_library_upload_buttons($attachment_id), $this->get_allowed_html()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Content is safe HTML generated by helper function.
			echo '</div>';
		}
	}

	/**
	 * Add WP Vimeo in the Media Library table
	 *
	 * @param $columns
	 *
	 * @return mixed
	 */
	public function manage_media_columns($columns)
	{
		if ($this->api_helper->is_connected) {
			$columns['upvimeo_info'] = esc_html__('WP Vimeo', 'upvimeo-direct-uploads');
		}

		return $columns;
	}

	/**
	 * Render WP Vimeo in the Media Library table
	 *
	 * @param $column_name
	 * @param $attachment_id
	 */
	public function manage_media_custom_column($column_name, $attachment_id)
	{
		if ($this->api_helper->is_connected) {
			switch ($column_name) {
				case 'upvimeo_info':
					echo '<div id="upvimeo-mlmb-' . esc_attr($attachment_id) . '">';
					echo wp_kses(upvimeo_render_media_library_upload_buttons($attachment_id), $this->get_allowed_html()); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Content is safe HTML generated by helper function.
					echo '</div>';
					break;
			}
		}
	}

	/**
	 * Add instructions view
	 */
	public function instructions()
	{
		if (!current_user_can('install_plugins')) {
			return;
		}

		// Verify dismiss
		$dismiss_key = 'upvimeo_instructions_dismissed';
		// phpcs:disable WordPress.Security.NonceVerification.Recommended
		if (isset($_GET['upvimeo_dismiss_instructions']) && isset($_GET['upvimeo_nonce'])) {
			if (wp_verify_nonce(sanitize_text_field(wp_unslash($_GET['upvimeo_nonce'])), 'upvimeo_instructions_dismiss')) {
				update_option($dismiss_key, 1);
			}
		}
		// Render if not dismissed.
		$instructions_hidden = get_option($dismiss_key);
		if (!$instructions_hidden || empty($instructions_hidden) || intval($instructions_hidden) !== 1) {
			$disallowed = array('upvimeo-library-pricing', 'upvimeo-library-account');
			$page = isset($_GET['page']) ? sanitize_text_field(wp_unslash($_GET['page'])) : null;
			if (!in_array($page, $disallowed)) {
				include UPVIMEO_PATH . '/admin/partials/instructions.php';
			}
		}
		// phpcs:enable
	}

	/**
	 * Add a link to the settings page on the plugins.php page.
	 *
	 * @param array $links List of existing plugin action links.
	 *
	 * @return array         List of modified plugin action links.
	 *
	 */
	public function plugin_action_links($links)
	{
		$new_links = array();

		// Check if Freemius is loaded
		if (function_exists('upvimeo_fs')) {
			if (upvimeo_fs()->can_use_premium_code()) {
				// Pro Active: Show Account Link
				$new_links[] = '<a href="' . esc_url(upvimeo_fs()->get_account_url()) . '">' . esc_html__('Account', 'upvimeo-direct-uploads') . '</a>';
			} else {
				// Free: Show Upgrade Link
				$upgrade_url = upvimeo_fs()->get_upgrade_url();
				$new_links[] = '<a href="' . esc_url($upgrade_url) . '" style="color:#2271b1;font-weight:bold;" target="_blank">' . esc_html__('Upgrade to Pro', 'upvimeo-direct-uploads') . '</a>';
			}
		}

		$new_links[] = '<a href="' . esc_url(admin_url('admin.php?page=upvimeo-settings')) . '">' . esc_html__(
			'Settings',
			'upvimeo-direct-uploads'
		) . '</a>';

		return array_merge($new_links, $links);
	}

	/**
	 * Is any page?
	 * @return bool
	 */
	public function is_any_page()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		return is_admin() && isset($_GET['page']) && in_array(sanitize_text_field(wp_unslash($_GET['page'])), array(
			self::PAGE_VIMEO,
			self::PAGE_EDIT,
			self::PAGE_SETTINGS,
			self::PAGE_DOCUMENTATION,
			'upvimeo-library-pricing', // Add naive slugs
			'upvimeo-library-account'
		));
	}

	/**
	 * Is the list page?
	 * @return bool
	 */
	public function is_list_page()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		return $this->is_any_page() && !isset($_GET['action']);
	}

	/**
	 * Is the edit page?
	 * @return bool
	 */
	public function is_edit_page()
	{
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		return $this->is_any_page() && isset($_GET['page']) && sanitize_text_field(wp_unslash($_GET['page'])) === self::PAGE_EDIT;
	}

	/**
	 * Hook to print styles in the admin head (Globally)
	 * Fixes the menu icon size on pages where the main stylesheet isn't loaded.
	 */
	public function hook_admin_head_style()
	{
		// ---------------------------------------------------------
		// Elementor Safety Guard
		// ---------------------------------------------------------
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$is_elementor_preview = isset($_GET['elementor-preview']);
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$is_elementor_action = isset($_GET['action']) && sanitize_text_field(wp_unslash($_GET['action'])) === 'elementor';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$is_elementor_ajax = isset($_REQUEST['action']) && sanitize_text_field(wp_unslash($_REQUEST['action'])) === 'elementor_ajax';
		$is_elementor_editor_mode = false;

		if (defined('ELEMENTOR_VERSION') && class_exists('\Elementor\Plugin')) {
			if (\Elementor\Plugin::$instance->editor->is_edit_mode()) {
				$is_elementor_editor_mode = true;
			}
		}

		if ($is_elementor_preview || $is_elementor_action || $is_elementor_editor_mode || $is_elementor_ajax) {
			return;
		}
	}
}
