<?php
/**
 * Admin class.
 *
 * Registers plugin settings via the WordPress Settings API.
 * Handles the admin settings page, asset loading, and the
 * modern wp.media image picker.
 *
 * @package IGIT_RPWT
 */

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

class IGIT_RPWT_Admin
{

	/**
	 * Settings page slug.
	 */
	const PAGE_SLUG = 'igit-rpwt';

	public function __construct()
	{
		add_action('admin_menu', array($this, 'add_menu_page'));
		add_action('admin_init', array($this, 'register_settings'));
		add_action('admin_init', array($this, 'handle_flush_cache'));
		add_action('admin_enqueue_scripts', array($this, 'enqueue_assets'));
		add_filter('plugin_action_links_' . IGIT_RPWT_BASENAME, array($this, 'action_links'));

		// Import / export handlers (admin_post_{action}).
		add_action('admin_post_igit_rpwt_export', array($this, 'handle_export_settings'));
		add_action('admin_post_igit_rpwt_import', array($this, 'handle_import_settings'));

		// AJAX handlers.
		add_action('wp_ajax_igit_rpwt_save_settings', array($this, 'ajax_save_settings'));
		add_action('wp_ajax_igit_rpwt_save_theme', array($this, 'ajax_save_theme'));
	}

	/**
	 * Add the Settings sub-menu item.
	 */
	public function add_menu_page()
	{
		add_menu_page(
			__('Related Posts With Thumb', 'igit-related-posts-with-thumb-images-after-posts'),
			__('Related Posts', 'igit-related-posts-with-thumb-images-after-posts'),
			'manage_options',
			self::PAGE_SLUG,
			array($this, 'render_settings_page'),
			'dashicons-networking',
			26
		);

		// Re-label the auto-created duplicate top-level submenu entry.
		add_submenu_page(
			self::PAGE_SLUG,
			__('Related Posts Settings', 'igit-related-posts-with-thumb-images-after-posts'),
			__('Settings', 'igit-related-posts-with-thumb-images-after-posts'),
			'manage_options',
			self::PAGE_SLUG,
			array($this, 'render_settings_page')
		);
	}

	/**
	 * Register all settings, sections, and fields via the Settings API.
	 */
	public function register_settings()
	{
		register_setting(
			'igit_rpwt_settings_group',
			IGIT_RPWT_Settings::OPTION_KEY,
			array(
				'sanitize_callback' => array('IGIT_RPWT_Settings', 'sanitise'),
			)
		);

		// ── Section: Display ────────────────────────────────────────────
		add_settings_section(
			'igit_rpwt_display',
			__('Display Settings', 'igit-related-posts-with-thumb-images-after-posts'),
			'__return_false',
			self::PAGE_SLUG
		);

		$this->add_field('heading_text', __('Heading Text', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_text'));
		$this->add_field('heading_level', __('Heading Level', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_heading_level'));
		$this->add_field('auto_show', __('Auto-show After Post', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_checkbox'));
		$this->add_field('post_count', __('Number of Posts', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_number'));
		$this->add_field('layout', __('Layout', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_layout'));
		$this->add_field('grid_columns_desktop', __('Grid Columns (Desktop)', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_number'));
		$this->add_field('grid_columns_tablet', __('Grid Columns (Tablet)', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_number'));
		$this->add_field('grid_columns_mobile', __('Grid Columns (Mobile)', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_number'));
		$this->add_field('no_posts_text', __('No Posts Found Text', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_text'));
		$this->add_field('show_title', __('Show Title', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_checkbox'));
		$this->add_field('show_excerpt', __('Show Excerpt', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_checkbox'));
		$this->add_field('excerpt_length', __('Excerpt Length (words)', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_number'));
		$this->add_field('show_date', __('Show Date', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_checkbox'));
		$this->add_field('show_reading_time', __('Show Reading Time', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_checkbox'));
		$this->add_field('show_comment_count', __('Show Comment Count', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_checkbox'));
		$this->add_field('show_category_badge', __('Category Badge on Thumb', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_checkbox'));
		$this->add_field('link_target', __('Link Opens In', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_link_target'));
		$this->add_field('link_nofollow', __('Nofollow Links', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_checkbox'));
		$this->add_field('custom_css', __('Custom CSS', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_display', array($this, 'field_textarea'));

		// ── Section: Thumbnails ─────────────────────────────────────────
		add_settings_section(
			'igit_rpwt_thumbnails',
			__('Thumbnail Settings', 'igit-related-posts-with-thumb-images-after-posts'),
			'__return_false',
			self::PAGE_SLUG
		);

		$this->add_field('show_thumbnail', __('Show Thumbnail', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_thumbnails', array($this, 'field_checkbox'));
		$this->add_field('thumbnail_size', __('Thumbnail Size', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_thumbnails', array($this, 'field_thumbnail_size'));
		$this->add_field('default_image', __('Default / Fallback Image', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_thumbnails', array($this, 'field_image_picker'));

		// ── Section: Query ──────────────────────────────────────────────
		add_settings_section(
			'igit_rpwt_query',
			__('Query Settings', 'igit-related-posts-with-thumb-images-after-posts'),
			'__return_false',
			self::PAGE_SLUG
		);

		$this->add_field('relate_by', __('Find Related Posts By', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_relate_by'));
		$this->add_field('post_types', __('Post Types', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_post_types'));
		$this->add_field('relate_taxonomies', __('Match Taxonomies', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_relate_taxonomies'));
		$this->add_field('exclude_categories', __('Exclude Categories', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_exclude_cats'));
		$this->add_field('exclude_posts', __('Exclude Post IDs', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_text'));
		$this->add_field('min_term_overlap', __('Min. Term Overlap', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_number'));
		$this->add_field('max_age_days', __('Max Post Age (days)', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_number'));
		$this->add_field('fallback_mode', __('Fallback Mode', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_fallback_mode'));
		$this->add_field('rotate_results', __('Rotate Results', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', igit_rpwt_is_pro() ? array($this, 'field_checkbox') : array($this, 'field_pro_checkbox'));
		$this->add_field('show_query_time', __('Show Query Time', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', array($this, 'field_checkbox'));

		if (is_multisite()) {
			$this->add_field('multisite_search', __('Search Network Sites', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_query', igit_rpwt_is_pro() ? array($this, 'field_checkbox') : array($this, 'field_pro_checkbox'));
		}

		// ── Section: Cache ──────────────────────────────────────────────
		add_settings_section(
			'igit_rpwt_cache',
			__('Cache Settings', 'igit-related-posts-with-thumb-images-after-posts'),
			'__return_false',
			self::PAGE_SLUG
		);

		$this->add_field('cache_ttl', __('Cache Duration (seconds)', 'igit-related-posts-with-thumb-images-after-posts'), 'igit_rpwt_cache', array($this, 'field_number'));

		// ── Section: Performance ────────────────────────────────────────
		add_settings_section(
			'igit_rpwt_performance',
			__('Performance', 'igit-related-posts-with-thumb-images-after-posts'),
			igit_rpwt_is_pro() ? '__return_false' : array(self::class, 'render_performance_preview'),
			self::PAGE_SLUG
		);

		// Note: when Pro is active, IGIT_RPWT_Pro::register_pro_settings() at
		// priority 20 registers the 'load_async' field with its own toggle UI.
		// No free-plugin field registration here to avoid a duplicate on the page.

		// ── Section: Analytics ──────────────────────────────────
		add_settings_section(
			'igit_rpwt_analytics',
			__('Analytics', 'igit-related-posts-with-thumb-images-after-posts'),
			igit_rpwt_is_pro() ? array('IGIT_RPWT_Analytics_Page', 'render_tab') : array(self::class, 'render_analytics_preview'),
			self::PAGE_SLUG
		);

		// Note: when Pro is active, IGIT_Related_Pro::register_pro_settings() at priority 20
		// overwrites this section and registers the analytics_manage field with the Pro callback.

		// ── Section: Integrations ───────────────────────────────────────
		add_settings_section(
			'igit_rpwt_integrations',
			__('Integrations', 'igit-related-posts-with-thumb-images-after-posts'),
			array(self::class, 'render_integrations_preview'),
			self::PAGE_SLUG
		);

		// ── Section: Post Nudges (Pro) ────────────────────────────
		// When Pro is active the real fields are registered by IGIT_RPWT_Nudges at
		// admin_init @25 on this same page slug.  We register the section here at @10
		// so the page slug is correct; passing '__return_false' when Pro is active
		// ensures no upgrade-preview markup is output and the JS PRO badge is hidden.
		add_settings_section(
			'igit_rpwt_nudges',
			__('Post Nudges', 'igit-related-posts-with-thumb-images-after-posts'),
			igit_rpwt_is_pro() ? '__return_false' : array(self::class, 'render_nudges_preview'),
			self::PAGE_SLUG
		);
	}

	// ── Field renderers ──────────────────────────────────────────────────────

	public function field_text($args)
	{
		$key = $args['key'];
		$raw = IGIT_RPWT_Settings::get($key);
		// exclude_posts is stored as an array; render it as comma-separated.
		$raw_value = is_array($raw) ? implode(', ', $raw) : $raw;
		$descriptions = array(
			'exclude_posts' => __('Comma-separated post IDs to never show in related posts (e.g. 12, 45, 99).', 'igit-related-posts-with-thumb-images-after-posts'),
		);
		printf(
			'<input type="text" id="%1$s" name="%2$s[%1$s]" value="%3$s" class="regular-text" />',
			esc_attr($key),
			esc_attr(IGIT_RPWT_Settings::OPTION_KEY),
			esc_attr($raw_value)
		);
		if (isset($descriptions[$key])) {
			echo '<p class="description">' . esc_html($descriptions[$key]) . '</p>';
		}
	}

	public function field_number($args)
	{
		$key = $args['key'];
		$value = absint(IGIT_RPWT_Settings::get($key));
		$config = array(
			'post_count' => array('min' => 1, 'max' => 20, 'desc' => ''),
			'excerpt_length' => array('min' => 10, 'max' => 30, 'desc' => __('Word count for the excerpt (10–30 words).', 'igit-related-posts-with-thumb-images-after-posts')),
			'grid_columns_desktop' => array('min' => 2, 'max' => 6, 'desc' => __('Columns on desktop screens (2–6).', 'igit-related-posts-with-thumb-images-after-posts')),
			'grid_columns_tablet' => array('min' => 1, 'max' => 3, 'desc' => __('Columns on tablet screens (1–3).', 'igit-related-posts-with-thumb-images-after-posts')),
			'grid_columns_mobile' => array('min' => 1, 'max' => 2, 'desc' => __('Columns on mobile screens (1–2).', 'igit-related-posts-with-thumb-images-after-posts')),
			'min_term_overlap' => array('min' => 1, 'max' => 5, 'desc' => __('Minimum shared terms for a post to qualify (1 = any overlap).', 'igit-related-posts-with-thumb-images-after-posts')),
			'max_age_days' => array('min' => 0, 'max' => 3650, 'desc' => __('Only show posts published within the last N days. 0 = no limit.', 'igit-related-posts-with-thumb-images-after-posts')),
			'cache_ttl' => array('min' => 0, 'max' => 604800, 'desc' => __('Set to 0 to disable. 43200 = 12 hours, 86400 = 24 hours.', 'igit-related-posts-with-thumb-images-after-posts')),
		);
		$cfg = isset($config[$key]) ? $config[$key] : array('min' => 0, 'max' => 100, 'desc' => '');
		printf(
			'<input type="number" id="%1$s" name="%2$s[%1$s]" value="%3$d" min="%4$d" max="%5$d" class="small-text" />',
			esc_attr($key),
			esc_attr(IGIT_RPWT_Settings::OPTION_KEY),
			absint($value),
			absint($cfg['min']),
			absint($cfg['max'])
		);
		if ($cfg['desc']) {
			echo '<p class="description">' . esc_html($cfg['desc']) . '</p>';
		}
	}

	public function field_checkbox($args)
	{
		$key = $args['key'];
		$checked = checked(true, (bool) IGIT_RPWT_Settings::get($key), false);
		$descriptions = array(
			'auto_show' => __('Automatically appends related posts after post content.', 'igit-related-posts-with-thumb-images-after-posts'),
			'show_thumbnail' => __('Display a thumbnail image for each related post.', 'igit-related-posts-with-thumb-images-after-posts'),
			'show_title' => __('Display the post title beneath the thumbnail.', 'igit-related-posts-with-thumb-images-after-posts'),
			'show_excerpt' => __('Display a short excerpt beneath each post title.', 'igit-related-posts-with-thumb-images-after-posts'),
			'show_date' => __('Show the publish date on each related post.', 'igit-related-posts-with-thumb-images-after-posts'),
			'show_reading_time' => __('Estimate reading time (avg. 200 wpm).', 'igit-related-posts-with-thumb-images-after-posts'),
			'show_comment_count' => __('Show the number of comments on each post.', 'igit-related-posts-with-thumb-images-after-posts'),
			'show_category_badge' => __('Overlay the primary category name on the thumbnail.', 'igit-related-posts-with-thumb-images-after-posts'),
			'link_nofollow' => __('Add rel="nofollow" to all related post links.', 'igit-related-posts-with-thumb-images-after-posts'),
			'load_async' => __('Load related posts via AJAX after the initial page load (reduces TTFB).', 'igit-related-posts-with-thumb-images-after-posts'),
			'enable_click_tracking' => __('Record clicks on related post links for analytics (stored in DB).', 'igit-related-posts-with-thumb-images-after-posts'),
			'multisite_search' => __('Include related posts from other sites in this network.', 'igit-related-posts-with-thumb-images-after-posts'),
			'rotate_results' => __('Show a different random selection from matching posts on each page load.', 'igit-related-posts-with-thumb-images-after-posts'),
			'show_query_time' => __('Display query execution time (in ms) next to the related posts heading. Useful for debugging; keep disabled in production.', 'igit-related-posts-with-thumb-images-after-posts'),
		);

		echo '<label class="igit-rpwt-toggle" for="' . esc_attr($key) . '">';
		printf(
			'<input type="checkbox" id="%1$s" name="%2$s[%1$s]" value="1" %3$s />',
			esc_attr($key),
			esc_attr(IGIT_RPWT_Settings::OPTION_KEY),
			$checked // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Value from checked() is safe markup.
		);
		echo '<span class="igit-rpwt-toggle-track"><span class="igit-rpwt-toggle-thumb"></span></span>';
		echo '</label>';

		if (isset($descriptions[$key])) {
			echo '<p class="description">' . esc_html($descriptions[$key]) . '</p>';
		}
	}

	/**
	 * Render a locked/disabled toggle for a Pro-only checkbox setting.
	 *
	 * Used when the Pro plugin is not active. Shows a greyed-out toggle with
	 * the standard Pro badge + upgrade CTA — consistent with field_post_types()
	 * and field_relate_taxonomies() locked previews.
	 *
	 * @param array $args Field args from add_settings_field() (expects 'key').
	 */
	public function field_pro_checkbox($args)
	{
		// Render a visually disabled toggle (not submitted, no hidden field needed
		// because sanitise() also forces this to false for free users).
		echo '<label class="igit-rpwt-toggle igit-rpwt-toggle--locked" style="opacity:0.5;cursor:not-allowed;">';
		echo '<input type="checkbox" disabled />';
		echo '<span class="igit-rpwt-toggle-track"><span class="igit-rpwt-toggle-thumb"></span></span>';
		echo '</label>';
		self::render_pro_notice();
	}

	public function field_layout($args)
	{
		$current = IGIT_RPWT_Settings::get('layout');
		$options = array(
			'grid' => __('Grid', 'igit-related-posts-with-thumb-images-after-posts'),
			'list' => __('List (vertical)', 'igit-related-posts-with-thumb-images-after-posts'),
			'compact' => __('Compact (text-only list)', 'igit-related-posts-with-thumb-images-after-posts'),
			'masonry' => __('Masonry', 'igit-related-posts-with-thumb-images-after-posts'),
			'carousel' => __('Carousel (horizontal scroll)', 'igit-related-posts-with-thumb-images-after-posts'),
			'chip' => __('Chip / Pill (compact inline)', 'igit-related-posts-with-thumb-images-after-posts'),
		);
		echo '<select id="layout" name="' . esc_attr(IGIT_RPWT_Settings::OPTION_KEY) . '[layout]">';
		foreach ($options as $value => $label) {
			printf(
				'<option value="%s" %s>%s</option>',
				esc_attr($value),
				selected($current, $value, false),
				esc_html($label)
			);
		}
		echo '</select>';
		echo '<p class="description" id="igit-rpwt-layout-hint"></p>';
	}

	public function field_relate_by($args)
	{
		$current = IGIT_RPWT_Settings::get('relate_by');
		$options = array(
			'both' => __('Category &amp; Tag (recommended)', 'igit-related-posts-with-thumb-images-after-posts'),
			'category' => __('Category only', 'igit-related-posts-with-thumb-images-after-posts'),
			'tag' => __('Tag only', 'igit-related-posts-with-thumb-images-after-posts'),
			'fulltext' => __('Content Similarity (Full-Text)', 'igit-related-posts-with-thumb-images-after-posts'),
			'author' => __('Same Author', 'igit-related-posts-with-thumb-images-after-posts'),
			'series' => __('Series', 'igit-related-posts-with-thumb-images-after-posts'),
		);
		echo '<select id="relate_by" name="' . esc_attr(IGIT_RPWT_Settings::OPTION_KEY) . '[relate_by]">';
		foreach ($options as $value => $label) {
			printf(
				'<option value="%s" %s>%s</option>',
				esc_attr($value),
				selected($current, $value, false),
				wp_kses_post($label)
			);
		}
		echo '</select>';
		echo '<p id="igit-rpwt-relate-by-desc" class="igit-rpwt-relate-by-desc"></p>';
	}

	public function field_thumbnail_size($args)
	{
		$current = IGIT_RPWT_Settings::get('thumbnail_size');
		$registered = get_intermediate_image_sizes();
		// Ensure our custom size is always listed.
		if (!in_array('igit-rpwt-thumb', $registered, true)) {
			array_unshift($registered, 'igit-rpwt-thumb');
		}
		echo '<select id="thumbnail_size" name="' . esc_attr(IGIT_RPWT_Settings::OPTION_KEY) . '[thumbnail_size]">';
		foreach ($registered as $size) {
			printf(
				'<option value="%s" %s>%s</option>',
				esc_attr($size),
				selected($current, $size, false),
				esc_html($size)
			);
		}
		echo '</select>';
		echo '<p class="description">' . esc_html__('"igit-rpwt-thumb" is the plugin\'s built-in 300×200 size.', 'igit-related-posts-with-thumb-images-after-posts') . '</p>';
	}

	public function field_image_picker($args)
	{
		$default_image = IGIT_RPWT_Settings::get('default_image');
		echo '<div class="igit-rpwt-image-picker">';
		printf(
			'<input type="url" id="default_image" name="%s[default_image]" value="%s" class="regular-text" placeholder="https://..." />',
			esc_attr(IGIT_RPWT_Settings::OPTION_KEY),
			esc_attr($default_image)
		);
		echo ' <button type="button" class="button igit-rpwt-upload-btn" data-target="#default_image">'
			. esc_html__('Choose Image', 'igit-related-posts-with-thumb-images-after-posts')
			. '</button>';
		if ($default_image) {
			echo '<br><img src="' . esc_url($default_image) . '" style="max-width:120px;margin-top:6px;border-radius:4px;" />';
		}
		echo '</div>';
		echo '<p class="description">' . esc_html__('Shown when a related post has no image.', 'igit-related-posts-with-thumb-images-after-posts') . '</p>';
	}

	public function field_heading_level($args)
	{
		$current = IGIT_RPWT_Settings::get('heading_level');
		$options = array('h2' => 'H2', 'h3' => 'H3', 'h4' => 'H4');
		echo '<select id="heading_level" name="' . esc_attr(IGIT_RPWT_Settings::OPTION_KEY) . '[heading_level]">';
		foreach ($options as $value => $label) {
			printf('<option value="%s" %s>%s</option>', esc_attr($value), selected($current, $value, false), esc_html($label));
		}
		echo '</select>';
		echo '<p class="description">' . esc_html__('HTML heading tag wrapping the section heading text.', 'igit-related-posts-with-thumb-images-after-posts') . '</p>';
	}

	public function field_link_target($args)
	{
		$current = IGIT_RPWT_Settings::get('link_target');
		$options = array(
			'same' => __('Same tab', 'igit-related-posts-with-thumb-images-after-posts'),
			'new' => __('New tab (_blank)', 'igit-related-posts-with-thumb-images-after-posts'),
		);
		echo '<select id="link_target" name="' . esc_attr(IGIT_RPWT_Settings::OPTION_KEY) . '[link_target]">';
		foreach ($options as $value => $label) {
			printf('<option value="%s" %s>%s</option>', esc_attr($value), selected($current, $value, false), esc_html($label));
		}
		echo '</select>';
	}

	public function field_fallback_mode($args)
	{
		$current = IGIT_RPWT_Settings::get('fallback_mode');
		$options = array(
			'random' => __('Random posts', 'igit-related-posts-with-thumb-images-after-posts'),
			'recent' => __('Most recent posts', 'igit-related-posts-with-thumb-images-after-posts'),
			'popular' => __('Most commented posts', 'igit-related-posts-with-thumb-images-after-posts'),
			'none' => __('None (show nothing)', 'igit-related-posts-with-thumb-images-after-posts'),
		);
		echo '<select id="fallback_mode" name="' . esc_attr(IGIT_RPWT_Settings::OPTION_KEY) . '[fallback_mode]">';
		foreach ($options as $value => $label) {
			printf('<option value="%s" %s>%s</option>', esc_attr($value), selected($current, $value, false), esc_html($label));
		}
		echo '</select>';
		echo '<p class="description">' . esc_html__('Shown when no taxonomy-matched related posts are found.', 'igit-related-posts-with-thumb-images-after-posts') . '</p>';
	}

	public function field_textarea($args)
	{
		$key = $args['key'];
		$value = IGIT_RPWT_Settings::get($key);
		printf(
			'<textarea id="%1$s" name="%2$s[%1$s]" rows="6" class="large-text igit-rpwt-textarea">%3$s</textarea>',
			esc_attr($key),
			esc_attr(IGIT_RPWT_Settings::OPTION_KEY),
			esc_textarea($value)
		);
		echo '<p class="description">' . esc_html__('Extra CSS applied only to the related posts widget. Scoped automatically.', 'igit-related-posts-with-thumb-images-after-posts') . '</p>';
	}

	public function field_post_types($args)
	{
		$opt_key = esc_attr(IGIT_RPWT_Settings::OPTION_KEY);

		if (!igit_rpwt_is_pro()) {
			// Classify all public post types: built-in (interactive) vs CPT (locked placeholder).
			$builtin_types = array('post', 'page', 'attachment', 'revision', 'nav_menu_item');
			$selected = (array) IGIT_RPWT_Settings::get('post_types');
			$all_types = get_post_types(array('public' => true), 'objects');

			echo '<div class="igit-rpwt-checkbox-grid">';
			foreach ($all_types as $pt) {
				if (in_array($pt->name, $builtin_types, true)) {
					// Built-in post types: interactive — free users can select these.
					$slug = esc_attr($pt->name);
					$label = esc_html($pt->label);
					$checked = in_array($pt->name, $selected, true) ? ' checked' : '';
					echo '<label class="igit-rpwt-checkbox-item">' . "<input type=\"checkbox\" name=\"{$opt_key}[post_types][]\" value=\"{$slug}\"{$checked} /><span>{$label}</span></label>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $opt_key/$slug are esc_attr()d; $checked is a safe string; $label is esc_html()d.
				} else {
					// Custom post types: locked/disabled placeholder — Pro feature.
					echo '<label class="igit-rpwt-checkbox-item igit-rpwt-checkbox-item--locked">';
					echo '<input type="checkbox" disabled />';
					echo '<span>' . esc_html($pt->label) . '</span>';
					echo '</label>';
				}
			}
			echo '</div>';

			$upgrade_url = function_exists('igit_rpwt_fs') ? igit_rpwt_fs()->get_upgrade_url() : '#';
			if (defined('IGIT_RPWT_PRO_MONTHLY_PRICE')) {
				/* translators: %s: monthly price, e.g. $6.99 */
				$upgrade_label = sprintf(__('Pro version — just %s/mo', 'igit-related-posts-with-thumb-images-after-posts'), IGIT_RPWT_PRO_MONTHLY_PRICE);
			} else {
				$upgrade_label = __('Pro version', 'igit-related-posts-with-thumb-images-after-posts');
			}
			echo '<p class="description">' . wp_kses(
				sprintf(
					/* translators: %1$s: opening <a> tag, %2$s: link label e.g. "Pro version — just $6.99/mo", %3$s: closing </a> tag */
					__('Custom post type support is available in the %1$s%2$s%3$s.', 'igit-related-posts-with-thumb-images-after-posts'),
					'<a href="' . esc_url($upgrade_url) . '" target="_blank" rel="noopener noreferrer" class="igit-rpwt-upgrade-link">',
					$upgrade_label,
					'</a>'
				),
				array('a' => array('href' => array(), 'target' => array(), 'rel' => array(), 'class' => array()))
			) . '</p>';
			return;
		}

		$selected = (array) IGIT_RPWT_Settings::get('post_types');
		$all_types = get_post_types(array('public' => true), 'objects');
		echo '<div class="igit-rpwt-checkbox-grid">';
		foreach ($all_types as $pt) {
			$slug = esc_attr($pt->name);
			$label = esc_html($pt->label);
			$checked = in_array($pt->name, $selected, true) ? ' checked' : '';
			echo '<label class="igit-rpwt-checkbox-item">' . "<input type=\"checkbox\" name=\"{$opt_key}[post_types][]\" value=\"{$slug}\"{$checked} /><span>{$label}</span></label>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $opt_key/$slug are esc_attr()d; $checked is a safe string literal; $label is esc_html()d.
		}
		echo '</div>';
		echo '<p class="description">' . esc_html__('Post types to include when querying related posts.', 'igit-related-posts-with-thumb-images-after-posts') . '</p>';
	}

	public function field_relate_taxonomies($args)
	{
		$selected = (array) IGIT_RPWT_Settings::get('relate_taxonomies');
		$all_tax = get_taxonomies(array('public' => true), 'objects');
		$opt_key = esc_attr(IGIT_RPWT_Settings::OPTION_KEY);

		// Classify each public taxonomy into built-in vs CPT-only.
		// Built-in: registered to at least one of the core WP post types (free feature).
		// CPT-only: registered exclusively to non-built-in post types (Pro feature).
		$builtin_types = array('post', 'page', 'attachment', 'revision', 'nav_menu_item');
		$builtin_taxonomies = array();
		$cpt_taxonomies = array();

		foreach ($all_tax as $tax) {
			if (!empty(array_intersect((array) $tax->object_type, $builtin_types))) {
				$builtin_taxonomies[] = $tax;
			} else {
				$cpt_taxonomies[] = $tax;
			}
		}

		// ── Built-in taxonomies: always interactive ───────────────────────────────
		echo '<div class="igit-rpwt-checkbox-grid">';
		foreach ($builtin_taxonomies as $tax) {
			$slug = esc_attr($tax->name);
			$label = esc_html($tax->label);
			$checked = in_array($tax->name, $selected, true) ? ' checked' : '';
			echo '<label class="igit-rpwt-checkbox-item">' . "<input type=\"checkbox\" name=\"{$opt_key}[relate_taxonomies][]\" value=\"{$slug}\"{$checked} /><span>{$label}</span></label>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $opt_key/$slug are esc_attr()d; $checked is a safe string literal; $label is esc_html()d.
		}
		echo '</div>';

		// ── CPT taxonomies: Pro-gated ─────────────────────────────────────────────
		if (!empty($cpt_taxonomies)) {
			if (igit_rpwt_is_pro()) {
				/**
				 * Fires inside field_relate_taxonomies() when Pro is active.
				 * The Pro plugin hooks here to render interactive CPT taxonomy checkboxes,
				 * keeping all CPT checkbox HTML in the Pro codebase.
				 *
				 * @param object[] $cpt_taxonomies Taxonomy objects for non-built-in CPTs.
				 * @param array    $selected       Currently saved taxonomy slugs.
				 * @param string   $opt_key        esc_attr()'d settings option key for use in name attributes.
				 */
				do_action('igit_rpwt_cpt_taxonomies_field', $cpt_taxonomies, $selected, $opt_key);
			} else {
				// Free version: show locked preview of CPT taxonomies to encourage upgrade.
				echo '<div class="igit-rpwt-checkbox-grid igit-rpwt-checkbox-grid--locked" style="margin-top:6px;">';
				foreach ($cpt_taxonomies as $tax) {
					echo '<label class="igit-rpwt-checkbox-item igit-rpwt-checkbox-item--locked">';
					echo '<input type="checkbox" disabled />';
					echo '<span>' . esc_html($tax->label) . '</span>';
					echo '</label>';
				}
				echo '</div>';

				$upgrade_url = function_exists('igit_rpwt_fs') ? igit_rpwt_fs()->get_upgrade_url() : '#';
				if (defined('IGIT_RPWT_PRO_MONTHLY_PRICE')) {
					/* translators: %s: monthly price, e.g. $6.99 */
					$upgrade_label = sprintf(__('Pro version — just %s/mo', 'igit-related-posts-with-thumb-images-after-posts'), IGIT_RPWT_PRO_MONTHLY_PRICE);
				} else {
					$upgrade_label = __('Pro version', 'igit-related-posts-with-thumb-images-after-posts');
				}
				echo '<p class="description" style="margin-top:4px;">' . wp_kses(
					sprintf(
						/* translators: %1$s: opening <a> tag, %2$s: link label e.g. "Pro version — just $6.99/mo", %3$s: closing </a> tag */
						__('Taxonomies for custom post types are available in the %1$s%2$s%3$s.', 'igit-related-posts-with-thumb-images-after-posts'),
						'<a href="' . esc_url($upgrade_url) . '" target="_blank" rel="noopener noreferrer" class="igit-rpwt-upgrade-link">',
						$upgrade_label,
						'</a>'
					),
					array('a' => array('href' => array(), 'target' => array(), 'rel' => array(), 'class' => array()))
				) . '</p>';
			}
		}

		echo '<p class="description">' . esc_html__('Taxonomies used to find matching related posts. Works alongside the &ldquo;Find Related Posts By&rdquo; filter above.', 'igit-related-posts-with-thumb-images-after-posts') . '</p>';
	}

	public function field_exclude_cats($args)
	{
		$selected = IGIT_RPWT_Settings::get('exclude_categories') ?: array();
		echo '<div class="igit-rpwt-cat-list">';
		wp_terms_checklist(0, array(
			'taxonomy' => 'category',
			'selected_cats' => array_map('absint', $selected),
			'checked_ontop' => false,
			'walker' => null,
			'echo' => true,
		));
		echo '</div>';
		echo '<p class="description">' . esc_html__('Posts in checked categories will not appear in related posts.', 'igit-related-posts-with-thumb-images-after-posts') . '</p>';
		// Rename the default checklist inputs to our option key.
		?>
		<script>
			document.addEventListener('DOMContentLoaded', function () {
				document.querySelectorAll('.igit-rpwt-cat-list input[type="checkbox"]').forEach(function (cb) {
					cb.name = '<?php echo esc_js(IGIT_RPWT_Settings::OPTION_KEY); ?>[exclude_categories][]';
				});
			});
		</script>
		<?php
	}

	// ── Page renderer ────────────────────────────────────────────────────────

	/**
	 * Output the settings page template.
	 */
	/**
	 * Handle the manual "Flush Cache" button POST action.
	 */
	public function handle_flush_cache()
	{
		if (!isset($_POST['igit_rpwt_flush_cache'])) {
			return;
		}
		check_admin_referer('igit_rpwt_flush_cache_action', 'igit_rpwt_flush_cache_nonce');
		if (!current_user_can('manage_options')) {
			return;
		}
		IGIT_RPWT_Query::flush_all_cache();
		IGIT_RPWT_Settings::flush_cache();
		wp_safe_redirect(
			add_query_arg(
				array(
					'page' => self::PAGE_SLUG,
					'cache-flushed' => '1',
				),
				admin_url('admin.php')
			)
		);
		exit;
	}

	public function render_settings_page()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to access this page.', 'igit-related-posts-with-thumb-images-after-posts'));
		}

		// After settings save, flush the related-posts cache so changes take effect immediately.
		if (isset($_GET['settings-updated']) && sanitize_key(wp_unslash($_GET['settings-updated']))) { // phpcs:ignore WordPress.Security.NonceVerification
			IGIT_RPWT_Settings::flush_cache();
			IGIT_RPWT_Query::flush_all_cache();
		}

		// Show confirmation notice after manual flush.
		$flushed = isset($_GET['cache-flushed']) && '1' === $_GET['cache-flushed']; // phpcs:ignore WordPress.Security.NonceVerification

		// Import status from redirect.
		$import_status = isset($_GET['import-status']) ? sanitize_key($_GET['import-status']) : ''; // phpcs:ignore WordPress.Security.NonceVerification

		include IGIT_RPWT_PLUGIN_DIR . 'admin/views/settings-page.php';
	}

	// ── Import / Export ─────────────────────────────────────────────────────

	/**
	 * Handle settings export — outputs a JSON file download.
	 */
	public function handle_export_settings()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to export settings.', 'igit-related-posts-with-thumb-images-after-posts'));
		}
		check_admin_referer('igit_rpwt_export_action', 'igit_rpwt_export_nonce');

		$settings = IGIT_RPWT_Settings::get_all();
		$filename = 'igit-rpwt-settings-' . gmdate('Ymd-His') . '.json';

		header('Content-Type: application/json; charset=utf-8');
		header('Content-Disposition: attachment; filename="' . $filename . '"');
		header('Cache-Control: no-store, no-cache, must-revalidate');
		header('Pragma: no-cache');

		// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		echo wp_json_encode($settings, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
		exit;
	}

	/**
	 * Handle settings import — reads an uploaded JSON file and saves.
	 */
	public function handle_import_settings()
	{
		if (!current_user_can('manage_options')) {
			wp_die(esc_html__('You do not have permission to import settings.', 'igit-related-posts-with-thumb-images-after-posts'));
		}
		check_admin_referer('igit_rpwt_import_action', 'igit_rpwt_import_nonce');

		$redirect_base = add_query_arg(
			array('page' => self::PAGE_SLUG),
			admin_url('admin.php')
		);

		// Validate file upload.
		$file = isset($_FILES['igit_rpwt_import_file']) ? $_FILES['igit_rpwt_import_file'] : null; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput
		if (!$file || UPLOAD_ERR_OK !== (int) $file['error']) {
			wp_safe_redirect(add_query_arg('import-status', 'no-file', $redirect_base));
			exit;
		}

		// Validate file extension.
		$ext = strtolower(pathinfo(sanitize_file_name($file['name']), PATHINFO_EXTENSION));
		if ('json' !== $ext) {
			wp_safe_redirect(add_query_arg('import-status', 'invalid', $redirect_base));
			exit;
		}

		// Read and decode.
		// phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		$content = file_get_contents($file['tmp_name']);
		if (false === $content) {
			wp_safe_redirect(add_query_arg('import-status', 'invalid', $redirect_base));
			exit;
		}

		$raw = json_decode($content, true);
		if (!is_array($raw) || empty($raw)) {
			wp_safe_redirect(add_query_arg('import-status', 'invalid', $redirect_base));
			exit;
		}

		// Sanitise via the settings class and persist.
		IGIT_RPWT_Settings::save($raw);
		IGIT_RPWT_Query::flush_all_cache();

		wp_safe_redirect(add_query_arg('import-status', 'success', $redirect_base));
		exit;
	}

	// ── AJAX ─────────────────────────────────────────────────────────────────

	/**
	 * AJAX handler: save plugin settings.
	 */
	public function ajax_save_settings()
	{
		if (!check_ajax_referer('igit_rpwt_ajax_save', '_ajax_nonce', false)) {
			wp_send_json_error(array('message' => __('Security check failed.', 'igit-related-posts-with-thumb-images-after-posts')), 400);
		}

		if (!current_user_can('manage_options')) {
			wp_send_json_error(array('message' => __('You do not have permission to do this.', 'igit-related-posts-with-thumb-images-after-posts')), 403);
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Missing,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitised via IGIT_RPWT_Settings::sanitise() on the next line.
		$raw = isset($_POST[IGIT_RPWT_Settings::OPTION_KEY]) ? (array) wp_unslash($_POST[IGIT_RPWT_Settings::OPTION_KEY]) : array();
		$sanitized = IGIT_RPWT_Settings::sanitise($raw);

		update_option(IGIT_RPWT_Settings::OPTION_KEY, $sanitized);
		IGIT_RPWT_Settings::flush_cache();
		IGIT_RPWT_Query::flush_all_cache();

		wp_send_json_success(array('message' => __('Settings saved.', 'igit-related-posts-with-thumb-images-after-posts')));
	}

	// ── Assets ───────────────────────────────────────────────────────────────

	/**
	 * Enqueue admin scripts and styles on the plugin settings page only.
	 *
	 * @param string $hook Current admin page hook.
	 */
	public function enqueue_assets($hook)
	{
		if ('toplevel_page_' . self::PAGE_SLUG !== $hook) {
			return;
		}

		wp_enqueue_style(
			'igit-rpwt-admin',
			IGIT_RPWT_PLUGIN_URL . 'assets/css/admin.css',
			array(),
			IGIT_RPWT_VERSION
		);

		// Always load analytics styles so the Pro feature preview renders correctly in free.
		wp_enqueue_style(
			'igit-rpwt-analytics',
			IGIT_RPWT_PLUGIN_URL . 'assets/css/analytics.css',
			array(),
			IGIT_RPWT_VERSION
		);

		wp_enqueue_media();

		wp_enqueue_script(
			'igit-rpwt-admin',
			IGIT_RPWT_PLUGIN_URL . 'assets/js/admin.js',
			array('jquery', 'media-upload'),
			IGIT_RPWT_VERSION,
			true
		);

		wp_localize_script('igit-rpwt-admin', 'igitRpwtAdmin', array(
			'ajaxUrl' => admin_url('admin-ajax.php'),
			'nonce' => wp_create_nonce('igit_rpwt_ajax_save'),
			'clearNonce' => igit_rpwt_is_pro() ? wp_create_nonce('igit_rpwt_clear_analytics') : '',
			'theme' => get_user_meta(get_current_user_id(), 'igit_rpwt_admin_theme', true) ?: 'indigo',
			'i18n' => array(
				'saved' => __('Settings saved.', 'igit-related-posts-with-thumb-images-after-posts'),
				'saving' => __('Saving…', 'igit-related-posts-with-thumb-images-after-posts'),
				'error' => __('Something went wrong. Please try again.', 'igit-related-posts-with-thumb-images-after-posts'),
				'clearConfirm' => __('Delete ALL analytics data? This cannot be undone.', 'igit-related-posts-with-thumb-images-after-posts'),
				'cleared' => __('All analytics data deleted.', 'igit-related-posts-with-thumb-images-after-posts'),
				'clearing' => __('Deleting…', 'igit-related-posts-with-thumb-images-after-posts'),
			),
		));
	}

	// ── Plugin action links ──────────────────────────────────────────────────

	/**
	 * Add a "Settings" link on the Plugins list page.
	 *
	 * @param array $links
	 * @return array
	 */
	public function action_links($links)
	{
		$settings_link = sprintf(
			'<a href="%s">%s</a>',
			esc_url(admin_url('admin.php?page=' . self::PAGE_SLUG)),
			esc_html__('Settings', 'igit-related-posts-with-thumb-images-after-posts')
		);
		array_unshift($links, $settings_link);
		return $links;
	}

	// ── AJAX: admin theme preference ─────────────────────────────────────────

	/**
	 * Save the current admin user's colour-theme preference to user meta.
	 *
	 * Hooked to wp_ajax_igit_rpwt_save_theme.
	 * Re-uses the igit_rpwt_ajax_save nonce to avoid an extra nonce registration.
	 */
	public function ajax_save_theme()
	{
		check_ajax_referer('igit_rpwt_ajax_save', '_ajax_nonce');

		if (!current_user_can('manage_options')) {
			wp_send_json_error(null, 403);
		}

		$theme = isset($_POST['theme']) ? sanitize_key(wp_unslash($_POST['theme'])) : '';
		if (!$theme) {
			wp_send_json_error(array('message' => 'Missing theme.'), 400);
		}

		update_user_meta(get_current_user_id(), 'igit_rpwt_admin_theme', $theme);
		wp_send_json_success();
	}

	// ── Post Nudges tab ────────────────────────────────────────────────

	/**
	 * Section callback: Post Nudges tab shown in free version.
	 * Renders a static preview of all three notification styles with a PRO upgrade CTA.
	 */
	public static function render_nudges_preview()
	{
		self::render_pro_notice();
		?>
		<p style="margin:0 0 20px 20px;color:var(--igit-text-muted);font-size:13px;">
			<?php esc_html_e('Post Nudges display floating notification cards that cycle through your posts/Custom Posts Types. Choose from three styles and four corner positions.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
		</p>
		<div class="igit-rpwt-nudge-preview-wrap">

			<?php /* ── Compact Style ──────────────────────── */ ?>
			<div class="igit-rpwt-nudge-preview">
				<span
					class="igit-rpwt-nudge-preview__label"><?php esc_html_e('Compact', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
				<div class="igit-rpwt-nudge igit-rpwt-nudge--compact igit-rpwt-nudge-preview__card">
					<div class="igit-rpwt-nudge__thumb-wrap">
						<div class="igit-rpwt-nudge__thumb-placeholder"></div>
					</div>
					<div class="igit-rpwt-nudge__body">
						<span
							class="igit-rpwt-nudge__label"><?php esc_html_e('You might also like', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
						<span
							class="igit-rpwt-nudge__title"><?php esc_html_e('10 Tips for Faster WordPress Sites', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
						<span class="igit-rpwt-nudge__meta">&#9201; 4 min &middot; Performance</span>
					</div>
					<div class="igit-rpwt-nudge__actions">
						<button class="igit-rpwt-nudge__skip"
							type="button"><?php esc_html_e('Skip', 'igit-related-posts-with-thumb-images-after-posts'); ?></button>
						<button class="igit-rpwt-nudge__close" type="button"
							aria-label="<?php esc_attr_e('Dismiss', 'igit-related-posts-with-thumb-images-after-posts'); ?>">&times;</button>
					</div>
				</div>
			</div>

			<?php /* ── Card Style ────────────────────────── */ ?>
			<div class="igit-rpwt-nudge-preview">
				<span
					class="igit-rpwt-nudge-preview__label"><?php esc_html_e('Card', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
				<div class="igit-rpwt-nudge igit-rpwt-nudge--card igit-rpwt-nudge-preview__card">
					<button class="igit-rpwt-nudge__close igit-rpwt-nudge__close--card" type="button"
						aria-label="<?php esc_attr_e('Dismiss', 'igit-related-posts-with-thumb-images-after-posts'); ?>">&times;</button>
					<div class="igit-rpwt-nudge__card-thumb">
						<div class="igit-rpwt-nudge__thumb-placeholder igit-rpwt-nudge__thumb-placeholder--card"></div>
						<span class="igit-rpwt-nudge__cat-badge">SEO</span>
					</div>
					<div class="igit-rpwt-nudge__card-body">
						<span
							class="igit-rpwt-nudge__label"><?php esc_html_e('You might also like', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
						<span
							class="igit-rpwt-nudge__title"><?php esc_html_e('How to Rank #1 on Google in 2026', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
						<span class="igit-rpwt-nudge__meta">&#9201; 5 min &middot; Mar 10, 2026</span>
						<a href="#" class="igit-rpwt-nudge__read-btn"
							onclick="return false;"><?php esc_html_e('Read Article →', 'igit-related-posts-with-thumb-images-after-posts'); ?></a>
					</div>
					<button class="igit-rpwt-nudge__skip igit-rpwt-nudge__skip--card"
						type="button"><?php esc_html_e('Skip', 'igit-related-posts-with-thumb-images-after-posts'); ?></button>
				</div>
			</div>

			<?php /* ── Minimal Style ─────────────────────── */ ?>
			<div class="igit-rpwt-nudge-preview">
				<span
					class="igit-rpwt-nudge-preview__label"><?php esc_html_e('Minimal', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
				<div class="igit-rpwt-nudge igit-rpwt-nudge--minimal igit-rpwt-nudge-preview__card">
					<span class="igit-rpwt-nudge__minimal-icon">&#128161;</span>
					<span
						class="igit-rpwt-nudge__minimal-text"><?php esc_html_e('You might like → Ultimate CSS Grid Guide', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					<button class="igit-rpwt-nudge__close" type="button"
						aria-label="<?php esc_attr_e('Dismiss', 'igit-related-posts-with-thumb-images-after-posts'); ?>">&times;</button>
				</div>
			</div>

		</div><!-- .igit-rpwt-nudge-preview-wrap -->
		<?php
	}

	// ── Integrations tab ────────────────────────────────────────────────

	/**
	 * Section callback: Integrations tab — all embedding methods in one place.
	 * Free tier shows Classic Widget + Shortcode (available now).
	 * Pro tier shows Gutenberg Block + Elementor Widget (locked in free).
	 */
	public static function render_integrations_preview()
	{
		// Both the Gutenberg Block and the Elementor Widget are PRO-only features.
		// They are only available when the Pro plugin is installed and active.
		$is_pro = igit_rpwt_is_pro();
		$block_active = $is_pro;
		$elementor_unlocked = $is_pro;  // PRO active; Elementor itself may or may not be installed
		$elementor_active = $is_pro && class_exists('\Elementor\Plugin');
		?>
		<div class="igit-rpwt-integrations-wrap">

			<?php /* ── Classic Widget (Free) ─────────────────────────────── */ ?>
			<div class="igit-rpwt-integration-card igit-rpwt-integration-card--free">
				<div class="igit-rpwt-integration-card__header">
					<span
						class="igit-rpwt-integration-badge igit-rpwt-integration-badge--free"><?php esc_html_e('FREE', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					<h3><?php esc_html_e('Classic Widget', 'igit-related-posts-with-thumb-images-after-posts'); ?></h3>
				</div>
				<p><?php esc_html_e('Add the Related Posts widget to any classic widget area (sidebar, footer, etc.) via Appearance → Widgets.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
				</p>
				<div class="igit-rpwt-integration-card__code">
					<?php esc_html_e('Appearance → Widgets → Related Posts', 'igit-related-posts-with-thumb-images-after-posts'); ?>
				</div>
				<a href="<?php echo esc_url(admin_url('widgets.php')); ?>"
					class="button button-secondary igit-rpwt-integration-card__btn">
					<?php esc_html_e('Open Widgets', 'igit-related-posts-with-thumb-images-after-posts'); ?>
				</a>
			</div>

			<?php /* ── Shortcode (Free) ──────────────────────────────────── */ ?>
			<div class="igit-rpwt-integration-card igit-rpwt-integration-card--free">
				<div class="igit-rpwt-integration-card__header">
					<span
						class="igit-rpwt-integration-badge igit-rpwt-integration-badge--free"><?php esc_html_e('FREE', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					<h3><?php esc_html_e('Shortcode', 'igit-related-posts-with-thumb-images-after-posts'); ?></h3>
				</div>
				<p><?php esc_html_e('Paste the shortcode anywhere in your post or page content to embed related posts at a specific location.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
				</p>
				<div class="igit-rpwt-integration-card__code">[igit_related_posts]</div>
				<p class="description">
					<?php esc_html_e('Optional: count="5" layout="grid"', 'igit-related-posts-with-thumb-images-after-posts'); ?>
				</p>
			</div>

			<?php /* ── Gutenberg Block (Pro) ───────────────────────────── */ ?>
			<div
				class="igit-rpwt-integration-card <?php echo $block_active ? 'igit-rpwt-integration-card--pro-active' : 'igit-rpwt-integration-card--pro-locked'; ?>">
				<div class="igit-rpwt-integration-card__header">
					<?php if ($block_active): ?>
						<span
							class="igit-rpwt-integration-badge igit-rpwt-integration-badge--active"><?php esc_html_e('ACTIVE', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					<?php else: ?>
						<span
							class="igit-rpwt-integration-badge igit-rpwt-integration-badge--pro"><?php esc_html_e('PRO', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					<?php endif; ?>
					<h3><?php esc_html_e('Gutenberg Block', 'igit-related-posts-with-thumb-images-after-posts'); ?></h3>
				</div>
				<?php if ($block_active): ?>
					<p><?php esc_html_e('Active. Search for “Related Posts” in the Gutenberg block inserter.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
					</p>
				<?php else: ?>
					<div class="igit-rpwt-feature-preview">
						<p><?php esc_html_e('Place a Related Posts block directly inside your post or page layout. Control post count and layout per block — without touching global settings.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
						</p>
						<div class="igit-rpwt-integration-card__code">&lt;!-- wp:igit-rpwt/related-posts
							{&quot;postCount&quot;:4,&quot;layout&quot;:&quot;grid&quot;} /--&gt;</div>
					</div>
					<?php
					/* translators: %s: monthly price, e.g. $6.99 */
					$igit_block_btn_label = defined('IGIT_RPWT_PRO_MONTHLY_PRICE') ? sprintf(__('Upgrade to Pro — just %s/mo →', 'igit-related-posts-with-thumb-images-after-posts'), IGIT_RPWT_PRO_MONTHLY_PRICE) : __('Upgrade to Pro →', 'igit-related-posts-with-thumb-images-after-posts');
					?>
					<a href="<?php echo esc_url(function_exists('igit_rpwt_fs') ? igit_rpwt_fs()->get_upgrade_url() : '#'); ?>"
						class="button button-primary igit-rpwt-upgrade-link igit-rpwt-integration-card__btn" target="_blank"
						rel="noopener noreferrer"><?php echo esc_html($igit_block_btn_label); ?></a>
				<?php endif; ?>
			</div>

			<?php /* ── Elementor Widget (Pro) ─────────────────────────── */ ?>
			<div
				class="igit-rpwt-integration-card <?php echo $elementor_unlocked ? 'igit-rpwt-integration-card--pro-active' : 'igit-rpwt-integration-card--pro-locked'; ?>">
				<div class="igit-rpwt-integration-card__header">
					<?php if ($elementor_active): ?>
						<span
							class="igit-rpwt-integration-badge igit-rpwt-integration-badge--active"><?php esc_html_e('ACTIVE', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					<?php elseif ($elementor_unlocked): ?>
						<span
							class="igit-rpwt-integration-badge igit-rpwt-integration-badge--active"><?php esc_html_e('AVAILABLE', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					<?php else: ?>
						<span
							class="igit-rpwt-integration-badge igit-rpwt-integration-badge--pro"><?php esc_html_e('PRO', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					<?php endif; ?>
					<h3><?php esc_html_e('Elementor Widget', 'igit-related-posts-with-thumb-images-after-posts'); ?></h3>
				</div>
				<?php if ($elementor_active): ?>
					<p><?php esc_html_e('Active. Find “Related Posts” under General in the Elementor widget panel.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
					</p>
				<?php elseif ($elementor_unlocked): ?>
					<p><?php esc_html_e('Unlocked with Pro. Install and activate the Elementor plugin to enable this widget.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
					</p>
				<?php else: ?>
					<div class="igit-rpwt-feature-preview">
						<p><?php esc_html_e('Drag and drop a Related Posts widget anywhere in your Elementor layout. Control post count, layout, thumbnail, and relation method per widget — independently from global settings.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
						</p>
						<div class="igit-rpwt-integration-card__code">
							<?php esc_html_e('Elementor → General → Related Posts', 'igit-related-posts-with-thumb-images-after-posts'); ?>
						</div>
					</div>
					<?php
					/* translators: %s: monthly price, e.g. $6.99 */
					$igit_elementor_btn_label = defined('IGIT_RPWT_PRO_MONTHLY_PRICE') ? sprintf(__('Upgrade to Pro — just %s/mo →', 'igit-related-posts-with-thumb-images-after-posts'), IGIT_RPWT_PRO_MONTHLY_PRICE) : __('Upgrade to Pro →', 'igit-related-posts-with-thumb-images-after-posts');
					?>
					<a href="<?php echo esc_url(function_exists('igit_rpwt_fs') ? igit_rpwt_fs()->get_upgrade_url() : '#'); ?>"
						class="button button-primary igit-rpwt-upgrade-link igit-rpwt-integration-card__btn" target="_blank"
						rel="noopener noreferrer"><?php echo esc_html($igit_elementor_btn_label); ?></a>
				<?php endif; ?>
			</div>

		</div>
		<?php
	}

	// ── Pro feature previews ─────────────────────────────────────────────

	/**
	 * Section callback: Performance tab teaser shown in free version.
	 */
	public static function render_performance_preview()
	{
		self::render_pro_notice();
		?>
		<div class="igit-rpwt-feature-preview">
			<div class="igit-rpwt-tracking-row">
				<span
					class="igit-rpwt-tracking-label"><?php esc_html_e('Async Loading', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
				<label class="igit-rpwt-toggle">
					<input type="checkbox" checked disabled />
					<span class="igit-rpwt-toggle-track"><span class="igit-rpwt-toggle-thumb"></span></span>
				</label>
				<p class="description">
					<?php esc_html_e('When enabled, related posts are loaded via a background AJAX request after the main page has already been delivered to the browser — instead of being included in the initial HTML response.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
					<br><br>
					<strong><?php esc_html_e('How it reduces TTFB:', 'igit-related-posts-with-thumb-images-after-posts'); ?></strong>
					<?php esc_html_e('TTFB (Time To First Byte) measures how long it takes for the server to start sending the page. Building related posts requires database queries. By deferring those queries to a separate AJAX call, the server sends the main page faster — reducing TTFB and improving your Core Web Vitals score.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
					<br><br>
					<strong><?php esc_html_e('Benefits for your site:', 'igit-related-posts-with-thumb-images-after-posts'); ?></strong>
					<?php esc_html_e('Faster perceived load times for visitors, better compatibility with full-page caching plugins (the cached HTML is served instantly while related posts load separately), and improved Google PageSpeed / Lighthouse scores.', 'igit-related-posts-with-thumb-images-after-posts'); ?>
				</p>
			</div>
		</div>
		<?php
	}

	/**
	 * Section callback: Analytics tab teaser shown in free version.
	 * Renders stat cards, bar chart, and top-posts table with sample data.
	 */
	public static function render_analytics_preview()
	{
		self::render_pro_notice();
		$heights = [5, 12, 8, 18, 30, 25, 15, 42, 55, 48, 38, 62, 70, 58, 45, 30, 40, 65, 80, 72, 58, 42, 68, 85, 90, 75, 60, 50, 38, 28];
		$preview_rows = [
			['title' => 'How to Speed Up Your WordPress Site', 'clicks' => 342, 'pct' => 100],
			['title' => '10 Essential SEO Tips for Beginners', 'clicks' => 289, 'pct' => 85],
			['title' => 'The Ultimate Guide to Content Marketing', 'clicks' => 198, 'pct' => 58],
		];
		?>
		<div class="igit-rpwt-feature-preview">
			<div class="igit-rpwt-tracking-row">
				<span
					class="igit-rpwt-tracking-label"><?php esc_html_e('Enable Click Tracking', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
				<label class="igit-rpwt-toggle">
					<input type="checkbox" checked disabled />
					<span class="igit-rpwt-toggle-track"><span class="igit-rpwt-toggle-thumb"></span></span>
				</label>
				<p class="description">
					<?php esc_html_e('Record clicks on related post links for analytics (stored in DB).', 'igit-related-posts-with-thumb-images-after-posts'); ?>
				</p>
			</div>
			<div class="igit-rpwt-analytics-tab-content">
				<div class="igit-rpwt-stat-cards">
					<div class="igit-rpwt-stat-card">
						<div class="igit-rpwt-stat-value">1,234</div>
						<div class="igit-rpwt-stat-label">
							<?php esc_html_e('Clicks (last 30 days)', 'igit-related-posts-with-thumb-images-after-posts'); ?>
						</div>
					</div>
					<div class="igit-rpwt-stat-card">
						<div class="igit-rpwt-stat-value">8,901</div>
						<div class="igit-rpwt-stat-label">
							<?php esc_html_e('Total Clicks (all time)', 'igit-related-posts-with-thumb-images-after-posts'); ?>
						</div>
					</div>
					<div class="igit-rpwt-stat-card">
						<div class="igit-rpwt-stat-value">47</div>
						<div class="igit-rpwt-stat-label">
							<?php esc_html_e('Posts Clicked (all time)', 'igit-related-posts-with-thumb-images-after-posts'); ?>
						</div>
					</div>
				</div>
				<div class="igit-rpwt-chart-card">
					<h2><?php esc_html_e('Click Activity', 'igit-related-posts-with-thumb-images-after-posts'); ?></h2>
					<div class="igit-rpwt-bar-chart">
						<?php foreach ($heights as $h): ?>
							<span class="igit-rpwt-bar-wrap">
								<span class="igit-rpwt-bar" style="height:<?php echo esc_attr(max(2, $h)); ?>%"></span>
							</span>
						<?php endforeach; ?>
					</div>
					<div class="igit-rpwt-chart-labels">
						<span><?php esc_html_e('30 days ago', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
						<span><?php esc_html_e('Today', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
					</div>
				</div>
				<div class="igit-rpwt-analytics-table-card">
					<h2><?php esc_html_e('Most Clicked Related Posts', 'igit-related-posts-with-thumb-images-after-posts'); ?>
					</h2>
					<table class="widefat striped igit-rpwt-analytics-table">
						<thead>
							<tr>
								<th scope="col">#</th>
								<th scope="col">
									<?php esc_html_e('Post', 'igit-related-posts-with-thumb-images-after-posts'); ?></th>
								<th scope="col">
									<?php esc_html_e('Clicks', 'igit-related-posts-with-thumb-images-after-posts'); ?></th>
								<th scope="col">
									<?php esc_html_e('Share', 'igit-related-posts-with-thumb-images-after-posts'); ?></th>
							</tr>
						</thead>
						<tbody>
							<?php foreach ($preview_rows as $i => $row): ?>
								<tr>
									<td class="igit-rpwt-rank"><?php echo esc_html($i + 1); ?></td>
									<td class="igit-rpwt-post-cell">
										<span class="igit-rpwt-post-info">
											<span class="igit-rpwt-post-title"><?php echo esc_html($row['title']); ?></span>
											<span
												class="igit-rpwt-post-type"><?php esc_html_e('Post', 'igit-related-posts-with-thumb-images-after-posts'); ?></span>
										</span>
									</td>
									<td class="igit-rpwt-click-count">
										<strong><?php echo esc_html(number_format_i18n($row['clicks'])); ?></strong></td>
									<td class="igit-rpwt-bar-cell">
										<span class="igit-rpwt-inline-bar"
											style="width:<?php echo esc_attr($row['pct']); ?>%"></span>
									</td>
								</tr>
							<?php endforeach; ?>
						</tbody>
					</table>
				</div>
			</div>
		</div>
		<?php
	}

	// ── Pro upgrade notice ───────────────────────────────────────────────

	/**
	 * Section callback shown in free version for Pro-only tabs.
	 */
	public static function render_pro_notice()
	{
		echo '<div class="igit-rpwt-pro-notice">';
		echo '<span class="igit-rpwt-pro-badge">' . esc_html__('PRO', 'igit-related-posts-with-thumb-images-after-posts') . '</span> ';
		echo '<strong>' . esc_html__('This feature is available in the Pro version.', 'igit-related-posts-with-thumb-images-after-posts') . '</strong> ';
		$upgrade_url = function_exists('igit_rpwt_fs') ? igit_rpwt_fs()->get_upgrade_url() : '#';
		if (defined('IGIT_RPWT_PRO_MONTHLY_PRICE')) {
			/* translators: %s: monthly price, e.g. $6.99 */
			$upgrade_label = sprintf(__('Upgrade to Pro — just %s/mo →', 'igit-related-posts-with-thumb-images-after-posts'), IGIT_RPWT_PRO_MONTHLY_PRICE);
		} else {
			$upgrade_label = __('Upgrade to Pro →', 'igit-related-posts-with-thumb-images-after-posts');
		}
		echo '<a href="' . esc_url($upgrade_url) . '" class="igit-rpwt-upgrade-link" target="_blank" rel="noopener noreferrer">' . esc_html($upgrade_label) . '</a>';
		echo '</div>';
	}
	// ── Helper ───────────────────────────────────────────────────────────────

	/**
	 * Register a settings field.
	 *
	 * @param string   $key
	 * @param string   $label
	 * @param string   $section
	 * @param callable $callback
	 */
	private function add_field($key, $label, $section, $callback)
	{
		add_settings_field(
			'igit_rpwt_' . $key,
			$label,
			$callback,
			self::PAGE_SLUG,
			$section,
			array('key' => $key, 'label_for' => $key)
		);
	}
}
