/**
 * Leadlotse - Frontend (progressive enhancement, Vanilla JS, D3).
 *
 * Ohne dieses Skript funktioniert das Formular vollstaendig ueber den
 * admin-post.php-Fallback. Mit Skript:
 * - Submit per REST leadlotse/v1/submit (fetch mit Nonce),
 * - Inline-Validierung (HTML5-Checks + Serverfehler je Feld),
 * - Conditional Logic (Felder ein-/ausblenden anhand data-conditions),
 * - UTM-/Capture-Befuellung der Hidden-Felder aus der URL,
 * - Danke-Verhalten: Meldung, oder Weiterleitung laut Server-Antwort.
 */
( function () {
	'use strict';

	var cfg = window.leadlotseFrontend || {};

	/* ---------------------------------------------------------------
	 * Conditional Logic (gleiche Struktur wie serverseitig, D-Etappe 2)
	 * --------------------------------------------------------------- */

	function fieldValue( form, fieldId ) {
		var els = form.querySelectorAll( '[name="fields[' + fieldId + ']"]' );
		var value = '';
		Array.prototype.forEach.call( els, function ( el ) {
			if ( el.type === 'checkbox' || el.type === 'radio' ) {
				if ( el.checked ) {
					value = el.value;
				}
			} else {
				value = el.value;
			}
		} );
		return String( value );
	}

	function ruleMatches( rule, form ) {
		var actual = fieldValue( form, rule.field );
		var expected = String( rule.value || '' );
		switch ( rule.operator ) {
			case 'equals':
				return actual === expected;
			case 'not_equals':
				return actual !== expected;
			case 'contains':
				return expected !== '' && actual.toLowerCase().indexOf( expected.toLowerCase() ) !== -1;
			case 'not_empty':
				return actual.trim() !== '';
			case 'empty':
				return actual.trim() === '';
			default:
				return false;
		}
	}

	function isVisible( conditions, form ) {
		if ( ! conditions || ! conditions.enabled ) {
			return true;
		}
		var rules = conditions.rules || [];
		if ( ! rules.length ) {
			return true;
		}
		var results = rules.map( function ( rule ) {
			return ruleMatches( rule, form );
		} );
		var matched = conditions.logic === 'or'
			? results.indexOf( true ) !== -1
			: results.indexOf( false ) === -1;
		return conditions.action === 'hide' ? ! matched : matched;
	}

	function applyConditions( form ) {
		var wrappers = form.querySelectorAll( '[data-conditions]' );
		Array.prototype.forEach.call( wrappers, function ( wrapper ) {
			var conditions;
			try {
				conditions = JSON.parse( wrapper.getAttribute( 'data-conditions' ) );
			} catch ( e ) {
				return;
			}
			var visible = isVisible( conditions, form );
			wrapper.hidden = ! visible;
			// Verborgene Pflichtfelder duerfen den Browser-Submit nicht blockieren.
			var inputs = wrapper.querySelectorAll( 'input, select, textarea' );
			Array.prototype.forEach.call( inputs, function ( input ) {
				if ( visible && input.getAttribute( 'aria-required' ) === 'true' ) {
					input.required = true;
				} else if ( ! visible ) {
					input.required = false;
				}
				input.disabled = ! visible;
			} );
		} );
	}

	/* ---------------------------------------------------------------
	 * Fehler- und Statusdarstellung
	 * --------------------------------------------------------------- */

	function clearErrors( form ) {
		Array.prototype.forEach.call( form.querySelectorAll( '.leadlotse-error' ), function ( el ) {
			el.textContent = '';
			el.removeAttribute( 'role' );
		} );
		Array.prototype.forEach.call( form.querySelectorAll( '.leadlotse-field--has-error' ), function ( el ) {
			el.classList.remove( 'leadlotse-field--has-error' );
		} );
	}

	function showFieldError( form, fieldId, message ) {
		var wrapper = form.querySelector( '[data-field-id="' + fieldId + '"]' );
		if ( ! wrapper ) {
			return;
		}
		wrapper.classList.add( 'leadlotse-field--has-error' );
		var error = wrapper.querySelector( '.leadlotse-error' );
		if ( error ) {
			error.textContent = message;
			error.setAttribute( 'role', 'alert' );
		}
	}

	function showStatus( form, type, message ) {
		var status = form.querySelector( '[data-leadlotse-status]' );
		if ( ! status ) {
			return;
		}
		status.classList.remove( 'leadlotse-status--success', 'leadlotse-status--error' );
		if ( type ) {
			status.classList.add( 'leadlotse-status--' + type );
		}
		status.setAttribute( 'role', type === 'error' ? 'alert' : 'status' );
		status.textContent = message;
		status.hidden = ! message;
		if ( message ) {
			status.scrollIntoView( { behavior: 'smooth', block: 'nearest' } );
		}
	}

	/* ---------------------------------------------------------------
	 * Capture: UTM-Parameter in Hidden-Felder uebernehmen
	 * --------------------------------------------------------------- */

	function fillCaptures( form ) {
		var params;
		try {
			params = new URLSearchParams( window.location.search );
		} catch ( e ) {
			return;
		}
		Array.prototype.forEach.call( form.querySelectorAll( 'input[data-capture]' ), function ( input ) {
			var key = input.getAttribute( 'data-capture' );
			if ( key && ! input.value && params.has( key ) ) {
				input.value = params.get( key ).substring( 0, 200 );
			}
		} );
	}

	/* ---------------------------------------------------------------
	 * Submit via REST
	 * --------------------------------------------------------------- */

	function collectPayload( form ) {
		var fields = {};
		Array.prototype.forEach.call( form.querySelectorAll( '[name^="fields["]' ), function ( el ) {
			var match = el.name.match( /^fields\[(.+)\]$/ );
			if ( ! match ) {
				return;
			}
			var id = match[ 1 ];
			if ( el.disabled ) {
				return;
			}
			if ( el.type === 'checkbox' || el.type === 'radio' ) {
				if ( el.checked ) {
					fields[ id ] = el.value;
				} else if ( ! ( id in fields ) ) {
					fields[ id ] = '';
				}
			} else {
				fields[ id ] = el.value;
			}
		} );

		var ts = form.querySelector( '[name="ll_ts"]' );
		var hp = form.querySelector( '[name="ll_website_url"]' );

		var params;
		try {
			params = new URLSearchParams( window.location.search );
		} catch ( e ) {
			params = null;
		}

		return {
			form_id: parseInt( form.getAttribute( 'data-form-id' ), 10 ) || 0,
			fields: fields,
			ll_ts: ts ? ts.value : '',
			ll_website_url: hp ? hp.value : '',
			source_url: window.location.href,
			utm_source: params && params.get( 'utm_source' ) ? params.get( 'utm_source' ) : '',
			utm_medium: params && params.get( 'utm_medium' ) ? params.get( 'utm_medium' ) : '',
			utm_campaign: params && params.get( 'utm_campaign' ) ? params.get( 'utm_campaign' ) : ''
		};
	}

	function submitViaRest( form ) {
		var restUrl = form.getAttribute( 'data-rest' ) || cfg.restUrl || '';
		if ( ! restUrl ) {
			return Promise.reject( new Error( 'no-rest-url' ) );
		}
		var headers = { 'Content-Type': 'application/json' };
		if ( cfg.nonce ) {
			headers[ 'X-WP-Nonce' ] = cfg.nonce;
		}
		return window.fetch( restUrl, {
			method: 'POST',
			headers: headers,
			credentials: 'same-origin',
			body: JSON.stringify( collectPayload( form ) )
		} ).then( function ( response ) {
			return response.json().then( function ( body ) {
				return { ok: response.ok, body: body };
			} );
		} );
	}

	function handleResult( form, result ) {
		var body = result.body || {};

		if ( result.ok && body.success ) {
			if ( body.redirect_url ) {
				window.location.assign( body.redirect_url );
				return;
			}
			form.reset();
			applyConditions( form );
			showStatus( form, 'success', body.message || cfg.i18n && cfg.i18n.success || '' );
			// Formularfelder nach Erfolg ausblenden? Nein: Meldung reicht, Felder bleiben (erneute Anfrage moeglich).
			return;
		}

		// Veralteter Nonce (haeufig auf gecachten Seiten): kein Feldfehler, sondern
		// klassischer POST-Fallback an admin-post.php (funktioniert ohne Nonce-Header).
		if ( ! result.ok && body.code === 'rest_cookie_invalid_nonce' ) {
			form.submit();
			return;
		}

		// Fehlerfall: Feldfehler inline, allgemeine Meldung oben.
		var data = body.data || {};
		var fieldErrors = data.fields || {};
		var firstErrorField = null;
		Object.keys( fieldErrors ).forEach( function ( fieldId ) {
			showFieldError( form, fieldId, String( fieldErrors[ fieldId ] ) );
			if ( ! firstErrorField ) {
				firstErrorField = form.querySelector( '[data-field-id="' + fieldId + '"] input, [data-field-id="' + fieldId + '"] select, [data-field-id="' + fieldId + '"] textarea' );
			}
		} );
		showStatus( form, 'error', body.message || ( cfg.i18n && cfg.i18n.error ) || '' );
		if ( firstErrorField ) {
			firstErrorField.focus();
		}
	}

	function onSubmit( event ) {
		var form = event.target.closest( '[data-leadlotse-form]' );
		if ( ! form ) {
			return;
		}
		// Native HTML5-Validierung zuerst (Inline-Hinweise des Browsers).
		if ( typeof form.checkValidity === 'function' && ! form.checkValidity() ) {
			return; // Browser zeigt seine Meldungen selbst.
		}

		event.preventDefault();
		clearErrors( form );

		var button = form.querySelector( '.leadlotse-submit' );
		if ( button ) {
			button.disabled = true;
		}

		submitViaRest( form ).then( function ( result ) {
			handleResult( form, result );
		} ).catch( function () {
			// REST nicht erreichbar: klassischen POST-Fallback nutzen.
			form.submit();
		} ).finally( function () {
			if ( button ) {
				button.disabled = false;
			}
		} );
	}

	function init() {
		var forms = document.querySelectorAll( '[data-leadlotse-form]' );
		Array.prototype.forEach.call( forms, function ( form ) {
			fillCaptures( form );
			applyConditions( form );
			form.addEventListener( 'change', function () {
				applyConditions( form );
			} );
			form.addEventListener( 'input', function ( e ) {
				if ( e.target && e.target.matches( 'input[type="radio"], select' ) ) {
					applyConditions( form );
				}
			} );
		} );
		document.addEventListener( 'submit', onSubmit );
	}

	if ( document.readyState === 'loading' ) {
		document.addEventListener( 'DOMContentLoaded', init );
	} else {
		init();
	}
} )();
