<?php
/**
 * Admin UI: full-bleed product pages (Zen Plugins admin design system).
 *
 * @package RedirectZen
 */

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

class RDZ_Admin {

	const CAPABILITY = 'manage_options';

	/**
	 * Task rows that can be hidden (per user).
	 *
	 * @var string[]
	 */
	public static $dismissible_tasks = array( 'newsletter', 'review', 'firstredirect', 'regex', 'import' );

	/**
	 * Hooks.
	 */
	public static function init() {
		add_action( 'admin_menu', array( __CLASS__, 'register_menu' ) );
		add_action( 'admin_init', array( __CLASS__, 'maybe_activation_redirect' ) );
		add_action( 'admin_init', array( __CLASS__, 'maybe_sdk_pricing_redirect' ) );
		add_action( 'admin_init', array( __CLASS__, 'register_settings' ) );
		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );
		add_action( 'admin_post_rdz_verify_all', array( __CLASS__, 'handle_verify_all' ) );
		add_action( 'admin_post_rdz_add_redirect', array( __CLASS__, 'handle_add_redirect' ) );
		add_action( 'admin_post_rdz_restore_backup', array( __CLASS__, 'handle_restore_backup' ) );
		add_action( 'load-toplevel_page_redirectzen', array( __CLASS__, 'handle_redirect_bulk_actions' ) );
		add_filter( 'set-screen-option', array( __CLASS__, 'save_screen_option' ), 10, 3 );
	}

	/**
	 * Right after single-plugin activation, send the user to the dashboard.
	 */
	/**
	 * The Freemius SDK registers a hidden "{slug}-pricing" page even with
	 * the pricing menu disabled, and it serves the SDK's stock pricing
	 * template — subscription-era FAQ boilerplate included. Every path to
	 * it lands on our upgrade page instead.
	 */
	public static function maybe_sdk_pricing_redirect() {
		if ( isset( $_GET['page'] ) && 'redirectzen-pricing' === $_GET['page'] && current_user_can( self::CAPABILITY ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			wp_safe_redirect( admin_url( 'admin.php?page=redirectzen-upgrade' ) );
			exit;
		}
	}

	public static function maybe_activation_redirect() {
		if ( ! get_transient( 'rdz_activation_redirect' ) ) {
			return;
		}
		delete_transient( 'rdz_activation_redirect' );

		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}
		if ( isset( $_GET['activate-multi'] ) || is_network_admin() || wp_doing_ajax() ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}

		wp_safe_redirect( admin_url( 'admin.php?page=redirectzen' ) );
		exit;
	}

	/**
	 * Registers the admin menu.
	 */
	public static function register_menu() {
		$counts = RDZ_Redirects::get_counts();
		$badge  = $counts['fail'] > 0
			? ' <span class="awaiting-mod count-' . (int) $counts['fail'] . '"><span class="pending-count">' . number_format_i18n( $counts['fail'] ) . '</span></span>'
			: '';

		$dashboard_hook = add_menu_page(
			__( 'RedirectZen — Redirect Health', 'redirectzen-301-redirect-manager' ),
			__( 'RedirectZen', 'redirectzen-301-redirect-manager' ) . $badge,
			self::CAPABILITY,
			'redirectzen',
			array( __CLASS__, 'render_dashboard' ),
			'dashicons-randomize',
			80
		);

		add_submenu_page( 'redirectzen', __( 'Redirects', 'redirectzen-301-redirect-manager' ), __( 'Redirects', 'redirectzen-301-redirect-manager' ), self::CAPABILITY, 'redirectzen', array( __CLASS__, 'render_dashboard' ) );
		$log_hook      = add_submenu_page( 'redirectzen', __( '404 Log', 'redirectzen-301-redirect-manager' ), __( '404 Log', 'redirectzen-301-redirect-manager' ), self::CAPABILITY, 'redirectzen-404s', array( __CLASS__, 'render_404s' ) );
		$import_hook   = add_submenu_page( 'redirectzen', __( 'Import & Export', 'redirectzen-301-redirect-manager' ), __( 'Import & Export', 'redirectzen-301-redirect-manager' ), self::CAPABILITY, 'redirectzen-import', array( __CLASS__, 'render_import' ) );
		$settings_hook = add_submenu_page( 'redirectzen', __( 'RedirectZen Settings', 'redirectzen-301-redirect-manager' ), __( 'Settings', 'redirectzen-301-redirect-manager' ), self::CAPABILITY, 'redirectzen-settings', array( __CLASS__, 'render_settings' ) );
		$pricing_hook  = add_submenu_page( 'redirectzen', __( 'RedirectZen Pro', 'redirectzen-301-redirect-manager' ), __( 'Upgrade', 'redirectzen-301-redirect-manager' ), self::CAPABILITY, 'redirectzen-upgrade', array( __CLASS__, 'render_pricing' ) );
		$contact_hook  = add_submenu_page( 'redirectzen', __( 'Contact', 'redirectzen-301-redirect-manager' ), __( 'Contact', 'redirectzen-301-redirect-manager' ), self::CAPABILITY, 'redirectzen-support', array( __CLASS__, 'render_contact' ) );

		add_action( "load-{$dashboard_hook}", array( __CLASS__, 'add_redirects_screen_options' ) );
		add_action( "load-{$log_hook}", array( __CLASS__, 'add_404s_screen_options' ) );
		add_action( "load-{$log_hook}", array( __CLASS__, 'handle_404_bulk_actions' ) );

		foreach ( array( $dashboard_hook, $log_hook, $import_hook, $settings_hook, $pricing_hook, $contact_hook ) as $hook ) {
			add_action( "load-{$hook}", array( __CLASS__, 'prepare_zen_page' ) );
		}
	}

	/**
	 * Full-bleed treatment: our pages own their canvas. Third-party admin
	 * notices are removed on RedirectZen screens only (RedirectZen itself
	 * never adds admin-wide notices anywhere).
	 */
	public static function prepare_zen_page() {
		remove_all_actions( 'admin_notices' );
		remove_all_actions( 'all_admin_notices' );
		add_filter(
			'admin_body_class',
			static function ( $classes ) {
				return $classes . ' rdz-zen';
			}
		);
	}

	/**
	 * Screen options.
	 */
	public static function add_redirects_screen_options() {
		add_screen_option( 'per_page', array( 'label' => __( 'Redirects per page', 'redirectzen-301-redirect-manager' ), 'default' => 25, 'option' => 'rdz_redirects_per_page' ) );
	}

	public static function add_404s_screen_options() {
		add_screen_option( 'per_page', array( 'label' => __( '404s per page', 'redirectzen-301-redirect-manager' ), 'default' => 25, 'option' => 'rdz_404s_per_page' ) );
	}

	/**
	 * Persists per-page screen options.
	 *
	 * @param mixed  $status Default.
	 * @param string $option Option name.
	 * @param mixed  $value  Submitted value.
	 * @return mixed
	 */
	public static function save_screen_option( $status, $option, $value ) {
		if ( in_array( $option, array( 'rdz_redirects_per_page', 'rdz_404s_per_page' ), true ) ) {
			return max( 1, min( 200, absint( $value ) ) );
		}

		return $status;
	}

	/**
	 * Registers the settings option.
	 */
	public static function register_settings() {
		register_setting(
			'rdz_settings_group',
			RDZ_Settings::OPTION_KEY,
			array(
				'type'              => 'array',
				'sanitize_callback' => array( 'RDZ_Settings', 'sanitize' ),
				'default'           => RDZ_Settings::defaults(),
			)
		);
	}

	/**
	 * Enqueues admin assets on RedirectZen pages only.
	 *
	 * @param string $hook_suffix Current admin page.
	 */
	public static function enqueue_assets( $hook_suffix ) {
		if ( false === strpos( (string) $hook_suffix, 'redirectzen' ) ) {
			return;
		}

		wp_enqueue_style( 'zen-admin', RDZ_PLUGIN_URL . 'assets/css/zen-admin.css', array(), RDZ_VERSION );
		wp_enqueue_style( 'rdz-admin', RDZ_PLUGIN_URL . 'assets/css/admin.css', array( 'zen-admin' ), RDZ_VERSION );
		wp_enqueue_script( 'rdz-admin', RDZ_PLUGIN_URL . 'assets/js/admin.js', array( 'jquery' ), RDZ_VERSION, true );

		wp_localize_script(
			'rdz-admin',
			'rdzAdmin',
			array(
				'ajaxUrl' => admin_url( 'admin-ajax.php' ),
				'nonce'   => wp_create_nonce( 'rdz_admin_nonce' ),
				'i18n'    => array(
					'confirmDelete' => __( 'Delete this redirect? Anyone visiting the old URL will see a 404 again.', 'redirectzen-301-redirect-manager' ),
					'confirmBulk'   => __( 'Delete the selected redirects? Their old URLs will 404 again.', 'redirectzen-301-redirect-manager' ),
					'ignored'       => __( '404 ignored — it will stay out of your open list.', 'redirectzen-301-redirect-manager' ),
					'disabled'      => __( 'Redirect disabled.', 'redirectzen-301-redirect-manager' ),
					'undo'          => __( 'Undo', 'redirectzen-301-redirect-manager' ),
					'working'       => __( 'Working…', 'redirectzen-301-redirect-manager' ),
					'verifying'     => __( 'Verifying…', 'redirectzen-301-redirect-manager' ),
					'error'         => __( 'Something went wrong. Please try again.', 'redirectzen-301-redirect-manager' ),
					'redirectMade'  => __( 'Redirect created and queued for verification.', 'redirectzen-301-redirect-manager' ),
					'noSuggestions' => __( 'No close matches found.', 'redirectzen-301-redirect-manager' ),
				),
			)
		);
	}

	/**
	 * "Verify all" button handler.
	 */
	public static function handle_verify_all() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			wp_die( esc_html__( 'You are not allowed to do that.', 'redirectzen-301-redirect-manager' ) );
		}
		check_admin_referer( 'rdz_verify_all' );

		RDZ_Verifier::queue_all();
		spawn_cron();

		wp_safe_redirect( add_query_arg( 'rdz_notice', 'verify_queued', admin_url( 'admin.php?page=redirectzen' ) ) );
		exit;
	}

	/**
	 * Add-redirect form handler (dashboard card).
	 */
	public static function handle_add_redirect() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			wp_die( esc_html__( 'You are not allowed to do that.', 'redirectzen-301-redirect-manager' ) );
		}
		check_admin_referer( 'rdz_add_redirect' );

		$source = isset( $_POST['rdz_source'] ) ? sanitize_text_field( wp_unslash( $_POST['rdz_source'] ) ) : '';
		$target = isset( $_POST['rdz_target'] ) ? sanitize_text_field( wp_unslash( $_POST['rdz_target'] ) ) : '';
		$type   = isset( $_POST['rdz_type'] ) ? absint( $_POST['rdz_type'] ) : 301;
		$regex  = ! empty( $_POST['rdz_regex'] ) && rdz_can_use_premium();

		$result = RDZ_Redirects::add_rule( $source, $target, $type, array( 'is_regex' => $regex ) );

		if ( is_wp_error( $result ) ) {
			$args = array( 'rdz_notice' => $result->get_error_code() );
		} else {
			RDZ_Redirects::record_user_fix();
			RDZ_404_Log::resolve_matching( $result['source'] );
			spawn_cron();
			$args = array( 'rdz_notice' => ( 'chain' === $result['chain'] ) ? 'redirect_added_chain' : 'redirect_added' );
		}

		wp_safe_redirect( add_query_arg( $args, admin_url( 'admin.php?page=redirectzen' ) ) );
		exit;
	}

	/**
	 * Backup restore handler.
	 */
	public static function handle_restore_backup() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			wp_die( esc_html__( 'You are not allowed to do that.', 'redirectzen-301-redirect-manager' ) );
		}

		$id = isset( $_GET['backup_id'] ) ? absint( $_GET['backup_id'] ) : 0;
		check_admin_referer( 'rdz_restore_backup_' . $id );

		$result = RDZ_Backups::restore( $id );
		$args   = is_wp_error( $result )
			? array( 'rdz_notice' => $result->get_error_code() )
			: array( 'rdz_notice' => 'restore_done', 'restored' => (int) $result );

		wp_safe_redirect( add_query_arg( array_merge( array( 'page' => 'redirectzen-import' ), $args ), admin_url( 'admin.php' ) ) );
		exit;
	}

	/**
	 * Redirects-table bulk actions.
	 */
	public static function handle_redirect_bulk_actions() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}

		$action = self::current_bulk_action();
		if ( ! $action || ! in_array( $action, array( 'verify', 'activate', 'deactivate', 'delete' ), true ) ) {
			return;
		}

		check_admin_referer( 'bulk-rdz_redirects' );

		$ids = isset( $_REQUEST['redirect_ids'] ) ? array_map( 'absint', (array) $_REQUEST['redirect_ids'] ) : array();
		$ids = array_slice( array_filter( $ids ), 0, 200 );
		if ( empty( $ids ) ) {
			return;
		}

		$done = 0;
		if ( 'delete' === $action ) {
			RDZ_Backups::snapshot( __( 'Before bulk delete', 'redirectzen-301-redirect-manager' ) );
			$done = RDZ_Redirects::delete_rules( $ids );
		} else {
			foreach ( $ids as $id ) {
				if ( 'verify' === $action ) {
					$result = RDZ_Redirects::update_rule( $id, array() );
					if ( $result && ! is_wp_error( $result ) ) {
						global $wpdb;
						$wpdb->update( RDZ_Redirects::table(), array( 'verify_status' => 'queued' ), array( 'id' => $id ), array( '%s' ), array( '%d' ) );
						$done++;
					}
				} else {
					$result = RDZ_Redirects::update_rule( $id, array( 'is_active' => ( 'activate' === $action ) ? 1 : 0 ) );
					if ( ! is_wp_error( $result ) ) {
						$done++;
					}
				}
			}
			if ( 'verify' === $action ) {
				spawn_cron();
			}
		}

		wp_safe_redirect(
			add_query_arg(
				array( 'page' => 'redirectzen', 'rdz_notice' => 'bulk_done', 'rdz_count' => $done ),
				admin_url( 'admin.php' )
			)
		);
		exit;
	}

	/**
	 * 404-table bulk actions.
	 */
	public static function handle_404_bulk_actions() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}

		$action = self::current_bulk_action();
		if ( ! $action || ! in_array( $action, array( 'ignore', 'delete' ), true ) ) {
			return;
		}

		check_admin_referer( 'bulk-rdz_404s' );

		$ids = isset( $_REQUEST['log_ids'] ) ? array_map( 'absint', (array) $_REQUEST['log_ids'] ) : array();
		$ids = array_slice( array_filter( $ids ), 0, 200 );
		if ( empty( $ids ) ) {
			return;
		}

		$done = 0;
		if ( 'delete' === $action ) {
			$done = RDZ_404_Log::delete_rows( $ids );
		} else {
			foreach ( $ids as $id ) {
				if ( RDZ_404_Log::set_status( $id, 1 ) ) {
					$done++;
				}
			}
		}

		wp_safe_redirect(
			add_query_arg(
				array( 'page' => 'redirectzen-404s', 'rdz_notice' => 'bulk_done', 'rdz_count' => $done ),
				admin_url( 'admin.php' )
			)
		);
		exit;
	}

	/**
	 * Reads the submitted bulk action, if any.
	 *
	 * @return string
	 */
	private static function current_bulk_action() {
		foreach ( array( 'action', 'action2' ) as $key ) {
			if ( isset( $_REQUEST[ $key ] ) && '-1' !== $_REQUEST[ $key ] ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
				return sanitize_key( wp_unslash( $_REQUEST[ $key ] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			}
		}

		return '';
	}

	/**
	 * The Zen Plugins top bar (lockup, tabs, docs, Go Pro).
	 *
	 * @param string $active dashboard|log|import|settings|pricing|contact.
	 */
	private static function render_topbar( $active ) {
		$docs_base = apply_filters( 'rdz_docs_base', 'https://redirectzen.com/docs/' );
		$tabs      = array(
			'dashboard' => array( admin_url( 'admin.php?page=redirectzen' ), __( 'Redirects', 'redirectzen-301-redirect-manager' ) ),
			'log'       => array( admin_url( 'admin.php?page=redirectzen-404s' ), __( '404 Log', 'redirectzen-301-redirect-manager' ) ),
			'import'    => array( admin_url( 'admin.php?page=redirectzen-import' ), __( 'Import & Export', 'redirectzen-301-redirect-manager' ) ),
			'settings'  => array( admin_url( 'admin.php?page=redirectzen-settings' ), __( 'Settings', 'redirectzen-301-redirect-manager' ) ),
		);
		?>
		<header class="zen-topbar">
			<div class="zen-lockup">
				<svg width="26" height="26" viewBox="0 0 48 48" aria-hidden="true"><defs><linearGradient id="rdz-lockup-grad" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#34D399"/><stop offset="1" stop-color="#059669"/></linearGradient></defs><circle cx="24" cy="24" r="19" fill="none" stroke="url(#rdz-lockup-grad)" stroke-width="3" stroke-linecap="round" stroke-dasharray="98.2 21.2" transform="rotate(120 24 24)"/><path d="M15 20 h12 a5 5 0 0 1 0 10 h-4" fill="none" stroke="#1B1620" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/><path d="M26.5 26.5 L23 30 l3.5 3.5" fill="none" stroke="#1B1620" stroke-width="2.8" stroke-linecap="round" stroke-linejoin="round"/></svg>
				<span>RedirectZen</span>
			</div>
			<nav class="zen-tabs" aria-label="<?php esc_attr_e( 'RedirectZen sections', 'redirectzen-301-redirect-manager' ); ?>">
				<?php foreach ( $tabs as $key => $tab ) : ?>
					<a class="zen-tab<?php echo $key === $active ? ' is-active' : ''; ?>" <?php echo $key === $active ? 'aria-current="page"' : ''; ?> href="<?php echo esc_url( $tab[0] ); ?>"><?php echo esc_html( $tab[1] ); ?></a>
				<?php endforeach; ?>
			</nav>
			<div class="zen-topbar-actions">
				<a class="zen-doclink" href="<?php echo esc_url( $docs_base ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Documentation', 'redirectzen-301-redirect-manager' ); ?></a>
				<?php if ( ! rdz_can_use_premium() ) : ?>
					<a class="zen-btn zen-btn--primary zen-btn--pro" href="<?php echo esc_url( self::upgrade_url() ); ?>" aria-label="<?php esc_attr_e( 'Go Pro — redirects that fix themselves', 'redirectzen-301-redirect-manager' ); ?>"><span class="zen-pro-main"><?php esc_html_e( 'Go Pro', 'redirectzen-301-redirect-manager' ); ?></span><span class="zen-pro-sub"><?php esc_html_e( 'Redirects that fix themselves', 'redirectzen-301-redirect-manager' ); ?></span></a>
				<?php endif; ?>
			</div>
		</header>
		<?php
	}

	/**
	 * Admin notices for our own pages (inline, never admin-wide).
	 *
	 * @param string $context dashboard|log|import.
	 */
	private static function render_notices( $context ) {
		$notice = isset( $_GET['rdz_notice'] ) ? sanitize_key( wp_unslash( $_GET['rdz_notice'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( ! $notice ) {
			return;
		}

		$count    = isset( $_GET['rdz_count'] ) ? absint( $_GET['rdz_count'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$messages = array(
			'verify_queued'        => array( 'success', __( 'Verification queued. RedirectZen checks each redirect end-to-end in background batches — results appear within minutes.', 'redirectzen-301-redirect-manager' ) ),
			'redirect_added'       => array( 'success', __( 'Redirect saved and queued for verification.', 'redirectzen-301-redirect-manager' ) ),
			'redirect_added_chain' => array( 'warning', __( 'Redirect saved — but its target is itself redirected. It works, though pointing straight at the final page would be faster and better for SEO.', 'redirectzen-301-redirect-manager' ) ),
			/* translators: %d: number of rows. */
			'bulk_done'            => array( 'success', sprintf( __( '%d items processed.', 'redirectzen-301-redirect-manager' ), $count ) ),
			'rdz_bad_source'       => array( 'error', __( 'Please enter a valid source URL or path.', 'redirectzen-301-redirect-manager' ) ),
			'rdz_bad_target'       => array( 'error', __( 'Please enter a valid target URL or path.', 'redirectzen-301-redirect-manager' ) ),
			'rdz_bad_regex'        => array( 'error', __( 'That regular expression does not compile.', 'redirectzen-301-redirect-manager' ) ),
			'rdz_duplicate'        => array( 'error', __( 'A redirect for this source already exists.', 'redirectzen-301-redirect-manager' ) ),
			'rdz_loop'             => array( 'error', __( 'Not saved: this redirect would create a loop. Loops take sites down — RedirectZen checks before saving.', 'redirectzen-301-redirect-manager' ) ),
			'rdz_db_error'         => array( 'error', __( 'Could not save the redirect rule.', 'redirectzen-301-redirect-manager' ) ),
			'rdz_no_backup'        => array( 'error', __( 'Backup not found.', 'redirectzen-301-redirect-manager' ) ),
			'rdz_bad_backup'       => array( 'error', __( 'This backup could not be read.', 'redirectzen-301-redirect-manager' ) ),
		);

		if ( 'restore_done' === $notice ) {
			$restored = isset( $_GET['restored'] ) ? absint( $_GET['restored'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			/* translators: %d: number of redirects restored. */
			$messages['restore_done'] = array( 'success', sprintf( __( 'Backup restored — %d redirects are live again.', 'redirectzen-301-redirect-manager' ), $restored ) );
		}
		if ( 'import_done' === $notice || 'csv_done' === $notice ) {
			$imported = isset( $_GET['imported'] ) ? absint( $_GET['imported'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$skipped  = isset( $_GET['skipped'] ) ? absint( $_GET['skipped'] ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			/* translators: 1: imported count, 2: skipped count. */
			$text = sprintf( __( 'Import finished: %1$d redirects imported, %2$d skipped (duplicates, wildcards or invalid rows). All imported redirects are queued for verification — in a few minutes you\'ll KNOW they work.', 'redirectzen-301-redirect-manager' ), $imported, $skipped );
			if ( isset( $_GET['error'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
				$text = __( 'Import failed: the file was missing, unreadable or empty.', 'redirectzen-301-redirect-manager' );
				$messages[ $notice ] = array( 'error', $text );
			} else {
				$messages[ $notice ] = array( 'success', $text );
			}
		}

		if ( isset( $messages[ $notice ] ) ) {
			printf(
				'<div class="notice notice-%1$s rdz-own"><p>%2$s</p></div>',
				esc_attr( $messages[ $notice ][0] ),
				esc_html( $messages[ $notice ][1] )
			);
		}
	}

	/**
	 * Renders the dashboard page.
	 */
	public static function render_dashboard() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}

		$counts     = RDZ_Redirects::get_counts();
		$log_counts = RDZ_404_Log::get_counts();
		$last       = (int) get_option( 'rdz_last_verify_cycle', 0 );
		$frequency  = class_exists( 'RDZ_Pro_Schedule' ) && rdz_can_use_premium() ? RDZ_Pro_Schedule::interval_seconds( RDZ_Settings::get( 'verify_schedule' ) ) : 0;
		$grade      = RDZ_Grade::compute( $counts, $last, $frequency, time() );
		$tone       = RDZ_Grade::tone( $grade );

		$table = new RDZ_Redirects_Table();
		$table->prepare_items();
		?>
		<div class="zen-admin zen-shell rdz-wrap">
			<?php self::render_topbar( 'dashboard' ); ?>
			<h1 class="zen-sr-only"><?php esc_html_e( 'RedirectZen dashboard', 'redirectzen-301-redirect-manager' ); ?></h1>
			<hr class="wp-header-end" style="display:none" />

			<div class="zen-layout">
				<main class="zen-main">
					<?php self::render_notices( 'dashboard' ); ?>
					<?php $review_ask_up = self::render_grade_card( $grade, $tone, $counts, $log_counts, $last ); ?>
					<?php self::render_issues_card( $counts, $log_counts ); ?>
					<?php self::render_add_card(); ?>

					<section class="zen-card zen-table-card" aria-label="<?php esc_attr_e( 'Redirects', 'redirectzen-301-redirect-manager' ); ?>">
						<form method="get">
							<input type="hidden" name="page" value="redirectzen" />
							<?php
							$table->views();
							$table->search_box( __( 'Search redirects', 'redirectzen-301-redirect-manager' ), 'rdz-search' );
							$table->display();
							?>
						</form>
					</section>
					<?php if ( ! $review_ask_up ) : // Politeness queue: never two review asks on one screen. ?>
						<p class="zen-footer-ask zen-footer-ask--muted"><?php esc_html_e( 'Enjoying RedirectZen?', 'redirectzen-301-redirect-manager' ); ?> <a href="https://wordpress.org/support/plugin/redirectzen-301-redirect-manager/reviews/#new-post" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Leave a review', 'redirectzen-301-redirect-manager' ); ?></a></p>
					<?php endif; ?>
				</main>

				<aside class="zen-side">
					<?php self::render_checklist_card( $counts, $log_counts ); ?>
					<?php self::render_zen_family_card(); ?>
					<?php self::render_optin_card(); ?>
					<?php self::render_tips_card(); ?>
				</aside>
			</div>
		</div>
		<?php
	}

	/**
	 * The Redirect Health grade card.
	 *
	 * @param string $grade      Letter or 'pending'.
	 * @param string $tone       good|warn|bad|pending.
	 * @param array  $counts     Redirect verify counts.
	 * @param array  $log_counts 404 counts.
	 * @param int    $last       Last verify-cycle timestamp.
	 * @return bool Whether a review ask was rendered (politeness queue:
	 *              the caller must not show another ask on this screen).
	 */
	private static function render_grade_card( $grade, $tone, $counts, $log_counts, $last ) {
		$letter = 'pending' === $grade ? '…' : $grade;

		if ( 'pending' === $grade ) {
			$headline = $counts['total'] ? __( 'First verification in progress', 'redirectzen-301-redirect-manager' ) : __( 'Add or import your first redirect', 'redirectzen-301-redirect-manager' );
			$sub      = $counts['total']
				? __( 'RedirectZen is requesting each redirect end-to-end in the background. Your grade appears here shortly.', 'redirectzen-301-redirect-manager' )
				: __( 'Every redirect you add is verified end-to-end — you\'ll never wonder whether they actually work.', 'redirectzen-301-redirect-manager' );
		} elseif ( 'good' === $tone ) {
			$headline = __( 'Your redirects are verified and working', 'redirectzen-301-redirect-manager' );
			$sub      = __( 'Every rule was requested end-to-end and landed on a working page. No silent failures here.', 'redirectzen-301-redirect-manager' );
		} elseif ( 'warn' === $tone ) {
			$headline = __( 'A few redirects need attention', 'redirectzen-301-redirect-manager' );
			$sub      = __( 'Fix the failing rules below to bring your grade back up.', 'redirectzen-301-redirect-manager' );
		} else {
			$headline = __( 'Redirects on this site are silently failing', 'redirectzen-301-redirect-manager' );
			$sub      = __( 'Visitors following old links are hitting dead ends right now. The list below shows exactly which rules are broken.', 'redirectzen-301-redirect-manager' );
		}

		if ( $counts['queued'] > 0 ) {
			$verified_chip = __( 'Verification running now', 'redirectzen-301-redirect-manager' );
		} elseif ( $last ) {
			/* translators: %s: human-readable time difference. */
			$verified_chip = sprintf( __( 'Verified %s ago', 'redirectzen-301-redirect-manager' ), human_time_diff( $last, time() ) );
		} else {
			$verified_chip = __( 'Not verified yet', 'redirectzen-301-redirect-manager' );
		}

		$first_redirect = get_option( 'rdz_first_redirect_at' ) && ! in_array( 'firstredirect', self::hidden_tasks(), true );

		// One-time review ask when the grade improves (dismiss persists).
		$improvement = null;
		if ( 'pending' !== $grade ) {
			$order = array_flip( RDZ_Grade::LETTERS );
			$prev  = get_option( 'rdz_last_grade', '' );
			if ( $prev && $prev !== $grade && isset( $order[ $prev ], $order[ $grade ] ) && $order[ $grade ] < $order[ $prev ] ) {
				update_option( 'rdz_grade_improvement', array( 'from' => $prev, 'to' => $grade ), false );
			}
			if ( $prev !== $grade ) {
				update_option( 'rdz_last_grade', $grade, false );
			}
			$stored = get_option( 'rdz_grade_improvement' );
			if ( is_array( $stored ) && isset( $stored['to'] ) && $stored['to'] === $grade && ! in_array( 'review', self::hidden_tasks(), true ) ) {
				$improvement = $stored;
			}
		}
		?>
		<section class="zen-card zen-grade zen-grade--<?php echo esc_attr( $tone ); ?>" aria-label="<?php esc_attr_e( 'Redirect health grade', 'redirectzen-301-redirect-manager' ); ?>">
			<div class="zen-grade-panel"><div class="zen-grade-letter" role="img" aria-label="<?php echo esc_attr( sprintf( /* translators: %s: letter grade. */ __( 'Redirect health grade: %s', 'redirectzen-301-redirect-manager' ), $letter ) ); ?>"><?php echo esc_html( $letter ); ?></div></div>
			<div class="zen-grade-body">
				<h2><?php echo esc_html( $headline ); ?></h2>
				<p><?php echo esc_html( $sub ); ?></p>
				<div class="zen-stats">
					<div class="zen-stat <?php echo $counts['fail'] ? 'zen-stat--bad' : 'zen-stat--ok'; ?>"><span class="zen-stat-n"><?php echo esc_html( number_format_i18n( $counts['fail'] ) ); ?></span><span class="zen-stat-l"><?php esc_html_e( 'failing', 'redirectzen-301-redirect-manager' ); ?></span></div>
					<div class="zen-stat <?php echo $counts['warn'] ? 'zen-stat--warn' : 'zen-stat--ok'; ?>"><span class="zen-stat-n"><?php echo esc_html( number_format_i18n( $counts['warn'] ) ); ?></span><span class="zen-stat-l"><?php esc_html_e( 'fragile', 'redirectzen-301-redirect-manager' ); ?></span></div>
					<div class="zen-stat zen-stat--ok"><span class="zen-stat-n"><?php echo esc_html( number_format_i18n( $counts['ok'] ) ); ?></span><span class="zen-stat-l"><?php esc_html_e( 'verified working', 'redirectzen-301-redirect-manager' ); ?></span></div>
					<div class="zen-stat <?php echo $log_counts['open'] ? 'zen-stat--warn' : 'zen-stat--ok'; ?>"><span class="zen-stat-n"><?php echo esc_html( number_format_i18n( $log_counts['open'] ) ); ?></span><span class="zen-stat-l"><?php esc_html_e( 'open 404s', 'redirectzen-301-redirect-manager' ); ?></span></div>
					<div class="zen-stat"><span class="zen-stat-n">⏱</span><span class="zen-stat-l"><?php echo esc_html( $verified_chip ); ?></span></div>
				</div>
				<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="display:inline-block">
					<input type="hidden" name="action" value="rdz_verify_all" />
					<?php wp_nonce_field( 'rdz_verify_all' ); ?>
					<button type="submit" class="zen-btn zen-btn--dark" <?php disabled( ! $counts['total'] ); ?>><?php esc_html_e( 'Verify all now', 'redirectzen-301-redirect-manager' ); ?></button>
				</form>
				<a class="zen-grade-doclink" href="<?php echo esc_url( apply_filters( 'rdz_docs_base', 'https://redirectzen.com/docs/' ) . '#grade' ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'What does my grade mean?', 'redirectzen-301-redirect-manager' ); ?></a>
				<?php $show_first_fix = $first_redirect && ! $improvement && 'pending' !== $grade; ?>
				<?php if ( $show_first_fix ) : ?>
					<p class="zen-review-ask">
						<?php esc_html_e( 'That old URL now lands somewhere useful — for your visitors and for Google. We\'re a tiny team and RedirectZen is free; if it just saved you time, a ★★★★★ review genuinely keeps it alive →', 'redirectzen-301-redirect-manager' ); ?>
						<a href="https://wordpress.org/support/plugin/redirectzen-301-redirect-manager/reviews/#new-post" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Review on WordPress.org', 'redirectzen-301-redirect-manager' ); ?></a>
						<button type="button" class="zen-hide-task" data-task="firstredirect" aria-label="<?php esc_attr_e( 'Dismiss', 'redirectzen-301-redirect-manager' ); ?>">&times;</button>
					</p>
				<?php endif; ?>
				<?php if ( $improvement ) : ?>
					<p class="zen-review-ask">
						<?php echo esc_html( sprintf( /* translators: 1: old grade, 2: new grade. */ __( 'Your grade just went from %1$s to %2$s 🎉 We put a lot of love into this free plugin — if it\'s earned it,', 'redirectzen-301-redirect-manager' ), $improvement['from'], $improvement['to'] ) ); ?>
						<a href="https://wordpress.org/support/plugin/redirectzen-301-redirect-manager/reviews/#new-post" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'a 5-star review means the world → ★', 'redirectzen-301-redirect-manager' ); ?></a>
						<button type="button" class="zen-hide-task" data-task="review" aria-label="<?php esc_attr_e( 'Dismiss', 'redirectzen-301-redirect-manager' ); ?>">&times;</button>
					</p>
				<?php endif; ?>
			</div>
		</section>
		<?php
		return $show_first_fix || null !== $improvement;
	}

	/**
	 * The issues card: what needs attention, grouped by severity.
	 *
	 * @param array $counts     Redirect verify counts.
	 * @param array $log_counts 404 counts.
	 */
	private static function render_issues_card( $counts, $log_counts ) {
		$base = admin_url( 'admin.php?page=redirectzen' );

		$groups = array(
			array(
				'count' => $counts['fail'],
				'label' => __( 'Failing redirects — the old URL still dead-ends', 'redirectzen-301-redirect-manager' ),
				'sev'   => 'red',
				'view'  => add_query_arg( 'rdz_status', 'fail', $base ),
			),
			array(
				'count' => $counts['warn'],
				'label' => __( 'Fragile redirects — chains or unexpected destinations', 'redirectzen-301-redirect-manager' ),
				'sev'   => 'amber',
				'view'  => add_query_arg( 'rdz_status', 'warn', $base ),
			),
			array(
				'count' => $log_counts['open'],
				'label' => __( 'Open 404s without a redirect', 'redirectzen-301-redirect-manager' ),
				'sev'   => 'amber',
				'view'  => admin_url( 'admin.php?page=redirectzen-404s' ),
			),
		);

		$has_issues = false;
		foreach ( $groups as $group ) {
			if ( $group['count'] > 0 ) {
				$has_issues = true;
				break;
			}
		}
		?>
		<section class="zen-card" aria-label="<?php esc_attr_e( 'Issues', 'redirectzen-301-redirect-manager' ); ?>">
			<h2><?php esc_html_e( 'Issues', 'redirectzen-301-redirect-manager' ); ?></h2>
			<p class="zen-card-sub"><?php esc_html_e( 'What verification found, grouped by severity.', 'redirectzen-301-redirect-manager' ); ?></p>
			<div class="zen-issues">
				<?php if ( ! $has_issues ) : ?>
					<div class="zen-issue">
						<span class="zen-sev zen-sev--done"><?php esc_html_e( 'Clear', 'redirectzen-301-redirect-manager' ); ?></span>
						<span class="zen-issue-label"><?php esc_html_e( 'No issues found — your redirects check out.', 'redirectzen-301-redirect-manager' ); ?></span>
					</div>
				<?php endif; ?>

				<?php foreach ( $groups as $group ) : ?>
					<?php if ( $group['count'] < 1 ) { continue; } ?>
					<div class="zen-issue">
						<span class="zen-sev zen-sev--<?php echo esc_attr( $group['sev'] ); ?>"><?php echo 'red' === $group['sev'] ? esc_html__( 'Broken', 'redirectzen-301-redirect-manager' ) : esc_html__( 'Warning', 'redirectzen-301-redirect-manager' ); ?></span>
						<span class="zen-issue-label"><?php echo esc_html( $group['label'] ); ?></span>
						<span class="zen-count"><?php echo esc_html( number_format_i18n( $group['count'] ) ); ?></span>
						<span class="zen-issue-actions"><a href="<?php echo esc_url( $group['view'] ); ?>"><?php esc_html_e( 'View', 'redirectzen-301-redirect-manager' ); ?></a></span>
					</div>
				<?php endforeach; ?>
			</div>
		</section>
		<?php
	}

	/**
	 * The add-redirect card.
	 */
	private static function render_add_card() {
		$is_premium = rdz_can_use_premium();
		?>
		<section class="zen-card" aria-label="<?php esc_attr_e( 'Add redirect', 'redirectzen-301-redirect-manager' ); ?>">
			<h2><?php esc_html_e( 'Add redirect', 'redirectzen-301-redirect-manager' ); ?></h2>
			<p class="zen-card-sub"><?php esc_html_e( 'Loops are blocked before they can take your site down, and every rule is verified right after saving.', 'redirectzen-301-redirect-manager' ); ?></p>
			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" class="rdz-add-form">
				<input type="hidden" name="action" value="rdz_add_redirect" />
				<?php wp_nonce_field( 'rdz_add_redirect' ); ?>
				<div class="rdz-add-row">
					<input type="text" name="rdz_source" class="regular-text code" placeholder="/old-page/" aria-label="<?php esc_attr_e( 'Source URL or path', 'redirectzen-301-redirect-manager' ); ?>" required />
					<span class="rdz-arrow" aria-hidden="true">→</span>
					<input type="text" name="rdz_target" class="regular-text code" placeholder="https://… <?php esc_attr_e( 'or', 'redirectzen-301-redirect-manager' ); ?> /new-page/" aria-label="<?php esc_attr_e( 'Target URL or path', 'redirectzen-301-redirect-manager' ); ?>" required />
					<select name="rdz_type" aria-label="<?php esc_attr_e( 'Redirect type', 'redirectzen-301-redirect-manager' ); ?>">
						<option value="301"><?php esc_html_e( '301 — Permanent', 'redirectzen-301-redirect-manager' ); ?></option>
						<option value="302"><?php esc_html_e( '302 — Temporary', 'redirectzen-301-redirect-manager' ); ?></option>
						<option value="307"><?php esc_html_e( '307 — Temporary (strict)', 'redirectzen-301-redirect-manager' ); ?></option>
					</select>
					<?php if ( $is_premium ) : ?>
						<label class="rdz-regex-toggle"><input type="checkbox" name="rdz_regex" value="1" /> <?php esc_html_e( 'Regex', 'redirectzen-301-redirect-manager' ); ?></label>
					<?php endif; ?>
					<button type="submit" class="zen-btn zen-btn--primary"><?php esc_html_e( 'Add redirect', 'redirectzen-301-redirect-manager' ); ?></button>
				</div>
			</form>
		</section>
		<?php
	}

	/**
	 * Redirect health checklist — every row is a true, auto-verified state.
	 *
	 * @param array $counts     Redirect verify counts.
	 * @param array $log_counts 404 counts.
	 */
	private static function render_checklist_card( $counts, $log_counts ) {
		$hidden = self::hidden_tasks();
		$base   = admin_url( 'admin.php?page=redirectzen' );

		$importable = RDZ_Importers::detect();

		$items = array(
			array( 'done' => $counts['total'] > 0, 'label' => __( 'First redirect added', 'redirectzen-301-redirect-manager' ), 'sev' => 'task' ),
			array( 'done' => $counts['total'] > 0 && 0 === $counts['queued'] + $counts['pending'], 'label' => __( 'All redirects verified', 'redirectzen-301-redirect-manager' ), 'sev' => 'task', 'count' => $counts['queued'] + $counts['pending'] ),
			array( 'done' => 0 === $counts['fail'], 'label' => __( 'Fix failing redirects', 'redirectzen-301-redirect-manager' ), 'sev' => 'red', 'count' => $counts['fail'], 'url' => add_query_arg( 'rdz_status', 'fail', $base ), 'cta' => __( 'View', 'redirectzen-301-redirect-manager' ) ),
			array( 'done' => 0 === $log_counts['open'], 'label' => __( 'Clear open 404s', 'redirectzen-301-redirect-manager' ), 'sev' => 'amber', 'count' => $log_counts['open'], 'url' => admin_url( 'admin.php?page=redirectzen-404s' ), 'cta' => __( 'View', 'redirectzen-301-redirect-manager' ) ),
		);

		if ( ! empty( $importable ) ) {
			$items[] = array( 'done' => false, 'label' => __( 'Import redirects from your old plugin', 'redirectzen-301-redirect-manager' ), 'sev' => 'task', 'key' => 'import', 'url' => admin_url( 'admin.php?page=redirectzen-import' ), 'cta' => __( 'Import', 'redirectzen-301-redirect-manager' ), 'dismiss' => true );
		}

		$items[] = array( 'done' => rdz_can_use_premium(), 'label' => __( 'Auto re-verify on a schedule (Pro)', 'redirectzen-301-redirect-manager' ), 'sev' => 'task', 'key' => 'regex', 'url' => self::upgrade_url(), 'cta' => __( 'Go Pro', 'redirectzen-301-redirect-manager' ), 'dismiss' => true );
		$items[] = array( 'done' => RDZ_Optin::has_optin(), 'label' => __( 'Subscribe to redirect-health updates', 'redirectzen-301-redirect-manager' ), 'sev' => 'task', 'key' => 'newsletter', 'url' => '#', 'cta' => '', 'dismiss' => true );

		$rows = array();
		foreach ( $items as $item ) {
			if ( ! empty( $item['key'] ) && ! empty( $item['dismiss'] ) && in_array( $item['key'], $hidden, true ) ) {
				continue; // dismissed → out of the denominator entirely.
			}
			$rows[] = $item;
		}
		$total = count( $rows );
		$done  = count( array_filter( $rows, static function ( $r ) { return $r['done']; } ) );
		$pct   = $total ? round( 100 * $done / $total ) : 100;
		?>
		<section class="zen-card" aria-label="<?php esc_attr_e( 'Redirect health checklist', 'redirectzen-301-redirect-manager' ); ?>">
			<h2><?php esc_html_e( 'Redirect health checklist', 'redirectzen-301-redirect-manager' ); ?></h2>
			<p class="zen-card-sub"><?php echo esc_html( sprintf( /* translators: 1: done, 2: total. */ __( '%1$d of %2$d complete', 'redirectzen-301-redirect-manager' ), $done, $total ) ); ?></p>
			<div class="zen-progress" role="progressbar" aria-valuenow="<?php echo (int) $pct; ?>" aria-valuemin="0" aria-valuemax="100"><span style="width:<?php echo (int) $pct; ?>%"></span></div>
			<div class="zen-issues">
				<?php foreach ( $rows as $item ) : ?>
					<div class="zen-issue">
						<span class="zen-sev <?php echo $item['done'] ? 'zen-sev--done' : 'zen-sev--' . esc_attr( $item['sev'] ); ?>"><?php echo $item['done'] ? '✓' : '&nbsp;·&nbsp;'; ?></span>
						<span class="zen-issue-label"><?php echo esc_html( $item['label'] ); ?></span>
						<?php if ( ! $item['done'] && isset( $item['count'] ) && $item['count'] > 0 ) : ?><span class="zen-count"><?php echo esc_html( number_format_i18n( $item['count'] ) ); ?></span><?php endif; ?>
						<span class="zen-issue-actions">
							<?php if ( ! $item['done'] && ! empty( $item['url'] ) && ! empty( $item['cta'] ) ) : ?><a href="<?php echo esc_url( $item['url'] ); ?>"><?php echo esc_html( $item['cta'] ); ?></a><?php endif; ?>
							<?php if ( ! $item['done'] && ! empty( $item['dismiss'] ) && ! empty( $item['key'] ) ) : ?><button type="button" class="zen-hide-task" data-task="<?php echo esc_attr( $item['key'] ); ?>" aria-label="<?php esc_attr_e( 'Hide this task', 'redirectzen-301-redirect-manager' ); ?>">&times;</button><?php endif; ?>
						</span>
					</div>
				<?php endforeach; ?>
			</div>
		</section>
		<?php
	}

	/**
	 * "More from Zen Plugins" sidebar card (quiet cross-promo, no notices).
	 * RedirectZen owns inbound 404s; LinkGuard owns outbound broken links —
	 * together they're complete link health, so LinkGuard leads here.
	 */
	private static function render_zen_family_card() {
		if ( ! function_exists( 'is_plugin_active' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$plugins = array(
			array(
				'file'  => 'linkguard-broken-link-fixer/linkguard-broken-link-fixer.php',
				'slug'  => 'linkguard-broken-link-fixer',
				'name'  => 'LinkGuard',
				'line'  => __( 'Finds and fixes broken OUTBOUND links — the other half of link health.', 'redirectzen-301-redirect-manager' ),
				'cta'   => __( 'Fix broken links — free', 'redirectzen-301-redirect-manager' ),
			),
			array(
				'file'  => 'ssl-zen/ssl_zen.php',
				'slug'  => 'ssl-zen',
				'name'  => 'SSL Zen',
				'line'  => __( 'Free SSL certificates + HTTPS enforcement.', 'redirectzen-301-redirect-manager' ),
				'cta'   => __( 'Protect your site — free', 'redirectzen-301-redirect-manager' ),
			),
		);
		?>
		<section class="zen-card" aria-label="<?php esc_attr_e( 'More from Zen Plugins', 'redirectzen-301-redirect-manager' ); ?>">
			<h2><?php esc_html_e( 'More from Zen Plugins', 'redirectzen-301-redirect-manager' ); ?></h2>
			<?php foreach ( $plugins as $plugin ) : ?>
				<div class="zen-promo">
					<div class="zen-promo-head">
						<span class="zen-promo-ico"><img src="<?php echo esc_url( RDZ_PLUGIN_URL . 'assets/img/' . $plugin['slug'] . '-icon.png' ); ?>" width="40" height="40" alt="" onerror="this.parentNode.style.display='none'" /></span>
						<span class="zen-promo-id"><h3><?php echo esc_html( $plugin['name'] ); ?></h3></span>
					</div>
					<p class="zen-promo-line"><?php echo esc_html( $plugin['line'] ); ?></p>
					<?php if ( is_plugin_active( $plugin['file'] ) ) : ?>
						<span class="zen-sev zen-sev--done"><?php esc_html_e( 'Active on this site', 'redirectzen-301-redirect-manager' ); ?></span>
					<?php else : ?>
						<?php
						if ( file_exists( WP_PLUGIN_DIR . '/' . $plugin['file'] ) ) {
							$url = wp_nonce_url( self_admin_url( 'plugins.php?action=activate&plugin=' . $plugin['file'] ), 'activate-plugin_' . $plugin['file'] );
						} else {
							$url = wp_nonce_url( self_admin_url( 'update.php?action=install-plugin&plugin=' . $plugin['slug'] ), 'install-plugin_' . $plugin['slug'] );
						}
						?>
						<a class="zen-btn zen-btn--primary" href="<?php echo esc_url( $url ); ?>"><?php echo esc_html( $plugin['cta'] ); ?></a>
					<?php endif; ?>
				</div>
			<?php endforeach; ?>
		</section>
		<?php
	}

	/**
	 * Post-value opt-in card: dismissible, nothing leaves the site without
	 * the click.
	 */
	private static function render_optin_card() {
		if ( ! get_option( 'rdz_first_redirect_at' ) || RDZ_Optin::has_optin() || in_array( 'newsletter', self::hidden_tasks(), true ) ) {
			return;
		}
		?>
		<section class="zen-card rdz-optin-card" aria-label="<?php esc_attr_e( 'Email updates', 'redirectzen-301-redirect-manager' ); ?>">
			<button type="button" class="zen-hide-task rdz-optin-close" data-task="newsletter" aria-label="<?php esc_attr_e( 'Dismiss', 'redirectzen-301-redirect-manager' ); ?>">&times;</button>
			<h2><?php esc_html_e( 'Get update alerts & redirect-health tips', 'redirectzen-301-redirect-manager' ); ?></h2>
			<p class="zen-card-sub"><?php esc_html_e( 'Occasional, useful emails from the RedirectZen team.', 'redirectzen-301-redirect-manager' ); ?></p>
			<div class="rdz-optin-form">
				<input type="email" class="rdz-optin-email regular-text" value="<?php echo esc_attr( get_option( 'admin_email' ) ); ?>" aria-label="<?php esc_attr_e( 'Email address', 'redirectzen-301-redirect-manager' ); ?>" />
				<button type="button" class="zen-btn zen-btn--primary rdz-optin-submit"><?php esc_html_e( 'Subscribe', 'redirectzen-301-redirect-manager' ); ?></button>
			</div>
			<p class="rdz-optin-note"><?php esc_html_e( 'No spam, unsubscribe anytime.', 'redirectzen-301-redirect-manager' ); ?></p>
		</section>
		<?php
	}

	/**
	 * Tips sidebar card — short educational reads.
	 */
	private static function render_tips_card() {
		$docs_base = apply_filters( 'rdz_docs_base', 'https://redirectzen.com/docs/' );
		$tips      = array(
			'#301-vs-302' => __( '301 vs 302 vs 307 — which one when', 'redirectzen-301-redirect-manager' ),
			'#chains'     => __( 'Why redirect chains hurt SEO', 'redirectzen-301-redirect-manager' ),
			'#grade'      => __( 'Reading your Redirect Health grade', 'redirectzen-301-redirect-manager' ),
			'#migrate'    => __( 'Migrating from another redirect plugin', 'redirectzen-301-redirect-manager' ),
		);
		?>
		<section class="zen-card" aria-label="<?php esc_attr_e( 'Tips and guides', 'redirectzen-301-redirect-manager' ); ?>">
			<h2><?php esc_html_e( 'Tips & guides', 'redirectzen-301-redirect-manager' ); ?></h2>
			<ul class="zen-tips">
				<?php foreach ( $tips as $anchor => $label ) : ?>
					<li><a href="<?php echo esc_url( $docs_base . $anchor ); ?>" target="_blank" rel="noopener noreferrer"><?php echo esc_html( $label ); ?></a></li>
				<?php endforeach; ?>
			</ul>
		</section>
		<?php
	}

	/**
	 * Renders the 404 log page.
	 */
	public static function render_404s() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}

		$table = new RDZ_404_Table();
		$table->prepare_items();

		$retention = (int) RDZ_Settings::get( 'retention_days' );
		?>
		<div class="zen-admin zen-shell rdz-wrap">
			<?php self::render_topbar( 'log' ); ?>
			<h1 class="zen-sr-only"><?php esc_html_e( '404 log', 'redirectzen-301-redirect-manager' ); ?></h1>
			<hr class="wp-header-end" style="display:none" />

			<div class="zen-layout" style="grid-template-columns:1fr">
				<main class="zen-main">
					<?php self::render_notices( 'log' ); ?>
					<section class="zen-card zen-table-card" aria-label="<?php esc_attr_e( '404 log', 'redirectzen-301-redirect-manager' ); ?>">
						<h2><?php esc_html_e( '404 log', 'redirectzen-301-redirect-manager' ); ?></h2>
						<p class="zen-card-sub">
							<?php
							/* translators: %d: retention days. */
							echo esc_html( sprintf( __( 'Every 404 with hit counts — free. Turn any row into a redirect in one click. Entries are pruned automatically after %d days so this table can never bloat your database.', 'redirectzen-301-redirect-manager' ), $retention ) );
							?>
						</p>
						<form method="get">
							<input type="hidden" name="page" value="redirectzen-404s" />
							<?php
							if ( isset( $_GET['rdz_view'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
								printf( '<input type="hidden" name="rdz_view" value="%s" />', esc_attr( sanitize_key( wp_unslash( $_GET['rdz_view'] ) ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
							}
							$table->views();
							$table->search_box( __( 'Search 404s', 'redirectzen-301-redirect-manager' ), 'rdz-404-search' );
							$table->display();
							?>
						</form>
					</section>
				</main>
			</div>
		</div>
		<?php
	}

	/**
	 * Renders the import/export page.
	 */
	public static function render_import() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}

		$importable = RDZ_Importers::detect();
		$backups    = RDZ_Backups::all();
		?>
		<div class="zen-admin zen-shell rdz-wrap">
			<?php self::render_topbar( 'import' ); ?>
			<h1 class="zen-sr-only"><?php esc_html_e( 'Import and export', 'redirectzen-301-redirect-manager' ); ?></h1>
			<hr class="wp-header-end" style="display:none" />

			<div class="zen-layout" style="grid-template-columns:1fr;max-width:920px">
				<main class="zen-main">
					<?php self::render_notices( 'import' ); ?>

					<section class="zen-card" aria-label="<?php esc_attr_e( 'Import from another plugin', 'redirectzen-301-redirect-manager' ); ?>">
						<h2><?php esc_html_e( 'Import from your old redirect plugin', 'redirectzen-301-redirect-manager' ); ?></h2>
						<p class="zen-card-sub"><?php esc_html_e( 'One click. Your current rules are backed up first, and every imported redirect is verified end-to-end afterwards — so you\'ll know your migration actually worked.', 'redirectzen-301-redirect-manager' ); ?></p>
						<?php if ( empty( $importable ) ) : ?>
							<p><?php esc_html_e( 'No importable data found. RedirectZen looks for Redirection, Quick Page/Post Redirect Plugin, WP 301 Redirects / Simple 301 Redirects, and Safe Redirect Manager.', 'redirectzen-301-redirect-manager' ); ?></p>
						<?php else : ?>
							<div class="zen-issues">
								<?php foreach ( $importable as $key => $info ) : ?>
									<div class="zen-issue">
										<span class="zen-sev zen-sev--task"><?php esc_html_e( 'Found', 'redirectzen-301-redirect-manager' ); ?></span>
										<span class="zen-issue-label"><strong><?php echo esc_html( $info['label'] ); ?></strong></span>
										<span class="zen-count"><?php echo esc_html( number_format_i18n( $info['count'] ) ); ?></span>
										<span class="zen-issue-actions">
											<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" style="display:inline">
												<input type="hidden" name="action" value="rdz_import" />
												<input type="hidden" name="rdz_source" value="<?php echo esc_attr( $key ); ?>" />
												<?php wp_nonce_field( 'rdz_import' ); ?>
												<button type="submit" class="button button-primary"><?php esc_html_e( 'Import', 'redirectzen-301-redirect-manager' ); ?></button>
											</form>
										</span>
									</div>
								<?php endforeach; ?>
							</div>
							<?php if ( ! rdz_can_use_premium() ) : ?>
								<p class="description"><?php esc_html_e( 'Regex and wildcard rules are skipped on the free plan — they import as regex rules with Pro.', 'redirectzen-301-redirect-manager' ); ?></p>
							<?php endif; ?>
						<?php endif; ?>
					</section>

					<section class="zen-card" aria-label="<?php esc_attr_e( 'CSV', 'redirectzen-301-redirect-manager' ); ?>">
						<h2><?php esc_html_e( 'CSV import & export', 'redirectzen-301-redirect-manager' ); ?></h2>
						<p class="zen-card-sub"><?php esc_html_e( 'Free and unlimited. The importer accepts our format plus common exports (source/target, url/redirect_to, from/to).', 'redirectzen-301-redirect-manager' ); ?></p>
						<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" enctype="multipart/form-data" style="margin-bottom:14px">
							<input type="hidden" name="action" value="rdz_import_csv" />
							<?php wp_nonce_field( 'rdz_import_csv' ); ?>
							<input type="file" name="rdz_csv" accept=".csv,text/csv" required />
							<button type="submit" class="button button-primary"><?php esc_html_e( 'Import CSV', 'redirectzen-301-redirect-manager' ); ?></button>
						</form>
						<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
							<input type="hidden" name="action" value="rdz_export_csv" />
							<?php wp_nonce_field( 'rdz_export_csv' ); ?>
							<button type="submit" class="button"><?php esc_html_e( 'Export all redirects as CSV', 'redirectzen-301-redirect-manager' ); ?></button>
						</form>
					</section>

					<section class="zen-card" aria-label="<?php esc_attr_e( 'Backups', 'redirectzen-301-redirect-manager' ); ?>">
						<h2><?php esc_html_e( 'Automatic backups', 'redirectzen-301-redirect-manager' ); ?></h2>
						<p class="zen-card-sub"><?php esc_html_e( 'RedirectZen snapshots your rules before every import, bulk change and plugin update. One click brings everything back.', 'redirectzen-301-redirect-manager' ); ?></p>
						<?php if ( empty( $backups ) ) : ?>
							<p><?php esc_html_e( 'No backups yet — one is created automatically before the first bulk change.', 'redirectzen-301-redirect-manager' ); ?></p>
						<?php else : ?>
							<div class="zen-issues">
								<?php foreach ( $backups as $backup ) : ?>
									<div class="zen-issue">
										<span class="zen-sev zen-sev--task">⧗</span>
										<span class="zen-issue-label">
											<?php echo esc_html( $backup['label'] ); ?>
											<small> — <?php echo esc_html( sprintf( /* translators: 1: rule count, 2: date. */ __( '%1$s rules, %2$s', 'redirectzen-301-redirect-manager' ), number_format_i18n( (int) $backup['rows_count'] ), $backup['created_at'] ) ); ?> UTC</small>
										</span>
										<span class="zen-issue-actions">
											<a href="<?php echo esc_url( wp_nonce_url( admin_url( 'admin-post.php?action=rdz_restore_backup&backup_id=' . (int) $backup['id'] ), 'rdz_restore_backup_' . (int) $backup['id'] ) ); ?>" onclick="return confirm('<?php echo esc_js( __( 'Replace ALL current redirects with this backup? The current state is backed up first.', 'redirectzen-301-redirect-manager' ) ); ?>');"><?php esc_html_e( 'Restore', 'redirectzen-301-redirect-manager' ); ?></a>
										</span>
									</div>
								<?php endforeach; ?>
							</div>
						<?php endif; ?>
					</section>
				</main>
			</div>
		</div>
		<?php
	}

	/**
	 * Renders the settings page inside the same shell.
	 */
	public static function render_settings() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}

		$settings   = RDZ_Settings::all();
		$is_premium = rdz_can_use_premium();
		$key        = RDZ_Settings::OPTION_KEY;
		?>
		<div class="zen-admin zen-shell rdz-wrap">
			<?php self::render_topbar( 'settings' ); ?>
			<h1 class="zen-sr-only"><?php esc_html_e( 'RedirectZen settings', 'redirectzen-301-redirect-manager' ); ?></h1>

			<div class="zen-layout" style="grid-template-columns:1fr;max-width:920px">
				<main class="zen-main">
					<form method="post" action="options.php">
						<?php settings_fields( 'rdz_settings_group' ); ?>

						<section class="zen-card">
							<h2><?php esc_html_e( 'Redirects', 'redirectzen-301-redirect-manager' ); ?></h2>
							<table class="form-table" role="presentation">
								<tr>
									<th scope="row"><label for="rdz-default-type"><?php esc_html_e( 'Default redirect type', 'redirectzen-301-redirect-manager' ); ?></label></th>
									<td>
										<select id="rdz-default-type" name="<?php echo esc_attr( $key ); ?>[default_redirect_type]">
											<option value="301" <?php selected( $settings['default_redirect_type'], 301 ); ?>><?php esc_html_e( '301 — Permanent (best for SEO)', 'redirectzen-301-redirect-manager' ); ?></option>
											<option value="302" <?php selected( $settings['default_redirect_type'], 302 ); ?>><?php esc_html_e( '302 — Temporary', 'redirectzen-301-redirect-manager' ); ?></option>
											<option value="307" <?php selected( $settings['default_redirect_type'], 307 ); ?>><?php esc_html_e( '307 — Temporary (strict)', 'redirectzen-301-redirect-manager' ); ?></option>
										</select>
									</td>
								</tr>
								<tr>
									<th scope="row"><label for="rdz-timeout"><?php esc_html_e( 'Verification timeout', 'redirectzen-301-redirect-manager' ); ?></label></th>
									<td>
										<input type="number" id="rdz-timeout" min="3" max="30" name="<?php echo esc_attr( $key ); ?>[request_timeout]" value="<?php echo esc_attr( $settings['request_timeout'] ); ?>" class="small-text" />
										<span><?php esc_html_e( 'seconds', 'redirectzen-301-redirect-manager' ); ?></span>
									</td>
								</tr>
								<tr>
									<th scope="row"><label for="rdz-batch"><?php esc_html_e( 'Verification batch size', 'redirectzen-301-redirect-manager' ); ?></label></th>
									<td>
										<input type="number" id="rdz-batch" min="5" max="50" name="<?php echo esc_attr( $key ); ?>[verify_batch]" value="<?php echo esc_attr( $settings['verify_batch'] ); ?>" class="small-text" />
										<p class="description"><?php esc_html_e( 'Redirects verified per background run (every 5 minutes). Lower this on shared hosting.', 'redirectzen-301-redirect-manager' ); ?></p>
									</td>
								</tr>
								<tr>
									<th scope="row"><label for="rdz-verify-schedule"><?php esc_html_e( 'Re-verify everything', 'redirectzen-301-redirect-manager' ); ?></label></th>
									<td>
										<select id="rdz-verify-schedule" name="<?php echo esc_attr( $key ); ?>[verify_schedule]" <?php disabled( ! $is_premium ); ?>>
											<option value="off" <?php selected( $settings['verify_schedule'], 'off' ); ?>><?php esc_html_e( 'Manually only', 'redirectzen-301-redirect-manager' ); ?></option>
											<option value="daily" <?php selected( $settings['verify_schedule'], 'daily' ); ?>><?php esc_html_e( 'Daily', 'redirectzen-301-redirect-manager' ); ?></option>
											<option value="weekly" <?php selected( $settings['verify_schedule'], 'weekly' ); ?>><?php esc_html_e( 'Weekly', 'redirectzen-301-redirect-manager' ); ?></option>
										</select>
										<?php if ( ! $is_premium ) : ?>
											<p class="description">
												<?php esc_html_e( 'The free plan verifies on save and on demand. Scheduled re-verification (with an email digest when something breaks) is a Pro feature.', 'redirectzen-301-redirect-manager' ); ?>
												<a href="<?php echo esc_url( self::upgrade_url() ); ?>"><?php esc_html_e( 'Upgrade to Pro', 'redirectzen-301-redirect-manager' ); ?></a>
											</p>
										<?php endif; ?>
									</td>
								</tr>
							</table>
						</section>

						<section class="zen-card">
							<h2><?php esc_html_e( '404 logging', 'redirectzen-301-redirect-manager' ); ?></h2>
							<table class="form-table" role="presentation">
								<tr>
									<th scope="row"><?php esc_html_e( 'Log 404s', 'redirectzen-301-redirect-manager' ); ?></th>
									<td>
										<label>
											<input type="checkbox" name="<?php echo esc_attr( $key ); ?>[log_404]" value="1" <?php checked( $settings['log_404'] ); ?> />
											<?php esc_html_e( 'Record 404 hits so they can be turned into redirects', 'redirectzen-301-redirect-manager' ); ?>
										</label>
									</td>
								</tr>
								<tr>
									<th scope="row"><label for="rdz-retention"><?php esc_html_e( 'Keep entries for', 'redirectzen-301-redirect-manager' ); ?></label></th>
									<td>
										<input type="number" id="rdz-retention" min="1" max="365" name="<?php echo esc_attr( $key ); ?>[retention_days]" value="<?php echo esc_attr( $settings['retention_days'] ); ?>" class="small-text" />
										<span><?php esc_html_e( 'days', 'redirectzen-301-redirect-manager' ); ?></span>
									</td>
								</tr>
								<tr>
									<th scope="row"><label for="rdz-max-rows"><?php esc_html_e( 'Maximum log rows', 'redirectzen-301-redirect-manager' ); ?></label></th>
									<td>
										<input type="number" id="rdz-max-rows" min="100" max="100000" name="<?php echo esc_attr( $key ); ?>[max_404_rows]" value="<?php echo esc_attr( $settings['max_404_rows'] ); ?>" class="small-text" />
										<p class="description"><?php esc_html_e( 'Oldest entries are pruned past this cap. Your database stays lean no matter how hard bots hammer the site.', 'redirectzen-301-redirect-manager' ); ?></p>
									</td>
								</tr>
								<tr>
									<th scope="row"><label for="rdz-ignore"><?php esc_html_e( 'Ignore patterns', 'redirectzen-301-redirect-manager' ); ?></label></th>
									<td>
										<textarea id="rdz-ignore" name="<?php echo esc_attr( $key ); ?>[ignore_patterns]" rows="5" class="large-text code"><?php echo esc_textarea( implode( "\n", (array) $settings['ignore_patterns'] ) ); ?></textarea>
										<p class="description"><?php esc_html_e( 'One per line. * is a wildcard; a pattern without * matches as a substring. Requests matching these are never logged (bot probes, scanners).', 'redirectzen-301-redirect-manager' ); ?></p>
									</td>
								</tr>
							</table>
						</section>

						<section class="zen-card">
							<h2><?php esc_html_e( 'Email digest', 'redirectzen-301-redirect-manager' ); ?></h2>
							<table class="form-table" role="presentation">
								<tr>
									<th scope="row"><?php esc_html_e( 'Weekly summary', 'redirectzen-301-redirect-manager' ); ?></th>
									<td>
										<label>
											<input type="checkbox" name="<?php echo esc_attr( $key ); ?>[digest_enabled]" value="1" <?php checked( $settings['digest_enabled'] ); ?> <?php disabled( ! $is_premium ); ?> />
											<?php esc_html_e( 'Email me a weekly redirect-health summary', 'redirectzen-301-redirect-manager' ); ?>
										</label>
										<?php if ( ! $is_premium ) : ?>
											<p class="description"><?php esc_html_e( 'Part of scheduled re-verification (Pro).', 'redirectzen-301-redirect-manager' ); ?></p>
										<?php endif; ?>
									</td>
								</tr>
								<tr>
									<th scope="row"><label for="rdz-recipient"><?php esc_html_e( 'Recipient', 'redirectzen-301-redirect-manager' ); ?></label></th>
									<td>
										<input type="email" id="rdz-recipient" name="<?php echo esc_attr( $key ); ?>[digest_recipient]" value="<?php echo esc_attr( $settings['digest_recipient'] ); ?>" class="regular-text" placeholder="<?php echo esc_attr( get_option( 'admin_email' ) ); ?>" />
										<p class="description"><?php esc_html_e( 'Leave empty to use the site admin email.', 'redirectzen-301-redirect-manager' ); ?></p>
										<label style="display:block;margin-top:12px">
											<input type="checkbox" name="<?php echo esc_attr( $key ); ?>[updates_optin]" value="1" <?php checked( RDZ_Settings::get( 'updates_optin' ) ); ?> />
											<?php esc_html_e( 'Also send me occasional RedirectZen product updates', 'redirectzen-301-redirect-manager' ); ?>
										</label>
									</td>
								</tr>
							</table>
						</section>

						<section class="zen-card">
							<h2><?php esc_html_e( 'Data', 'redirectzen-301-redirect-manager' ); ?></h2>
							<table class="form-table" role="presentation">
								<tr>
									<th scope="row"><?php esc_html_e( 'On uninstall', 'redirectzen-301-redirect-manager' ); ?></th>
									<td>
										<label>
											<input type="checkbox" name="<?php echo esc_attr( $key ); ?>[keep_data]" value="1" <?php checked( $settings['keep_data'] ); ?> />
											<?php esc_html_e( 'Keep redirects and settings if the plugin is uninstalled', 'redirectzen-301-redirect-manager' ); ?>
										</label>
										<p class="description"><?php esc_html_e( 'Off by default: uninstalling removes every trace of RedirectZen from your database.', 'redirectzen-301-redirect-manager' ); ?></p>
									</td>
								</tr>
							</table>
						</section>

						<?php submit_button( null, 'zen-btn zen-btn--primary' ); ?>
					</form>
				</main>
			</div>
		</div>
		<?php
	}

	/**
	 * Task keys the current user has hidden.
	 *
	 * @return string[]
	 */
	public static function hidden_tasks() {
		$hidden = get_user_meta( get_current_user_id(), 'rdz_hidden_tasks', true );

		return is_array( $hidden ) ? $hidden : array();
	}

	/**
	 * Contact page — a human answers.
	 */
	public static function render_contact() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}
		?>
		<div class="zen-admin zen-shell rdz-wrap">
			<?php self::render_topbar( 'contact' ); ?>
			<div class="zen-layout" style="grid-template-columns:1fr;max-width:640px">
				<main class="zen-main">
					<section class="zen-card" style="text-align:center;padding:40px 32px">
						<h2 style="font-size:24px;margin:0 0 6px"><?php esc_html_e( 'A human answers.', 'redirectzen-301-redirect-manager' ); ?></h2>
						<p class="zen-card-sub" style="margin-bottom:20px"><?php esc_html_e( 'No ticket bots, no tiers. We reply within 24 hours — usually much faster.', 'redirectzen-301-redirect-manager' ); ?></p>
						<a class="zen-btn zen-btn--primary" href="mailto:support@zenplugins.org?subject=RedirectZen">support@zenplugins.org</a>
						<p style="margin:18px 0 0"><a href="<?php echo esc_url( apply_filters( 'rdz_docs_base', 'https://redirectzen.com/docs/' ) ); ?>" target="_blank" rel="noopener noreferrer"><?php esc_html_e( 'Or read the docs →', 'redirectzen-301-redirect-manager' ); ?></a></p>
					</section>
				</main>
			</div>
		</div>
		<?php
	}

	/**
	 * Custom Pro pricing page — lifetime-first (this niche buys lifetime),
	 * Freemius handles checkout once the product is wired.
	 */
	public static function render_pricing() {
		if ( ! current_user_can( self::CAPABILITY ) ) {
			return;
		}

		$counts = RDZ_Redirects::get_counts();
		$last   = (int) get_option( 'rdz_last_verify_cycle', 0 );
		$grade  = RDZ_Grade::compute( $counts, $last, 0, time() );

		// Freemius product 33515, plan PRO 55116, lifetime-only pricing.
		$tiers = array(
			array( 'pricing_id' => 72689, 'name' => __( '1 Site', 'redirectzen-301-redirect-manager' ), 'price' => 39, 'popular' => false, 'features' => array( __( 'Regex & wildcard redirects', 'redirectzen-301-redirect-manager' ), __( 'Auto-suggest targets for 404s', 'redirectzen-301-redirect-manager' ), __( 'Scheduled re-verification + email digest', 'redirectzen-301-redirect-manager' ) ) ),
			array( 'pricing_id' => 72690, 'name' => __( '5 Sites', 'redirectzen-301-redirect-manager' ), 'price' => 59, 'popular' => true, 'features' => array( __( 'Everything in 1 Site', 'redirectzen-301-redirect-manager' ), __( 'Use on up to 5 sites', 'redirectzen-301-redirect-manager' ), __( 'Priority email support', 'redirectzen-301-redirect-manager' ) ) ),
			array( 'pricing_id' => 72691, 'name' => __( '25 Sites', 'redirectzen-301-redirect-manager' ), 'price' => 99, 'popular' => false, 'features' => array( __( 'Everything in 5 Sites', 'redirectzen-301-redirect-manager' ), __( 'Use on up to 25 sites', 'redirectzen-301-redirect-manager' ), __( 'Multisite support', 'redirectzen-301-redirect-manager' ) ) ),
		);
		?>
		<div class="zen-admin zen-shell rdz-wrap">
			<?php self::render_topbar( 'pricing' ); ?>
			<h1 class="zen-sr-only"><?php esc_html_e( 'RedirectZen Pro pricing', 'redirectzen-301-redirect-manager' ); ?></h1>
			<div class="zen-layout" style="grid-template-columns:1fr;max-width:980px">
				<main class="zen-main">
					<?php if ( 'pending' !== $grade && $counts['fail'] > 0 ) : ?>
						<section class="zen-card zen-grade zen-grade--<?php echo esc_attr( RDZ_Grade::tone( $grade ) ); ?>" style="padding:18px 24px">
							<div class="zen-grade-letter" style="width:64px;height:64px;font-size:34px" aria-hidden="true"><?php echo esc_html( $grade ); ?></div>
							<div class="zen-grade-body"><h2 style="margin:0">
								<?php
								echo esc_html(
									sprintf(
										/* translators: 1: grade letter, 2: number of failing redirects. */
										_n(
											'Your site: grade %1$s — %2$d redirect is silently failing right now.',
											'Your site: grade %1$s — %2$d redirects are silently failing right now.',
											$counts['fail'],
											'redirectzen-301-redirect-manager'
										),
										$grade,
										$counts['fail']
									)
								);
								?>
							</h2><p style="margin:6px 0 0;color:var(--zen-muted)"><?php esc_html_e( 'Pro re-verifies everything on a schedule and emails you the moment one breaks.', 'redirectzen-301-redirect-manager' ); ?></p></div>
						</section>
					<?php endif; ?>

					<div class="zen-harm">
						<div class="zen-card"><h3><?php esc_html_e( 'Redirects rot', 'redirectzen-301-redirect-manager' ); ?></h3><p><?php esc_html_e( 'Targets get deleted, permalinks change, plugins conflict. A redirect that worked in January silently dead-ends in June.', 'redirectzen-301-redirect-manager' ); ?></p></div>
						<div class="zen-card"><h3><?php esc_html_e( 'Nobody notices', 'redirectzen-301-redirect-manager' ); ?></h3><p><?php esc_html_e( 'You never browse your own old URLs — visitors and Google do. They meet the 404 before you ever hear about it.', 'redirectzen-301-redirect-manager' ); ?></p></div>
						<div class="zen-card"><h3><?php esc_html_e( 'Rankings leak', 'redirectzen-301-redirect-manager' ); ?></h3><p><?php esc_html_e( 'Every failed redirect throws away the link equity the old URL earned over years.', 'redirectzen-301-redirect-manager' ); ?></p></div>
					</div>

					<div class="zen-offer"><span>⚡ <?php esc_html_e( 'Launch offer — 30% off with code', 'redirectzen-301-redirect-manager' ); ?> <code>ZENLAUNCH</code></span></div>

					<div class="zen-plans">
						<?php foreach ( $tiers as $tier ) : ?>
							<div class="zen-card zen-plan<?php echo $tier['popular'] ? ' zen-plan--popular' : ''; ?>">
								<?php if ( $tier['popular'] ) : ?><span class="zen-pop"><?php esc_html_e( 'Most popular', 'redirectzen-301-redirect-manager' ); ?></span><?php endif; ?>
								<h3><?php echo esc_html( $tier['name'] ); ?></h3>
								<p class="zen-price">$<?php echo (int) $tier['price']; ?><small> <?php esc_html_e( 'lifetime — pay once', 'redirectzen-301-redirect-manager' ); ?></small></p>
								<ul>
									<?php foreach ( $tier['features'] as $feature ) : ?><li><?php echo esc_html( $feature ); ?></li><?php endforeach; ?>
								</ul>
								<a class="zen-btn <?php echo $tier['popular'] ? 'zen-btn--primary' : 'zen-btn--ghost'; ?>" href="<?php echo esc_url( self::checkout_url( (int) $tier['pricing_id'] ) ); ?>" target="_blank" rel="noopener noreferrer">
									<?php echo esc_html( sprintf( /* translators: %s: tier name. */ __( 'Get %s', 'redirectzen-301-redirect-manager' ), $tier['name'] ) ); ?>
								</a>
							</div>
						<?php endforeach; ?>
					</div>
					<p class="zen-moneyback">🛡 <?php esc_html_e( '14-day money-back guarantee, no questions asked. The free version stays free forever.', 'redirectzen-301-redirect-manager' ); ?></p>

					<section class="zen-card">
						<h2><?php esc_html_e( 'Free vs Pro', 'redirectzen-301-redirect-manager' ); ?></h2>
						<table class="zen-compare zen-compare--big">
							<thead><tr><th></th><th class="zen-lgcol"><?php esc_html_e( 'Free', 'redirectzen-301-redirect-manager' ); ?></th><th class="zen-lgcol">Pro</th></tr></thead>
							<tbody>
							<?php
							$rows = array(
								array( __( 'Unlimited redirects, verified end-to-end', 'redirectzen-301-redirect-manager' ), '✓', '✓' ),
								array( __( '404 log with hit counts + one-click redirects', 'redirectzen-301-redirect-manager' ), '✓', '✓' ),
								array( __( 'One-click importers + CSV, auto-backups', 'redirectzen-301-redirect-manager' ), '✓', '✓' ),
								array( __( 'Regex & wildcard redirects', 'redirectzen-301-redirect-manager' ), '—', '✓' ),
								array( __( 'Auto-suggest targets for 404s', 'redirectzen-301-redirect-manager' ), '—', '✓' ),
								array( __( 'Scheduled re-verification of everything', 'redirectzen-301-redirect-manager' ), '—', '✓' ),
								array( __( 'Email digest when a redirect breaks', 'redirectzen-301-redirect-manager' ), '—', '✓' ),
							);
							foreach ( $rows as $r ) {
								echo '<tr><td>' . esc_html( $r[0] ) . '</td><td class="zen-lgcol">' . esc_html( $r[1] ) . '</td><td class="zen-lgcol">' . esc_html( $r[2] ) . '</td></tr>';
							}
							?>
							</tbody>
						</table>
					</section>

					<section class="zen-card">
						<h2><?php esc_html_e( 'Questions', 'redirectzen-301-redirect-manager' ); ?></h2>
						<details class="zen-faq"><summary><?php esc_html_e( 'Is it really lifetime?', 'redirectzen-301-redirect-manager' ); ?></summary><p><?php esc_html_e( 'Yes. Pay once and updates are included for the life of the product.', 'redirectzen-301-redirect-manager' ); ?></p></details>
						<details class="zen-faq"><summary><?php esc_html_e( 'Do I need to renew anything?', 'redirectzen-301-redirect-manager' ); ?></summary><p><?php esc_html_e( 'No. A license is a one-time purchase — there is nothing that auto-renews and nothing to remember to keep active.', 'redirectzen-301-redirect-manager' ); ?></p></details>
						<details class="zen-faq"><summary><?php esc_html_e( 'What happens if Pro is not for me?', 'redirectzen-301-redirect-manager' ); ?></summary><p><?php esc_html_e( '14-day money-back guarantee, no questions asked — one email, full refund.', 'redirectzen-301-redirect-manager' ); ?></p></details>
						<details class="zen-faq"><summary><?php esc_html_e( 'Does the free version stay free?', 'redirectzen-301-redirect-manager' ); ?></summary><p><?php esc_html_e( 'Yes. Unlimited verified redirects, the 404 log and importers are free forever. Pro adds automation on top.', 'redirectzen-301-redirect-manager' ); ?></p></details>
					</section>
				</main>
			</div>
		</div>
		<?php
	}

	/**
	 * Hosted Freemius checkout URL for a pricing tier. The hosted page is
	 * used deliberately: the overlay checkout script proved nondeterministic
	 * in live testing (blank overlays, click-blocking iframes after close).
	 *
	 * @param int $pricing_id Freemius pricing ID.
	 * @return string
	 */
	public static function checkout_url( $pricing_id ) {
		if ( ! RDZ_FREEMIUS_ID ) {
			return 'https://redirectzen.com/#pricing';
		}

		return add_query_arg(
			array(
				'pricing_id'    => (int) $pricing_id,
				'billing_cycle' => 'lifetime',
				'coupon'        => 'ZENLAUNCH',
			),
			'https://checkout.freemius.com/plugin/' . (int) RDZ_FREEMIUS_ID . '/plan/55116/'
		);
	}

	/**
	 * Upgrade URL.
	 *
	 * @return string
	 */
	public static function upgrade_url() {
		return admin_url( 'admin.php?page=redirectzen-upgrade' );
	}
}
