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

namespace Hafenstudios\Wellenbrecher\Engine;

defined( 'ABSPATH' ) || exit;

/**
 * Unveraenderlicher Bewertungs-Kontext (readonly DTO, Bauplan Kap. 4.2).
 *
 * Die Kanal-Adapter (W2/W3) bauen den Context aus dem rohen Request; die
 * Engine und die Regeln lesen nur. Konventionen:
 *
 * - fields: rohe Eingabefelder. Kanaluebergreifende Schluessel:
 *   'content' (Haupttext), 'author_name', 'author_url', 'author_email'.
 * - server: Header-Snapshot in Kleinbuchstaben-Schluesseln:
 *   'remote_addr', 'user_agent', 'accept_language', 'protocol',
 *   'sec_fetch_site', 'request_time' (Unix-Sekunden des Empfangs).
 *   'remote_addr' ist die bereits AUFGELOESTE Client-IP: der Kanal ruft
 *   IpHasher::client_ip() mit dem Setting proxy.trusted_header auf und legt
 *   das Ergebnis hier ab. Regeln lesen nur 'remote_addr' und duerfen die
 *   Proxy-Aufloesung nicht selbst versuchen.
 * - signals: Frontend-Signale: 'token' (HMAC-Formular-Token),
 *   'js_timestamp' (Wert des Timestamp-Felds), 'honeypot' (Wert des
 *   Honeypot-Felds), 'original_field_posted' (bool, Feld-Tausch umgangen).
 * - user: Trust-Flags: 'can_moderate', 'has_approved_comment',
 *   'has_history', 'is_verified_buyer', 'is_allowlisted'.
 * - meta: Kanal-Metadaten: 'form_id', 'post_id', 'skip_token_rules'
 *   (bool, true fuer REST-/XML-RPC-Kontexte: Token-/JS-Regeln neutralisiert).
 */
class Context {

	/**
	 * @param string               $channel Kanal (comment|trackback|registration|leadlotse|woo_review|woo_checkout).
	 * @param array<string, mixed> $fields  Rohe Eingabefelder.
	 * @param array<string, mixed> $server  Header-Snapshot.
	 * @param array<string, mixed> $signals Frontend-Signale (Token/JS/Honeypot).
	 * @param array<string, mixed> $user    Nutzer-Trust-Flags.
	 * @param array<string, mixed> $meta    Kanal-Metadaten.
	 */
	public function __construct(
		public readonly string $channel,
		public readonly array $fields = array(),
		public readonly array $server = array(),
		public readonly array $signals = array(),
		public readonly array $user = array(),
		public readonly array $meta = array()
	) {
	}

	/**
	 * Liest ein Eingabefeld als String.
	 *
	 * @param string $key Feldschluessel.
	 * @return string
	 */
	public function field( string $key ): string {
		$value = $this->fields[ $key ] ?? '';
		return is_scalar( $value ) ? (string) $value : '';
	}

	/**
	 * Liest einen Server-Wert als String.
	 *
	 * @param string $key Schluessel (Kleinbuchstaben-Konvention).
	 * @return string
	 */
	public function server( string $key ): string {
		$value = $this->server[ $key ] ?? '';
		return is_scalar( $value ) ? (string) $value : '';
	}

	/**
	 * Liest ein Signal als String.
	 *
	 * @param string $key Signalschluessel.
	 * @return string
	 */
	public function signal( string $key ): string {
		$value = $this->signals[ $key ] ?? '';
		return is_scalar( $value ) ? (string) $value : '';
	}

	/**
	 * Liest ein boolesches Nutzer-Trust-Flag.
	 *
	 * @param string $key Flag-Schluessel.
	 * @return bool
	 */
	public function user_flag( string $key ): bool {
		return ! empty( $this->user[ $key ] );
	}
}
