<?php
/**
 * @package Hafenstudios\Wellenbrecher
 */

namespace Hafenstudios\Wellenbrecher\Rules;

use Hafenstudios\Wellenbrecher\Engine\Context;
use Hafenstudios\Wellenbrecher\Engine\RuleResult;

defined( 'ABSPATH' ) || exit;

/**
 * Ausfuellzeit unter der Mindestschwelle (Client-Timestamp vs. Empfangszeit,
 * cache-unabhaengig). Negative Differenzen (falsche Client-Uhr) sind KEIN
 * Treffer: falsche Uhren sind nur Score-Rauschen, nie ein Blockgrund.
 */
class FillTimeRule extends AbstractRule {

	public const ID             = 'fill_time';
	public const DEFAULT_POINTS = 15;

	public const MIN_SECONDS = 3;

	protected int $min_seconds;

	public function __construct( int $points = self::DEFAULT_POINTS, int $min_seconds = self::MIN_SECONDS ) {
		parent::__construct( $points );
		$this->min_seconds = $min_seconds;
	}

	public function id(): string {
		return self::ID;
	}

	public function stage(): int {
		return 1;
	}

	public function applies( Context $context ): bool {
		return empty( $context->meta['skip_token_rules'] );
	}

	public function evaluate( Context $context ): RuleResult {
		$value = trim( $context->signal( 'js_timestamp' ) );
		if ( '' === $value || ! ctype_digit( $value ) || (float) $value < JsTimestampRule::MIN_CLIENT_TIMESTAMP ) {
			// Kein echter Client-Timestamp: Sache der js_missing-Regel.
			return $this->miss();
		}

		$request_time = (int) $context->server( 'request_time' );
		if ( $request_time <= 0 ) {
			$request_time = time();
		}

		$elapsed = $request_time - (int) round( (float) $value / 1000 );
		if ( $elapsed >= 0 && $elapsed < $this->min_seconds ) {
			return $this->hit();
		}
		return $this->miss();
	}
}
