<?php
/**
 * SEO Plugin Compatibility Detector
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Compatibility;

/**
 * Detects competing SEO plugins and manages output mode
 */
class Detector {

	/**
	 * Test-only override for detect_active_provider(). Null uses production detection.
	 *
	 * @var string|null
	 */
	private static $test_provider_override = null;

	/**
	 * Test-only override for get_conflicts(). Null uses production detection.
	 *
	 * @var array|null
	 */
	private static $test_conflicts_override = null;

	/**
	 * Test-only override for Router REST provider detection.
	 *
	 * @var array|null
	 */
	private static $test_rest_providers_override = null;

	/**
	 * Test-only override for migration importer availability (plugin directory slugs).
	 *
	 * @var array|null
	 */
	private static $test_migration_slugs_override = null;

	/**
	 * Test-only override for is_old_connector_active().
	 *
	 * @var bool|null
	 */
	private static $test_old_connector_override = null;

	/**
	 * Provider constants
	 */
	const PROVIDER_SEOVAULT        = 'seovault';
	const PROVIDER_RANKMATH        = 'rankmath';
	const PROVIDER_YOAST           = 'yoast';
	const PROVIDER_AIOSEO          = 'aioseo';
	const PROVIDER_SURERANK        = 'surerank';
	const PROVIDER_SLIMSEO         = 'slimseo';
	const PROVIDER_THESEOFRAMEWORK = 'theseoframework';
	const PROVIDER_NONE            = 'none';
	const PROVIDER_UNKNOWN         = 'unknown';

	/**
	 * Detect which SEO plugin is active
	 *
	 * @return string Provider identifier
	 */
	public static function detect_active_provider() {
		if ( null !== self::$test_provider_override ) {
			return self::$test_provider_override;
		}

		// Check for Yoast SEO
		if ( defined( 'WPSEO_VERSION' ) ) {
			return self::PROVIDER_YOAST;
		}

		// Check for Rank Math
		if ( defined( 'RANK_MATH_VERSION' ) ) {
			return self::PROVIDER_RANKMATH;
		}

		// Check for All in One SEO
		if ( class_exists( 'All_in_One_SEO_Pack' ) || defined( 'AIOSEOP_VERSION' ) || defined( 'AIOSEO_VERSION' ) ) {
			return self::PROVIDER_AIOSEO;
		}

		// Check for SureRank SEO
		if ( defined( 'SURERANK_VERSION' ) || defined( 'SURERANK_FILE' ) || class_exists( 'SureRank\\Loader' ) ) {
			return self::PROVIDER_SURERANK;
		}

		// Check for Slim SEO
		if ( defined( 'SLIM_SEO_VER' ) || class_exists( 'SlimSEO\\Container' ) ) {
			return self::PROVIDER_SLIMSEO;
		}

		// Check for The SEO Framework
		if ( defined( 'THE_SEO_FRAMEWORK_VERSION' ) || defined( 'TSF_VERSION' ) ) {
			return self::PROVIDER_THESEOFRAMEWORK;
		}

		// No other SEO plugin detected
		return self::PROVIDER_NONE;
	}

	/**
	 * Check if SEOvault should output SEO tags on the frontend.
	 *
	 * The only question that matters: is SEOvault's output mode disabled?
	 * Competitor plugins are informational only and never gate output.
	 *
	 * @return bool
	 */
	public static function should_output_seo() {
		if ( 'disabled' === \SEOvaultSEO\Core\Options::get_output_mode() ) {
			return false;
		}

		return true;
	}

	/**
	 * Check if SEOvault should auto-generate SEO values (titles, descriptions, etc).
	 *
	 * @return bool
	 */
	public static function is_auto_generation() {
		return 'auto' === \SEOvaultSEO\Core\Options::get_output_mode();
	}

	/**
	 * Get the current SEO provider.
	 *
	 * Returns SEOvault unless output mode is disabled. Competitor detection
	 * is a separate, informational concern (see detect_active_provider()).
	 *
	 * @return string Provider identifier
	 */
	public static function get_active_provider() {
		if ( 'disabled' === \SEOvaultSEO\Core\Options::get_output_mode() ) {
			return self::PROVIDER_NONE;
		}

		return self::PROVIDER_SEOVAULT;
	}

	/**
	 * Get list of conflicting SEO plugins
	 *
	 * @return array Array of conflicting plugin names
	 */
	public static function get_conflicts() {
		if ( null !== self::$test_conflicts_override ) {
			return self::$test_conflicts_override;
		}

		$conflicts = array();

		if ( defined( 'WPSEO_VERSION' ) ) {
			$conflicts[] = 'Yoast SEO';
		}

		if ( defined( 'RANK_MATH_VERSION' ) ) {
			$conflicts[] = 'Rank Math';
		}

		if ( class_exists( 'All_in_One_SEO_Pack' ) || defined( 'AIOSEOP_VERSION' ) || defined( 'AIOSEO_VERSION' ) ) {
			$conflicts[] = 'All in One SEO';
		}

		if ( defined( 'SURERANK_VERSION' ) || defined( 'SURERANK_FILE' ) || class_exists( 'SureRank\\Loader' ) ) {
			$conflicts[] = 'SureRank';
		}

		if ( defined( 'SLIM_SEO_VER' ) || class_exists( 'SlimSEO\\Container' ) ) {
			$conflicts[] = 'Slim SEO';
		}

		if ( defined( 'THE_SEO_FRAMEWORK_VERSION' ) || defined( 'TSF_VERSION' ) ) {
			$conflicts[] = 'The SEO Framework';
		}

		return $conflicts;
	}

	/**
	 * Check if there are any conflicts
	 *
	 * @return bool
	 */
	public static function has_conflicts() {
		return count( self::get_conflicts() ) > 0;
	}

	/**
	 * Check if old SEOvault connector is active
	 *
	 * @return bool
	 */
	public static function is_old_connector_active() {
		if ( null !== self::$test_old_connector_override ) {
			return self::$test_old_connector_override;
		}

		return defined( 'SEOVAULTAI_CONNECTOR_VERSION' );
	}

	/**
	 * Configure simulated compatibility state for automated tests.
	 *
	 * @param string     $provider       Active provider constant from this class.
	 * @param array|null $conflicts      Conflict plugin names, or null to derive from provider.
	 * @param array|null $rest_providers REST API provider slugs (yoast, rank-math, aioseo).
	 * @return void
	 */
	public static function set_test_provider( $provider, $conflicts = null, $rest_providers = null ) {
		self::$test_provider_override = $provider;

		if ( null !== $conflicts ) {
			self::$test_conflicts_override = $conflicts;
		} elseif ( self::PROVIDER_NONE === $provider ) {
			self::$test_conflicts_override = array();
		} else {
			self::$test_conflicts_override = null;
		}

		if ( null !== $rest_providers ) {
			self::$test_rest_providers_override = $rest_providers;
		} elseif ( self::PROVIDER_NONE === $provider ) {
			self::$test_rest_providers_override = array();
		} else {
			self::$test_rest_providers_override = null;
		}
	}

	/**
	 * Configure simulated migration importer availability for automated tests.
	 *
	 * @param array $slugs Plugin directory slugs (e.g. wordpress-seo).
	 * @return void
	 */
	public static function set_test_migration_slugs( array $slugs ) {
		self::$test_migration_slugs_override = $slugs;
	}

	/**
	 * Configure simulated old connector state for automated tests.
	 *
	 * @param bool $active Whether the legacy connector is active.
	 * @return void
	 */
	public static function set_test_old_connector_active( $active ) {
		self::$test_old_connector_override = (bool) $active;
	}

	/**
	 * Get REST API provider override state.
	 *
	 * @return array|null Null when using production detection.
	 */
	public static function get_test_rest_providers_override() {
		return self::$test_rest_providers_override;
	}

	/**
	 * Check whether a migration importer should be treated as active in tests.
	 *
	 * @param string $slug        Plugin directory slug.
	 * @param bool   $real_active Production detection result.
	 * @return bool
	 */
	public static function is_migration_plugin_active( $slug, $real_active ) {
		if ( null !== self::$test_migration_slugs_override ) {
			return in_array( $slug, self::$test_migration_slugs_override, true );
		}

		return $real_active;
	}

	/**
	 * Check whether a competitor plugin is available for importer reads and detection.
	 *
	 * @param string $provider    Provider constant from this class.
	 * @param bool   $real_active Production detection result.
	 * @return bool
	 */
	public static function is_competitor_plugin_active( $provider, $real_active ) {
		if ( null !== self::$test_provider_override ) {
			if ( self::PROVIDER_NONE === self::$test_provider_override ) {
				return false;
			}

			return $provider === self::$test_provider_override;
		}

		return $real_active;
	}

	/**
	 * Reset all test-only compatibility overrides.
	 *
	 * @return void
	 */
	public static function reset_test_state() {
		self::$test_provider_override        = null;
		self::$test_conflicts_override       = null;
		self::$test_rest_providers_override  = null;
		self::$test_migration_slugs_override = null;
		self::$test_old_connector_override   = null;
	}

	/**
	 * Map a provider constant to a human-readable brand name.
	 *
	 * @param string $provider Provider constant from this class.
	 * @return string Branded display name.
	 */
	public static function get_provider_label( $provider ) {
		$labels = array(
			self::PROVIDER_SEOVAULT        => 'SEOvault AI',
			self::PROVIDER_RANKMATH        => 'Rank Math',
			self::PROVIDER_YOAST           => 'Yoast SEO',
			self::PROVIDER_AIOSEO          => 'AIOSEO',
			self::PROVIDER_SURERANK        => 'SureRank',
			self::PROVIDER_SLIMSEO         => 'Slim SEO',
			self::PROVIDER_THESEOFRAMEWORK => 'The SEO Framework',
			self::PROVIDER_NONE            => 'None',
			self::PROVIDER_UNKNOWN         => 'Unknown',
		);

		return isset( $labels[ $provider ] ) ? $labels[ $provider ] : ucfirst( $provider );
	}

	/**
	 * Map an output mode string to a human-readable label.
	 *
	 * @param string $mode Output mode ('auto', 'manual', 'disabled').
	 * @return string Display label.
	 */
	public static function get_output_mode_label( $mode ) {
		$labels = array(
			'auto'     => 'Autopilot',
			'manual'   => 'Manual',
			'disabled' => 'Disabled',
		);

		return isset( $labels[ $mode ] ) ? $labels[ $mode ] : ucfirst( $mode );
	}

	/**
	 * Get status information for display
	 *
	 * @return array Status information
	 */
	public static function get_status() {
		return array(
			'active_provider'      => self::get_active_provider(),
			'detected_competitor'  => self::detect_active_provider(),
			'has_competitors'      => self::has_conflicts(),
			'competitors'          => self::get_conflicts(),
			'should_output_seo'    => self::should_output_seo(),
			'is_auto_generation'   => self::is_auto_generation(),
			'output_mode'          => \SEOvaultSEO\Core\Options::get_output_mode(),
			'old_connector_active' => self::is_old_connector_active(),
		);
	}
}
