/**
 * Wellenbrecher Frontend-Signale (Vanilla, No-Build, progressive enhancement).
 *
 * Drei Signale, alle page-cache-fest, weil nichts Dynamisches ins HTML
 * gebacken wird: (a) Client-Timestamp nach Akismet-Muster, (b) einmaliges
 * Interaktions-Signal, (c) Fenster-Token vom ungecachten REST-Endpoint.
 * Ohne JavaScript bleibt alles funktionsfaehig; fehlende Signale sind fuer
 * die Engine nur Score, nie alleiniger Block.
 */
( function () {
	'use strict';

	function fill( name, value ) {
		// Kommentar-Kanal rendert name="wb_js"; Leadlotse-Formulare rendern
		// name="fields[wb_js]" (fliesst so in die Submit-Pipeline). Beide fuellen.
		var inputs = document.querySelectorAll(
			'input[name="' + name + '"], input[name="fields[' + name + ']"]'
		);
		for ( var i = 0; i < inputs.length; i++ ) {
			inputs[ i ].value = value;
		}
	}

	// (a) Timestamp: der Server rendert einen Zufallswert 0-250, das JS
	// ersetzt ihn durch die Client-Zeit in Millisekunden.
	fill( 'wb_js', String( Date.now() ) );

	// (b) Event-Signal: einmalig bei echter Interaktion (auch Tastatur).
	var events = [ 'mousemove', 'keydown', 'touchstart' ];
	function onInteract() {
		fill( 'wb_events', '1' );
		for ( var i = 0; i < events.length; i++ ) {
			document.removeEventListener( events[ i ], onInteract );
		}
	}
	for ( var i = 0; i < events.length; i++ ) {
		document.addEventListener( events[ i ], onInteract, { passive: true } );
	}

	// (c) Fenster-Token per fetch(); die Variable haelt ihn fuer die
	// Seitenlebensdauer (ein Abruf je Seitenaufruf, egal wie viele Felder).
	// Kommt (nur fuer vorbelastete IPs, Pro) eine PoW-Challenge mit, wird sie
	// per WebCrypto geloest; ohne WebCrypto (http-Kontext) laeuft alles weiter.
	var cfg = window.wellenbrecherSignals || {};
	var token = '';
	if ( cfg.tokenUrl && window.fetch ) {
		fetch( cfg.tokenUrl, { credentials: 'omit' } )
			.then( function ( res ) {
				return res.ok ? res.json() : null;
			} )
			.then( function ( data ) {
				if ( data && data.token ) {
					token = String( data.token );
					fill( 'wb_token', token );
				}
				if ( data && data.pow && data.pow.nonce ) {
					solvePow( String( data.pow.nonce ), Number( data.pow.difficulty ) || 4 );
				}
			} )
			.catch( function () {
				// Ohne Token bleibt alles funktionsfaehig (nur Score).
			} );
	}

	// Proof-of-Work: finde n, sodass SHA-256(nonce + n) mit difficulty
	// fuehrenden Hex-Nullen beginnt. Async ueber WebCrypto (nicht blockierend);
	// ohne crypto.subtle (http) passiert nichts, es bleibt beim Score.
	function solvePow( nonce, difficulty ) {
		if ( ! window.crypto || ! window.crypto.subtle || ! window.TextEncoder ) {
			return;
		}
		var prefix = new Array( difficulty + 1 ).join( '0' );
		var encoder = new TextEncoder();
		var limit = 5000000;

		function toHex( buffer ) {
			var bytes = new Uint8Array( buffer );
			var out = '';
			for ( var i = 0; i < bytes.length; i++ ) {
				out += ( bytes[ i ] >>> 4 ).toString( 16 ) + ( bytes[ i ] & 15 ).toString( 16 );
			}
			return out;
		}

		function attempt( n ) {
			if ( n > limit ) {
				return;
			}
			window.crypto.subtle.digest( 'SHA-256', encoder.encode( nonce + n ) )
				.then( function ( digest ) {
					if ( 0 === toHex( digest ).indexOf( prefix ) ) {
						fill( 'wb_pow', String( n ) );
					} else {
						attempt( n + 1 );
					}
				} )
				.catch( function () {} );
		}

		attempt( 0 );
	}
} )();
