<?php
/**
 * Feature-capability resolver for Schema Health validation.
 *
 * Keeps enable/disable decisions in one place so licensing can hook later
 * without scattering paywall checks through rules, AJAX, or UI.
 *
 * @package SEOvaultSEO\Schema\Validation
 */

namespace SEOvaultSEO\Schema\Validation;

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

/**
 * Resolves Schema Health feature flags through a single filterable map.
 */
class SchemaValidationFeatures {

	const LOCAL = 'local_schema_validation';
	const GOOGLE = 'google_rule_checks';
	const LIVE = 'live_page_validation';

	/**
	 * Known feature keys and their default enabled state.
	 *
	 * @return array<string, bool>
	 */
	public static function defaults() {
		return array(
			self::LOCAL  => true,
			self::GOOGLE => true,
			self::LIVE   => true,
		);
	}

	/**
	 * Whether a Schema Health feature is enabled.
	 *
	 * @param string $feature Feature key.
	 * @return bool
	 */
	public static function is_enabled( $feature ) {
		$feature = is_string( $feature ) ? $feature : '';
		$map     = self::get_map();

		return ! empty( $map[ $feature ] );
	}

	/**
	 * Get the sanitized feature map after filters.
	 *
	 * @return array<string, bool>
	 *
	 * Filter: seovaultseo_schema_validation_features
	 * @param array<string, bool> $features Default feature map.
	 * @return array<string, bool>
	 */
	public static function get_map() {
		$features = self::defaults();

		if ( function_exists( 'apply_filters' ) ) {
			/**
			 * Filters the Schema Health feature capability map.
			 *
			 * Unknown keys are ignored. Non-boolean values are coerced.
			 * This filter must not bypass permission or nonce checks.
			 *
			 * @param array<string, bool> $features Default feature map.
			 */
			$filtered = apply_filters( 'seovaultseo_schema_validation_features', $features );
			$features = self::sanitize_map( $filtered, $features );
		}

		return $features;
	}

	/**
	 * Keep only known keys and coerce values to booleans.
	 *
	 * @param mixed               $filtered Filtered value.
	 * @param array<string, bool> $defaults Default map used as fallback.
	 * @return array<string, bool>
	 */
	private static function sanitize_map( $filtered, $defaults ) {
		if ( ! is_array( $filtered ) ) {
			return $defaults;
		}

		$map = $defaults;
		foreach ( array_keys( $defaults ) as $key ) {
			if ( array_key_exists( $key, $filtered ) ) {
				$map[ $key ] = (bool) $filtered[ $key ];
			}
		}

		return $map;
	}
}
