<?php

declare(strict_types=1);

namespace Australcode\Rewards\Service\Licensing;

defined( 'ABSPATH' ) || exit;

/**
 * Defense-in-depth overlay: forces Pro settings to their "free" values when the
 * license is not Pro, WITHOUT touching storage. Even if someone edits
 * wp_options or strips a `disabled` attribute via DevTools, the getter still
 * returns the free value.
 *
 * Coexists with LicenseGate (which handles binary feature flags). The forced-
 * values map is populated at the container with Australcode Rewards's Pro-only earning
 * settings (signup_points, daily_login_points, daily_login_streak_bonus), so
 * they collapse to 0 in Free; OptionsSettingsRepository::get() routes the stored
 * values through apply_all(). Extensible via the `acrwd_pro_forced_values`
 * filter.
 */
final class FeatureMap {

	/** @var array<string,mixed> */
	private array $forced;

	/**
	 * @param array<string,mixed> $forced Setting key => value forced in Free mode.
	 */
	public function __construct( array $forced = array() ) {
		$this->forced = $forced;
	}

	/**
	 * @return array<string,mixed>
	 */
	public function forced_values(): array {
		/** @var array<string,mixed> $filtered */
		$filtered = apply_filters( 'acrwd_pro_forced_values', $this->forced );
		return $filtered;
	}

	public function is_pro_setting( string $key ): bool {
		return array_key_exists( $key, $this->forced_values() );
	}

	/**
	 * @param mixed $value
	 * @return mixed
	 */
	public function apply( string $key, $value, bool $is_pro ) {
		if ( $is_pro ) {
			return $value;
		}
		$forced = $this->forced_values();
		return array_key_exists( $key, $forced ) ? $forced[ $key ] : $value;
	}

	/**
	 * @param array<string,mixed> $settings
	 * @return array<string,mixed>
	 */
	public function apply_all( array $settings, bool $is_pro ): array {
		if ( $is_pro ) {
			return $settings;
		}
		foreach ( array_keys( $this->forced_values() ) as $key ) {
			if ( array_key_exists( $key, $settings ) ) {
				$settings[ $key ] = $this->apply( $key, $settings[ $key ], $is_pro );
			}
		}
		return $settings;
	}
}
