<?php
/**
 * This file is part of the Wisewand WordPress plugin.
 *
 * @package Wisewand
 * @since 1.0.0
 * @license GPL-2.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
namespace Wisewand\Admin;

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

use Wisewand\Utils\Options;
use Wisewand\Utils\DataForSEO_Universal;
use Wisewand\Logging\Logger;
use Wisewand\Admin\Traits\AJAX_Security;
use Wisewand\Admin\SEO\SEO_Handler_Context;
use Wisewand\Admin\SEO\SEO_Analysis_Handler;
use Wisewand\Admin\SEO\SEO_Keywords_Handler;
use Wisewand\Admin\SEO\SEO_Competitor_Handler;
use Wisewand\Admin\SEO\SEO_Clustering_Handler;
use Wisewand\Admin\SEO\SEO_AI_Matcher_Handler;

// phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_error_log, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange -- error_log() used within WP_DEBUG conditionals; table names derived from $wpdb->prefix are safe to interpolate; dynamic placeholder generation for IN clauses; all AJAX handlers verify nonce before processing $_POST data; direct database calls and schema changes required for custom plugin table operations

/**
 * SEO Intelligence Dashboard — Facade
 *
 * Admin page controller for keyword research, competitor analysis, and content
 * planning. Owns UI rendering, asset enqueueing, and repository initialisation.
 * All AJAX business logic is delegated to single-responsibility handler classes
 * in the Wisewand\Admin\SEO namespace:
 *
 * - SEO_Analysis_Handler   — domain analysis, snapshot loading, keyword discovery
 * - SEO_Keywords_Handler   — saved keyword library CRUD, enrichment, scheduling
 * - SEO_Competitor_Handler — competitor spy, spy-keyword saving, column prefs
 * - SEO_Clustering_Handler — deduplication scanning, cluster management, calendar
 * - SEO_AI_Matcher_Handler — AI category matching, author assignment, conflicts
 *
 * Handler files are lazy-loaded on first use via per-handler getter methods so
 * that pages that never trigger AJAX pay no load cost.
 *
 * @package Wisewand
 * @since 1.0.0
 */
class SEO_Intelligence_Real {

	use AJAX_Security;

	/**
	 * Plugin options wrapper
	 *
	 * @since 1.0.0
	 * @var Options
	 */
	private $options;

	/**
	 * Plugin logger
	 *
	 * @since 1.0.0
	 * @var Logger
	 */
	private $logger;

	/**
	 * DataForSEO API client (null when not configured)
	 *
	 * @since 1.0.0
	 * @var DataForSEO_Universal|null
	 */
	private $dataforseo_client;

	/**
	 * Normalised site domain (e.g. "example.com")
	 *
	 * @since 1.0.0
	 * @var string
	 */
	private $domain;

	/**
	 * SEO analysis repository
	 *
	 * @since 1.0.0
	 * @var \Wisewand\Repositories\SEO_Analysis_Repository
	 */
	private $seo_repository;

	/**
	 * Competitor analysis repository
	 *
	 * @since 1.0.0
	 * @var \Wisewand\Repositories\Competitor_Repository
	 */
	private $competitor_repository;

	/**
	 * Saved keywords repository
	 *
	 * @since 1.0.0
	 * @var \Wisewand\Repositories\Keyword_Repository
	 */
	private $keyword_repository;

	/**
	 * Editorial calendar repository
	 *
	 * @since 1.0.0
	 * @var \Wisewand\Repositories\Calendar_Repository
	 */
	private $calendar_repository;

	/**
	 * Rate limiter utility
	 *
	 * @since 1.0.0
	 * @var \Wisewand\Utils\Rate_Limiter
	 */
	private $rate_limiter;

	// =========================================================================
	// HANDLER INSTANCES (lazy-initialised)
	// =========================================================================

	/**
	 * Cached SEO handler context DTO
	 *
	 * @since 2.8.2
	 * @var SEO_Handler_Context|null
	 */
	private $handler_context;

	/**
	 * Cached analysis handler
	 *
	 * @since 2.8.2
	 * @var SEO_Analysis_Handler|null
	 */
	private $analysis_handler;

	/**
	 * Cached keywords handler
	 *
	 * @since 2.8.2
	 * @var SEO_Keywords_Handler|null
	 */
	private $keywords_handler;

	/**
	 * Cached competitor handler
	 *
	 * @since 2.8.2
	 * @var SEO_Competitor_Handler|null
	 */
	private $competitor_handler;

	/**
	 * Cached clustering handler
	 *
	 * @since 2.8.2
	 * @var SEO_Clustering_Handler|null
	 */
	private $clustering_handler;

	/**
	 * Cached AI matcher handler
	 *
	 * @since 2.8.2
	 * @var SEO_AI_Matcher_Handler|null
	 */
	private $ai_matcher_handler;

	// =========================================================================
	// CONSTRUCTOR
	// =========================================================================

	/**
	 * Initialise the facade: build repositories, detect domain, boot DataForSEO
	 *
	 * @since 1.0.0
	 *
	 * @param Options $options Plugin options wrapper.
	 * @param Logger  $logger  Plugin logger.
	 */
	public function __construct( Options $options, Logger $logger ) {
		$this->options = $options;
		$this->logger  = $logger;
		$this->domain  = $this->get_current_domain();
		$this->init_dataforseo_client();

		// Ensure database schemas are up to date using repositories
		if ( ! class_exists( 'Wisewand\\Repositories\\Keyword_Repository' ) ) {
			require_once WISEWAND_PLUGIN_DIR . 'includes/Repositories/Keyword_Repository.php';
		}
		$this->keyword_repository = new \Wisewand\Repositories\Keyword_Repository();
		$this->keyword_repository->ensure_schema();

		if ( ! class_exists( 'Wisewand\\Repositories\\Calendar_Repository' ) ) {
			require_once WISEWAND_PLUGIN_DIR . 'includes/Repositories/Calendar_Repository.php';
		}
		$this->calendar_repository = new \Wisewand\Repositories\Calendar_Repository();
		$this->calendar_repository->ensure_schema();

		if ( ! class_exists( 'Wisewand\\Repositories\\SEO_Analysis_Repository' ) ) {
			require_once WISEWAND_PLUGIN_DIR . 'includes/Repositories/SEO_Analysis_Repository.php';
		}
		$this->seo_repository = new \Wisewand\Repositories\SEO_Analysis_Repository();
		$this->seo_repository->ensure_schema();

		if ( ! class_exists( 'Wisewand\\Repositories\\Competitor_Repository' ) ) {
			require_once WISEWAND_PLUGIN_DIR . 'includes/Repositories/Competitor_Repository.php';
		}
		$this->competitor_repository = new \Wisewand\Repositories\Competitor_Repository();
		$this->competitor_repository->ensure_schema();
		$this->rate_limiter = new \Wisewand\Utils\Rate_Limiter( $this->logger );
	}

	// =========================================================================
	// UI / RENDERING
	// =========================================================================

	/**
	 * Render the SEO Intelligence admin page
	 *
	 * @since 1.0.0
	 */
	public function render_page() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'wisewand-ai-content-writer-seo-content-generator' ) );
		}

		echo '<div class="wrap seo-intelligence-real">';

		if ( ! $this->is_dataforseo_configured() ) {
			$this->render_setup_required();
		} else {
			$this->render_real_dashboard();
		}

		echo '</div>';
		$this->enqueue_real_assets();
	}

	/**
	 * Whether DataForSEO credentials are stored and valid
	 *
	 * @since 1.0.0
	 *
	 * @return bool
	 */
	private function is_dataforseo_configured() {
		return DataForSEO_Universal::is_configured();
	}

	/**
	 * Render the setup prompt shown when DataForSEO is not yet configured
	 *
	 * @since 1.0.0
	 */
	private function render_setup_required() {
		?>
		<div class="setup-hero">
			<h1>🚀 <?php esc_html_e( 'SEO Intelligence', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h1>
			<p><?php esc_html_e( 'Configure DataForSEO to analyze your website\'s SEO performance', 'wisewand-ai-content-writer-seo-content-generator' ); ?></p>
			<a href="<?php echo esc_url( admin_url( 'admin.php?page=wisewand-settings' ) ); ?>" class="cta-btn">
				⚙️ <?php esc_html_e( 'Configure DataForSEO', 'wisewand-ai-content-writer-seo-content-generator' ); ?>
			</a>
		</div>
		<?php
	}

	/**
	 * Render the full SEO Intelligence dashboard HTML
	 *
	 * @since 1.0.0
	 */
	private function render_real_dashboard() {
		$logo_url = plugin_dir_url( WISEWAND_PLUGIN_FILE ) . 'assets/images/logo-owl-white-black-background.png';
		?>
		<div class="real-dashboard">
			<!-- Brand Header with Logo -->
			<div class="brand-header" style="display: flex; align-items: center; gap: 24px; margin-bottom: 40px; padding-bottom: 24px; border-bottom: 1px solid rgba(0, 188, 212, 0.2);">
				<img src="<?php echo esc_url( $logo_url ); ?>" alt="Wisewand Logo" style="height: 56px; width: auto;" />
				<div>
					<h1 style="margin: 0 0 4px 0; font-size: 32px; font-weight: 700; color: var(--brand-white); letter-spacing: -0.02em;">
						<?php esc_html_e( 'SEO Intelligence', 'wisewand-ai-content-writer-seo-content-generator' ); ?>
					</h1>
					<p style="margin: 0; font-size: 14px; color: var(--brand-gray-light); font-weight: 500;">
						<?php
						/* translators: %s: Website domain name (e.g., 'example.com') */
						printf( esc_html__( 'Analyzing %s', 'wisewand-ai-content-writer-seo-content-generator' ), '<span style="color: var(--brand-primary); font-weight: 600;">' . esc_html( $this->domain ) . '</span>' );
						?>
					</p>
				</div>
				<div id="dataforseo-balance-badge" class="balance-badge" style="display:none;">
					<span class="balance-label"><?php esc_html_e( 'DataForSEO Balance:', 'wisewand-ai-content-writer-seo-content-generator' ); ?></span>
					<span id="dataforseo-balance-value" class="balance-value">&mdash;</span>
				</div>
			</div>

			<!-- Compact Actions Row -->
			<div class="actions-row">
				<div class="action-card">
					<div class="card-icon">🔍</div>
					<div class="card-content">
						<h4><?php esc_html_e( 'SEO Analysis', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h4>
						<p>
						<?php
							/* translators: %s: Website domain name (e.g., 'example.com') */
							printf( esc_html__( 'Analyze %s rankings', 'wisewand-ai-content-writer-seo-content-generator' ), '<strong>' . esc_html( $this->domain ) . '</strong>' );
						?>
							</p>
					</div>
					<div class="card-controls">
						<select id="market-selector" class="compact-select">
							<?php
							foreach ( \Wisewand\Config\Supported_Options::get_markets() as $value => $label ) {
								echo '<option value="' . esc_attr( $value ) . '">' . esc_html( $label ) . '</option>';
							}
							?>
						</select>
						<button type="button" id="run-analysis" class="card-action-btn">
							<?php esc_html_e( 'Run Analysis', 'wisewand-ai-content-writer-seo-content-generator' ); ?>
						</button>
					</div>
				</div>

				<div class="action-card">
					<div class="card-icon">💾</div>
					<div class="card-content">
						<h4><?php esc_html_e( 'Add Keywords', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h4>
						<p><?php esc_html_e( 'Build your keyword library', 'wisewand-ai-content-writer-seo-content-generator' ); ?></p>
					</div>
					<button type="button" id="open-add-keywords-modal" class="card-action-btn">
						<?php esc_html_e( 'Add Keywords', 'wisewand-ai-content-writer-seo-content-generator' ); ?>
					</button>
				</div>
			</div>

			<!-- Analysis Status Bar -->
			<div class="analysis-status" id="analysis-status" style="display: none;">
				<div class="status-progress">
					<div class="progress-bar">
						<div class="progress-fill" id="progress-fill"></div>
					</div>
					<div class="status-text" id="status-text"><?php esc_html_e( 'Starting analysis...', 'wisewand-ai-content-writer-seo-content-generator' ); ?></div>
				</div>
			</div>

			<!-- Roadmap Actions Row -->
			<div class="actions-row">
				<div class="action-card">
					<div class="card-icon">🔍</div>
					<div class="card-content">
						<h4><?php esc_html_e( 'Keyword Ideas', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h4>
						<p><?php esc_html_e( 'Discover new opportunities', 'wisewand-ai-content-writer-seo-content-generator' ); ?></p>
					</div>
					<button type="button" id="get-keyword-ideas" class="card-action-btn">
						<?php esc_html_e( 'Get Ideas', 'wisewand-ai-content-writer-seo-content-generator' ); ?>
					</button>
				</div>

				<div class="action-card">
					<div class="card-icon">🕵️</div>
					<div class="card-content">
						<h4><?php esc_html_e( 'Competitor Spy', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h4>
						<p><?php esc_html_e( 'Steal keywords from 1-3 competitors', 'wisewand-ai-content-writer-seo-content-generator' ); ?></p>
					</div>
					<button type="button" id="spy-competitors" class="card-action-btn">
						<?php esc_html_e( 'Spy Now', 'wisewand-ai-content-writer-seo-content-generator' ); ?>
					</button>
				</div>

				<div class="roadmap-cta-card">
					<div class="cta-content">
						<h3>🚀 <?php esc_html_e( 'Smart Roadmap Generator', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h3>
						<p><?php esc_html_e( 'Auto-schedule content for all available keywords', 'wisewand-ai-content-writer-seo-content-generator' ); ?></p>
					</div>
					<div class="roadmap-buttons-container" style="display: flex; gap: 12px; align-items: center; flex-wrap: wrap;">
						<button type="button" id="generate-all-roadmap" class="cta-btn">
							🚀 <?php esc_html_e( 'Generate All Keywords', 'wisewand-ai-content-writer-seo-content-generator' ); ?>
						</button>

						<button type="button" id="schedule-selected-roadmap" class="cta-btn" style="display:none; background: #059669;">
							📅 <?php esc_html_e( 'Schedule Selected', 'wisewand-ai-content-writer-seo-content-generator' ); ?> (<span class="selected-keywords-count">0</span>)
						</button>
					</div>
				</div>
			</div>

			<!-- Unified Keywords Table -->
			<div class="results-section">
				<div class="results-header">
					<h3><?php esc_html_e( '🎯 All Keywords', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h3>
					<div class="results-controls">
						<input type="search" id="keyword-search" placeholder="<?php esc_html_e( 'Search keywords...', 'wisewand-ai-content-writer-seo-content-generator' ); ?>" class="keyword-search-input">
						<select id="keyword-filter" class="keyword-filter-select">
							<option value="all"><?php esc_html_e( 'All Sources', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<option value="current"><?php esc_html_e( '📊 Current Rankings', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<option value="opportunities"><?php esc_html_e( '🔍 Opportunities', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<option value="saved"><?php esc_html_e( '💾 Saved (Manual)', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<option value="seed"><?php esc_html_e( '🌱 Seed Keywords', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<option value="ideas"><?php esc_html_e( '🆕 Keyword Ideas', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<option value="competitor_spy"><?php esc_html_e( '🕵️ Competitor Spy', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<option value="quick-wins"><?php esc_html_e( 'Quick Wins (11-20)', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<option value="high-volume"><?php esc_html_e( 'High Volume (1000+)', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
						</select>
						<select id="language-filter" class="keyword-filter-select">
							<option value="all"><?php esc_html_e( '🌍 All Languages', 'wisewand-ai-content-writer-seo-content-generator' ); ?></option>
							<?php
							foreach ( \Wisewand\Config\Supported_Options::get_languages() as $code => $lang ) {
								echo '<option value="' . esc_attr( $code ) . '">' . esc_html( $lang['flag'] . ' ' . $lang['name'] ) . '</option>';
							}
							?>
						</select>
						<button type="button" id="open-deduplication" class="keyword-filter-select" style="background: linear-gradient(135deg, var(--brand-purple) 0%, var(--brand-primary) 100%); color: var(--brand-white); border: 1px solid rgba(139, 92, 246, 0.5); cursor: pointer; padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 600; box-shadow: 0 2px 8px rgba(139, 92, 246, 0.3);">
							🔗 AI Semantic Deduplication
						</button>
						<button type="button" id="ai-match-categories" class="keyword-filter-select" style="background: linear-gradient(135deg, #10b981 0%, var(--brand-primary) 100%); color: var(--brand-white); border: 1px solid rgba(16, 185, 129, 0.5); cursor: pointer; padding: 8px 16px; border-radius: 6px; font-size: 13px; font-weight: 600; box-shadow: 0 2px 8px rgba(16, 185, 129, 0.3);">
							🤖 AI Match Categories
						</button>
						<button type="button" id="toggle-columns-btn" class="keyword-filter-select" style="background: var(--brand-card-bg); color: var(--brand-white); border: 1px solid rgba(0, 188, 212, 0.3); cursor: pointer; padding: 8px 12px; border-radius: 6px; font-size: 13px;">
							👁️ Columns
						</button>
						<button type="button" id="clear-all-calendar-btn" class="keyword-filter-select" style="background: var(--brand-error); color: var(--brand-white); border: 1px solid var(--brand-error); cursor: pointer; padding: 8px 12px; border-radius: 6px; font-size: 13px;">
							🗑️ Clear Calendar
						</button>
					</div>
				</div>

				<!-- Column Visibility Panel (Hidden by default) -->
				<div id="column-visibility-panel" style="display: none; background: var(--brand-card-bg); border: 1px solid rgba(0, 188, 212, 0.3); border-radius: 12px; padding: 16px; margin: 16px 24px; backdrop-filter: blur(10px);">
					<h4 style="margin: 0 0 12px 0; color: var(--brand-white); font-size: 14px; font-weight: 600;">👁️ Show/Hide Columns</h4>
					<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px;">
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="author" checked> 👤 Author
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="categories" checked> 📁 Categories
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="language" checked> 🌍 Language
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="position" checked> 📍 Position
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="change" checked> 📈 Change
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="page" checked> 📄 Page
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="volume" checked> 📊 Volume
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="difficulty" checked> ⚡ Difficulty
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="cpc" checked> 💰 CPC
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="competition" checked> 🎯 Competition
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="intent" checked> 🧠 Intent
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="priority" checked> 🎯 Priority
						</label>
						<label style="display: flex; align-items: center; gap: 8px; cursor: pointer; color: var(--brand-white); font-size: 13px;">
							<input type="checkbox" class="column-toggle" data-column="calendar" checked> 📅 Calendar
						</label>
					</div>
					<p style="margin: 12px 0 0 0; font-size: 11px; color: var(--brand-gray-light);">
						💡 Tip: Your preferences are automatically saved
					</p>
				</div>

				<div class="results-content" id="results-content">
					<div class="empty-state" id="initial-empty-state">
						<div class="empty-icon">📊</div>
						<h4><?php esc_html_e( 'Ready for SEO Analysis', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h4>
						<p><?php esc_html_e( 'Click "Run SEO Analysis" to discover your keyword rankings and opportunities.', 'wisewand-ai-content-writer-seo-content-generator' ); ?></p>

						<div class="empty-divider"><?php esc_html_e( 'OR', 'wisewand-ai-content-writer-seo-content-generator' ); ?></div>

						<div class="keyword-ideas-prompt">
							<h4>🆕 <?php esc_html_e( 'New Website? Get Keyword Ideas', 'wisewand-ai-content-writer-seo-content-generator' ); ?></h4>
							<p><?php esc_html_e( 'Enter your main topics to discover the 10 best keyword opportunities per topic', 'wisewand-ai-content-writer-seo-content-generator' ); ?></p>
							<textarea id="keyword-ideas-seeds" rows="3" placeholder="<?php esc_html_e( 'Enter main topics (one per line):\nwordpress seo\ncontent marketing\nblogging tips', 'wisewand-ai-content-writer-seo-content-generator' ); ?>"></textarea>
							<button type="button" id="get-keyword-ideas-empty" class="btn-keyword-ideas">
								🔍 <?php esc_html_e( 'Get Keyword Ideas', 'wisewand-ai-content-writer-seo-content-generator' ); ?>
							</button>
						</div>
					</div>
				</div>
			</div>
		</div>

		<!-- Reusable Modal -->
		<div id="wisewand-modal" class="wisewand-modal" style="display: none;">
			<div class="modal-overlay"></div>
			<div class="modal-container">
				<div class="modal-header">
					<h3 id="modal-title">Modal Title</h3>
					<button type="button" class="modal-close">×</button>
				</div>
				<div class="modal-body" id="modal-body">
					Modal content
				</div>
				<div class="modal-footer" id="modal-footer">
					<button type="button" class="modal-btn-secondary modal-close">Cancel</button>
					<button type="button" class="modal-btn-primary" id="modal-confirm">Confirm</button>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Render the saved keywords count summary (used in AJAX responses)
	 *
	 * @since 1.0.0
	 */
	private function render_saved_keywords_list() {
		// This method is now only used for AJAX response to update the list after saving
		// The saved keywords are displayed in the unified table instead
		echo '<div class="saved-keywords-count-display">';

		if ( ! class_exists( 'Wisewand\\Utils\\Saved_Keywords_Manager' ) ) {
			require_once WISEWAND_PLUGIN_DIR . 'includes/Utils/Saved_Keywords_Manager.php';
		}

		$saved_manager = new \Wisewand\Utils\Saved_Keywords_Manager( $this->options, $this->logger, $this->dataforseo_client );
		$stats         = $saved_manager->get_statistics();

		echo '<p style="color: #64748b; font-size: 13px; margin: 16px 0 0 0;">';
		echo '💾 Library: ' . esc_html( $stats['total'] ?? 0 ) . ' keywords';
		if ( ( $stats['by_source']['keyword_ideas'] ?? 0 ) > 0 ) {
			echo ' (' . esc_html( $stats['by_source']['keyword_ideas'] ) . ' from ideas)';
		}
		echo '</p>';
		echo '</div>';
	}

	/**
	 * Detect and normalise the current site domain
	 *
	 * Strips the www. prefix so domain comparisons are consistent regardless
	 * of whether the site URL uses it.
	 *
	 * @since 1.0.0
	 *
	 * @return string Normalised domain (e.g. "example.com").
	 */
	private function get_current_domain() {
		$url    = home_url();
		$parsed = wp_parse_url( $url );
		$domain = $parsed['host'] ?? '';

		// Normalize: remove www prefix for consistency
		$domain = preg_replace( '/^www\./i', '', $domain );

		$this->logger->debug(
			'Current domain detected',
			array(
				'raw_url'           => $url,
				'normalized_domain' => $domain,
			)
		);

		return $domain;
	}

	/**
	 * Enqueue CSS, JS, and localised script data for the SEO dashboard
	 *
	 * @since 1.0.0
	 */
	private function enqueue_real_assets() {
		wp_enqueue_style(
			'wisewand-seo-intelligence-admin',
			WISEWAND_PLUGIN_URL . 'assets/css/admin/wisewand-seo-intelligence-admin.css',
			array(),
			WISEWAND_PLUGIN_VERSION
		);

		wp_enqueue_script(
			'wisewand-seo-intelligence-admin',
			WISEWAND_PLUGIN_URL . 'assets/js/admin/wisewand-seo-intelligence-admin.js',
			array( 'jquery' ),
			WISEWAND_PLUGIN_VERSION,
			true
		);

		// Prepare category data for JavaScript
		$all_categories = array();
		$categories     = get_categories(
			array(
				'hide_empty' => false,
				'orderby'    => 'name',
			)
		);

		foreach ( $categories as $cat ) {
			$parent_name = '';
			if ( $cat->parent ) {
				$parent_cat = get_category( $cat->parent );
				if ( $parent_cat ) {
					$parent_name = $parent_cat->name;
				}
			}

			$all_categories[] = array(
				'id'          => $cat->term_id,
				'name'        => $cat->name,
				'parent'      => $cat->parent,
				'parent_name' => $parent_name,
			);
		}

		wp_localize_script(
			'wisewand-seo-intelligence-admin',
			'wisewandSEO',
			array(
				'ajaxUrl'                         => admin_url( 'admin-ajax.php' ),
				'nonce'                           => wp_create_nonce( 'wisewand_seo_real' ),
				'calendarNonce'                   => wp_create_nonce( 'wisewand_calendar' ),
				'domain'                          => $this->domain,
				'adminUrl'                        => admin_url( 'admin.php' ),
				'settingsUrl'                     => admin_url( 'admin.php?page=wisewand-settings' ),
				'totalCategories'                 => count( $categories ),
				'allCategories'                   => $all_categories,
				'defaultAutoGenerateInstructions' => (bool) $this->options->get( 'wisewand_default_auto_generate_instructions', false ),
				'openaiConfigured'                => \Wisewand\Utils\OpenAI_Client::is_configured(),
				'dataForSEOConfigured'            => \Wisewand\Utils\DataForSEO_Universal::is_configured(),
				'markets'                         => \Wisewand\Config\Supported_Options::get_markets(),
			)
		);
	}

	// =========================================================================
	// DATAFORSEO CLIENT INITIALISATION
	// =========================================================================

	/**
	 * Initialise the DataForSEO Universal client from stored credentials
	 *
	 * Sets $this->dataforseo_client to null when credentials are absent.
	 *
	 * @since 1.0.0
	 */
	private function init_dataforseo_client() {
		$credentials = DataForSEO_Universal::get_stored_credentials();
		if ( ! empty( $credentials['login'] ) && ! empty( $credentials['password'] ) ) {
			$this->dataforseo_client = new DataForSEO_Universal(
				$credentials['login'],
				$credentials['password'],
				$this->logger
			);
		}
	}

	// =========================================================================
	// HANDLER CONTEXT & LAZY HANDLER GETTERS
	// =========================================================================

	/**
	 * Build (or return cached) shared handler context DTO
	 *
	 * Creates a SEO_Handler_Context from the facade's own initialised
	 * dependencies so all handlers share the same repository instances.
	 *
	 * @since 2.8.2
	 *
	 * @return SEO_Handler_Context
	 */
	private function get_context() {
		if ( null === $this->handler_context ) {
			if ( ! class_exists( 'Wisewand\\Admin\\SEO\\SEO_Handler_Context' ) ) {
				require_once WISEWAND_PLUGIN_DIR . 'includes/Admin/SEO/SEO_Handler_Context.php';
			}
			$this->handler_context = new SEO_Handler_Context(
				$this->options,
				$this->logger,
				$this->dataforseo_client,
				$this->seo_repository,
				$this->competitor_repository,
				$this->keyword_repository,
				$this->calendar_repository,
				$this->rate_limiter,
				$this->domain
			);
		}
		return $this->handler_context;
	}

	/**
	 * Return (or lazily create) the SEO analysis handler
	 *
	 * @since 2.8.2
	 *
	 * @return SEO_Analysis_Handler
	 */
	private function get_analysis_handler() {
		if ( null === $this->analysis_handler ) {
			if ( ! class_exists( 'Wisewand\\Admin\\SEO\\SEO_Analysis_Handler' ) ) {
				require_once WISEWAND_PLUGIN_DIR . 'includes/Admin/SEO/SEO_Analysis_Handler.php';
			}
			$this->analysis_handler = new SEO_Analysis_Handler( $this->get_context() );
		}
		return $this->analysis_handler;
	}

	/**
	 * Return (or lazily create) the saved keywords handler
	 *
	 * @since 2.8.2
	 *
	 * @return SEO_Keywords_Handler
	 */
	private function get_keywords_handler() {
		if ( null === $this->keywords_handler ) {
			if ( ! class_exists( 'Wisewand\\Admin\\SEO\\SEO_Keywords_Handler' ) ) {
				require_once WISEWAND_PLUGIN_DIR . 'includes/Admin/SEO/SEO_Keywords_Handler.php';
			}
			$this->keywords_handler = new SEO_Keywords_Handler( $this->get_context() );
		}
		return $this->keywords_handler;
	}

	/**
	 * Return (or lazily create) the competitor handler
	 *
	 * @since 2.8.2
	 *
	 * @return SEO_Competitor_Handler
	 */
	private function get_competitor_handler() {
		if ( null === $this->competitor_handler ) {
			if ( ! class_exists( 'Wisewand\\Admin\\SEO\\SEO_Competitor_Handler' ) ) {
				require_once WISEWAND_PLUGIN_DIR . 'includes/Admin/SEO/SEO_Competitor_Handler.php';
			}
			$this->competitor_handler = new SEO_Competitor_Handler( $this->get_context() );
		}
		return $this->competitor_handler;
	}

	/**
	 * Return (or lazily create) the clustering handler
	 *
	 * @since 2.8.2
	 *
	 * @return SEO_Clustering_Handler
	 */
	private function get_clustering_handler() {
		if ( null === $this->clustering_handler ) {
			if ( ! class_exists( 'Wisewand\\Admin\\SEO\\SEO_Clustering_Handler' ) ) {
				require_once WISEWAND_PLUGIN_DIR . 'includes/Admin/SEO/SEO_Clustering_Handler.php';
			}
			$this->clustering_handler = new SEO_Clustering_Handler( $this->get_context() );
		}
		return $this->clustering_handler;
	}

	/**
	 * Return (or lazily create) the AI matcher handler
	 *
	 * @since 2.8.2
	 *
	 * @return SEO_AI_Matcher_Handler
	 */
	private function get_ai_matcher_handler() {
		if ( null === $this->ai_matcher_handler ) {
			if ( ! class_exists( 'Wisewand\\Admin\\SEO\\SEO_AI_Matcher_Handler' ) ) {
				require_once WISEWAND_PLUGIN_DIR . 'includes/Admin/SEO/SEO_AI_Matcher_Handler.php';
			}
			$this->ai_matcher_handler = new SEO_AI_Matcher_Handler( $this->get_context() );
		}
		return $this->ai_matcher_handler;
	}

	// =========================================================================
	// AJAX DELEGATIONS — SEO_Analysis_Handler
	// =========================================================================

	/**
	 * Delegate to SEO_Analysis_Handler::ajax_get_dataforseo_balance()
	 *
	 * @since 2.8.7
	 */
	public function ajax_get_dataforseo_balance() {
		$this->get_analysis_handler()->ajax_get_dataforseo_balance();
	}

	/**
	 * Delegate to SEO_Analysis_Handler::ajax_run_real_analysis()
	 *
	 * @since 1.0.0
	 */
	public function ajax_run_real_analysis() {
		$this->get_analysis_handler()->ajax_run_real_analysis();
	}

	/**
	 * Delegate to SEO_Analysis_Handler::ajax_load_latest_snapshot()
	 *
	 * @since 1.0.0
	 */
	public function ajax_load_latest_snapshot() {
		$this->get_analysis_handler()->ajax_load_latest_snapshot();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_schedule_keyword()
	 *
	 * @since 1.0.0
	 */
	public function ajax_schedule_keyword() {
		$this->get_keywords_handler()->ajax_schedule_keyword();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_discover_keywords()
	 *
	 * @since 1.0.0
	 */
	public function ajax_discover_keywords() {
		$this->get_keywords_handler()->ajax_discover_keywords();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_add_manual_keywords()
	 *
	 * @since 1.0.0
	 */
	public function ajax_add_manual_keywords() {
		$this->get_keywords_handler()->ajax_add_manual_keywords();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_generate_smart_roadmap()
	 *
	 * @since 1.0.0
	 */
	public function ajax_generate_smart_roadmap() {
		$this->get_keywords_handler()->ajax_generate_smart_roadmap();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_get_available_languages()
	 *
	 * @since 1.0.0
	 */
	public function ajax_get_available_languages() {
		$this->get_keywords_handler()->ajax_get_available_languages();
	}

	// =========================================================================
	// AJAX DELEGATIONS — SEO_Keywords_Handler
	// =========================================================================

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_save_keywords_to_library()
	 *
	 * @since 1.0.0
	 */
	public function ajax_save_keywords_to_library() {
		$this->get_keywords_handler()->ajax_save_keywords_to_library();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_enrich_saved_keywords()
	 *
	 * @since 1.0.0
	 */
	public function ajax_enrich_saved_keywords() {
		$this->get_keywords_handler()->ajax_enrich_saved_keywords();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_schedule_saved_keyword()
	 *
	 * @since 1.0.0
	 */
	public function ajax_schedule_saved_keyword() {
		$this->get_keywords_handler()->ajax_schedule_saved_keyword();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_schedule_saved_keywords()
	 *
	 * @since 1.0.0
	 */
	public function ajax_schedule_saved_keywords() {
		$this->get_keywords_handler()->ajax_schedule_saved_keywords();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_delete_saved_keyword()
	 *
	 * @since 1.0.0
	 */
	public function ajax_delete_saved_keyword() {
		$this->get_keywords_handler()->ajax_delete_saved_keyword();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_get_keyword_ideas()
	 *
	 * @since 1.0.0
	 */
	public function ajax_get_keyword_ideas() {
		$this->get_keywords_handler()->ajax_get_keyword_ideas();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_update_saved_keyword()
	 *
	 * @since 1.0.0
	 */
	public function ajax_update_saved_keyword() {
		$this->get_keywords_handler()->ajax_update_saved_keyword();
	}

	/**
	 * Delegate to SEO_Keywords_Handler::ajax_bulk_delete_saved_keywords()
	 *
	 * @since 1.0.0
	 */
	public function ajax_bulk_delete_saved_keywords() {
		$this->get_keywords_handler()->ajax_bulk_delete_saved_keywords();
	}

	// =========================================================================
	// AJAX DELEGATIONS — SEO_Competitor_Handler
	// =========================================================================

	/**
	 * Delegate to SEO_Competitor_Handler::ajax_spy_competitors()
	 *
	 * @since 1.0.0
	 */
	public function ajax_spy_competitors() {
		$this->get_competitor_handler()->ajax_spy_competitors();
	}

	/**
	 * Delegate to SEO_Competitor_Handler::ajax_save_spy_keywords()
	 *
	 * @since 1.0.0
	 */
	public function ajax_save_spy_keywords() {
		$this->get_competitor_handler()->ajax_save_spy_keywords();
	}

	/**
	 * Delegate to SEO_Competitor_Handler::ajax_save_column_preferences()
	 *
	 * @since 1.0.0
	 */
	public function ajax_save_column_preferences() {
		$this->get_competitor_handler()->ajax_save_column_preferences();
	}

	// =========================================================================
	// AJAX DELEGATIONS — SEO_Clustering_Handler
	// =========================================================================

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_remove_from_calendar()
	 *
	 * @since 1.0.0
	 */
	public function ajax_remove_from_calendar() {
		$this->get_clustering_handler()->ajax_remove_from_calendar();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_clear_all_calendar()
	 *
	 * @since 1.0.0
	 */
	public function ajax_clear_all_calendar() {
		$this->get_clustering_handler()->ajax_clear_all_calendar();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_scan_duplicates()
	 *
	 * @since 1.0.0
	 */
	public function ajax_scan_duplicates() {
		$this->get_clustering_handler()->ajax_scan_duplicates();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_run_clustering_scan()
	 *
	 * @since 1.0.0
	 */
	public function ajax_run_clustering_scan() {
		$this->get_clustering_handler()->ajax_run_clustering_scan();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_get_clusters()
	 *
	 * @since 1.0.0
	 */
	public function ajax_get_clusters() {
		$this->get_clustering_handler()->ajax_get_clusters();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_set_cluster_primary()
	 *
	 * @since 1.0.0
	 */
	public function ajax_set_cluster_primary() {
		$this->get_clustering_handler()->ajax_set_cluster_primary();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_ungroup_cluster()
	 *
	 * @since 1.0.0
	 */
	public function ajax_ungroup_cluster() {
		$this->get_clustering_handler()->ajax_ungroup_cluster();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_delete_cluster_variants()
	 *
	 * @since 1.0.0
	 */
	public function ajax_delete_cluster_variants() {
		$this->get_clustering_handler()->ajax_delete_cluster_variants();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_approve_cluster()
	 *
	 * @since 1.0.0
	 */
	public function ajax_approve_cluster() {
		$this->get_clustering_handler()->ajax_approve_cluster();
	}

	/**
	 * Delegate to SEO_Clustering_Handler::ajax_check_cannibalization()
	 *
	 * @since 1.0.0
	 */
	public function ajax_check_cannibalization() {
		$this->get_clustering_handler()->ajax_check_cannibalization();
	}

	// =========================================================================
	// AJAX DELEGATIONS — SEO_AI_Matcher_Handler
	// =========================================================================

	/**
	 * Delegate to SEO_AI_Matcher_Handler::ajax_save_keyword_author_categories()
	 *
	 * @since 1.0.0
	 */
	public function ajax_save_keyword_author_categories() {
		$this->get_ai_matcher_handler()->ajax_save_keyword_author_categories();
	}

	/**
	 * Delegate to SEO_AI_Matcher_Handler::ajax_ai_match_categories()
	 *
	 * @since 1.0.0
	 */
	public function ajax_ai_match_categories() {
		$this->get_ai_matcher_handler()->ajax_ai_match_categories();
	}

	/**
	 * Delegate to SEO_AI_Matcher_Handler::ajax_count_keywords_for_matching()
	 *
	 * @since 1.0.0
	 */
	public function ajax_count_keywords_for_matching() {
		$this->get_ai_matcher_handler()->ajax_count_keywords_for_matching();
	}

	/**
	 * Delegate to SEO_AI_Matcher_Handler::ajax_check_ranking_conflicts()
	 *
	 * @since 1.0.0
	 */
	public function ajax_check_ranking_conflicts() {
		$this->get_ai_matcher_handler()->ajax_check_ranking_conflicts();
	}
}
