/**
 * Biscotti CMP — Legal Wizard (local admin script)
 *
 * Drives the native multi-step Legal Wizard: step navigation, persisting company
 * data via the save-legal-entity proxy, a client-side compliance summary derived
 * from the jurisdiction lookup, and per-document generation via generate-document.
 *
 * IMPORTANT: the save payload contains ONLY verified LegalEntity columns. The
 * Cloud view additionally sends isProcessor/avvDataCategories/dataSubjects which
 * are NOT LegalEntity columns and make the save throw — we map AVV data categories
 * to the valid `dataCategories` column instead and omit the rest.
 *
 * @package Biscotti_CMP
 */
( function ( $ ) {
	'use strict';

	var cfg = window.biscottiAdmin || {};
	var i18n = cfg.i18n || {};
	function t( k, f ) { return i18n[ k ] || f; }

	// Wizard data injected by the template.
	var WD = { stepIds: [], totalSteps: 1, jurisdiction: '', jurLookup: {} };
	try {
		var el = document.getElementById( 'biscotti-lw-data' );
		if ( el ) { WD = JSON.parse( el.textContent || '{}' ); }
	} catch ( err ) { /* keep defaults */ }
	// Single-source jurisdiction schema injected by the template (DATA only — never code).
	var SCHEMA = { jurisdictionId: '', jurisdiction: null, countries: [], fieldColumnMap: {} };
	try {
		var sEl = document.getElementById( 'biscotti-lw-schema' );
		if ( sEl ) { var parsedSchema = JSON.parse( sEl.textContent || '{}' ); if ( parsedSchema && typeof parsedSchema === 'object' ) { SCHEMA = parsedSchema; } }
	} catch ( e2 ) { /* keep defaults */ }
	var ICON_ENUM = { User: 'PRIVATE', Building2: 'COMPANY', Users: 'PARTNERSHIP', Shield: 'ASSOCIATION' };

	// Jurisdiction-specific "local requirements" questions (single source of truth,
	// served by get-jurisdiction-questions / get-legal-wizard-data) + their saved
	// answers for pre-fill. Rendered in the Local step, re-fetched on jurisdiction change.
	var LOCALQ = [];
	try { var lqEl = document.getElementById( 'biscotti-lw-local-questions' ); if ( lqEl ) { LOCALQ = JSON.parse( lqEl.textContent || '[]' ) || []; } } catch ( e3 ) { LOCALQ = []; }
	var LOCALA = {};
	try { var laEl = document.getElementById( 'biscotti-lw-local-answers' ); if ( laEl ) { LOCALA = JSON.parse( laEl.textContent || '{}' ) || {}; } } catch ( e4 ) { LOCALA = {}; }

	var currentStep = 1;

	function gv( id ) { var e = document.getElementById( id ); return e ? e.value.trim() : ''; }
	function gc( id ) { var e = document.getElementById( id ); return !! ( e && e.checked ); }
	function radio( name, def ) { var r = document.querySelector( 'input[name="' + name + '"]:checked' ); return r ? r.value : def; }
	function checks( sel ) { return Array.prototype.map.call( document.querySelectorAll( sel + ':checked' ), function ( c ) { return c.value; } ); }

	function navStatus( msg, color ) {
		var s = document.getElementById( 'lw-nav-status' );
		if ( s ) { s.textContent = msg; s.style.color = color || '#64748b'; }
	}

	function showStep( n ) {
		currentStep = Math.max( 1, Math.min( n, WD.totalSteps ) );
		var stepId = WD.stepIds[ currentStep - 1 ];
		$( '.biscotti-lw-panel' ).removeClass( 'active' );
		$( '.biscotti-lw-panel[data-id="' + stepId + '"]' ).addClass( 'active' );
		$( '.biscotti-lw-step' ).each( function () {
			var sn = parseInt( this.getAttribute( 'data-step' ), 10 );
			$( this ).toggleClass( 'active', sn === currentStep ).toggleClass( 'done', sn < currentStep );
		} );
		$( '#lw-btn-back' ).toggle( currentStep > 1 );
		$( '#lw-btn-next' ).text( currentStep < WD.totalSteps ? t( 'next', 'Next' ) + ' →' : '✅ ' + t( 'saved', 'Done' ) );
		if ( 'compliance' === stepId ) { computeCompliance(); }
		window.scrollTo( { top: 0, behavior: 'smooth' } );
	}

	// ---------------------------------------------------------------------------
	// Local (jurisdiction-specific) requirements — rendered from the single source
	// (get-jurisdiction-questions / get-legal-wizard-data). Mirrors the App's local
	// step: options→radio; *address*→street/zip/city; visdp_name/person_address→
	// name+address+email (canonical visdp_* columns); else text. Conditional
	// visibility via trigger_conditions ("When <id> is <value>"). DOM-built (no
	// innerHTML of server data) — WP.org compliant.
	// ---------------------------------------------------------------------------
	function lqHost() { return document.getElementById( 'lw-local-questions' ); }
	function lqPh( name, def ) { var h = lqHost(); var v = h && h.getAttribute( 'data-ph-' + name ); return v || def; }
	function lqIsVisdp( q ) { return ( q.input_type === 'person_address' ) || ( String( q.question_id ).toLowerCase().indexOf( 'visdp_name' ) !== -1 ); }
	function lqIsAddress( q ) { return !lqIsVisdp( q ) && String( q.question_id ).toLowerCase().indexOf( 'address' ) !== -1; }
	function lqCanonVisdp( q ) { return String( q.question_id ).toLowerCase().indexOf( 'visdp_name' ) !== -1; }

	function lqCurrent( qid ) {
		var r = document.querySelector( 'input[name="lwlq-' + qid + '"]:checked' );
		if ( r ) { return r.value; }
		var t = document.querySelector( '.lw-localq-text[data-qid="' + qid + '"]' );
		return t ? t.value : '';
	}

	function lqInput( value, placeholder, cls, attrs ) {
		var inp = document.createElement( 'input' );
		inp.type = ( attrs && attrs.type ) || 'text';
		inp.className = 'biscotti-svc-input ' + ( cls || '' );
		if ( placeholder ) { inp.placeholder = placeholder; }
		if ( value ) { inp.value = value; }
		if ( attrs ) { Object.keys( attrs ).forEach( function ( k ) { if ( k !== 'type' ) { inp.setAttribute( k, attrs[ k ] ); } } ); }
		return inp;
	}

	function renderLocalQuestions( questions, answers ) {
		var host = lqHost();
		if ( !host ) { return; }
		host.innerHTML = '';
		var list = Array.isArray( questions ) ? questions : [];
		var ja = ( answers && answers.jurisdictionAnswers && typeof answers.jurisdictionAnswers === 'object' ) ? answers.jurisdictionAnswers : {};
		if ( !list.length ) {
			var ep = document.createElement( 'p' ); ep.className = 'biscotti-empty-state';
			ep.textContent = host.getAttribute( 'data-empty' ) || '';
			host.appendChild( ep );
			return;
		}
		list.forEach( function ( q ) {
			var qid = q.question_id; if ( !qid ) { return; }
			var idl = qid.toLowerCase();
			var card = document.createElement( 'div' );
			card.className = 'biscotti-lw-local-q biscotti-form-row';
			card.setAttribute( 'data-qid', qid );
			card.setAttribute( 'data-conditions', JSON.stringify( Array.isArray( q.trigger_conditions ) ? q.trigger_conditions : [] ) );

			var lbl = document.createElement( 'label' ); lbl.style.fontWeight = '600'; lbl.textContent = q.question || qid; card.appendChild( lbl );
			if ( q.description ) { var dd = document.createElement( 'p' ); dd.className = 'description'; dd.textContent = q.description; card.appendChild( dd ); }

			if ( q.options && q.options.length ) {
				var saved = ja[ qid ];
				if ( ( saved === undefined || saved === '' ) && idl.indexOf( 'journalistic' ) !== -1 && answers && typeof answers.blog_journalistic_content !== 'undefined' ) {
					saved = answers.blog_journalistic_content ? 'yes' : '';
				}
				var row = document.createElement( 'div' ); row.className = 'biscotti-lw-radio-row';
				q.options.forEach( function ( opt ) {
					var l = document.createElement( 'label' ); l.className = 'lw-radio';
					var inp = document.createElement( 'input' ); inp.type = 'radio'; inp.name = 'lwlq-' + qid; inp.value = opt.value; inp.className = 'lw-localq-input';
					if ( String( saved ) === String( opt.value ) ) { inp.checked = true; }
					var sp = document.createElement( 'span' ); sp.textContent = opt.label || opt.value;
					l.appendChild( inp ); l.appendChild( document.createTextNode( ' ' ) ); l.appendChild( sp );
					row.appendChild( l );
				} );
				card.appendChild( row );
			} else if ( lqIsVisdp( q ) ) {
				var canon = lqCanonVisdp( q );
				var grid = document.createElement( 'div' ); grid.className = 'biscotti-lw-grid-2';
				var vv = function ( canonKey, suffix ) { return canon ? ( ( answers && answers[ canonKey ] ) || '' ) : ( ja[ qid + suffix ] || '' ); };
				grid.appendChild( lqInput( canon ? ( ( answers && answers.visdp_name ) || '' ) : ( ja[ qid ] || '' ), lqPh( 'name', 'Name' ), 'lw-localq-visdp', { 'data-qid': qid, 'data-visdp': canon ? 'visdp_name' : qid } ) );
				grid.appendChild( lqInput( vv( 'visdp_street', '_street' ), lqPh( 'street', 'Street' ), 'lw-localq-visdp', { 'data-qid': qid, 'data-visdp': canon ? 'visdp_street' : ( qid + '_street' ) } ) );
				grid.appendChild( lqInput( vv( 'visdp_zip', '_zip' ), lqPh( 'zip', 'ZIP' ), 'lw-localq-visdp', { 'data-qid': qid, 'data-visdp': canon ? 'visdp_zip' : ( qid + '_zip' ) } ) );
				grid.appendChild( lqInput( vv( 'visdp_city', '_city' ), lqPh( 'city', 'City' ), 'lw-localq-visdp', { 'data-qid': qid, 'data-visdp': canon ? 'visdp_city' : ( qid + '_city' ) } ) );
				grid.appendChild( lqInput( vv( 'visdp_email', '_email' ), lqPh( 'email', 'Email' ), 'lw-localq-visdp', { type: 'email', 'data-qid': qid, 'data-visdp': canon ? 'visdp_email' : ( qid + '_email' ) } ) );
				card.appendChild( grid );
			} else if ( lqIsAddress( q ) ) {
				var grid2 = document.createElement( 'div' ); grid2.className = 'biscotti-lw-grid-3';
				grid2.appendChild( lqInput( ja[ qid + '_street' ] || '', lqPh( 'street', 'Street' ), 'lw-localq-addr', { 'data-qid': qid, 'data-sub': '_street' } ) );
				grid2.appendChild( lqInput( ja[ qid + '_zip' ] || '', lqPh( 'zip', 'ZIP' ), 'lw-localq-addr', { 'data-qid': qid, 'data-sub': '_zip' } ) );
				grid2.appendChild( lqInput( ja[ qid + '_city' ] || '', lqPh( 'city', 'City' ), 'lw-localq-addr', { 'data-qid': qid, 'data-sub': '_city' } ) );
				card.appendChild( grid2 );
			} else {
				card.appendChild( lqInput( ja[ qid ] || '', lqPh( 'text', 'Your answer' ), 'lw-localq-text', { 'data-qid': qid } ) );
			}
			host.appendChild( card );
		} );
		applyLocalConditions();
	}

	function applyLocalConditions() {
		var host = lqHost(); if ( !host ) { return; }
		Array.prototype.forEach.call( host.querySelectorAll( '.biscotti-lw-local-q' ), function ( card ) {
			var conds; try { conds = JSON.parse( card.getAttribute( 'data-conditions' ) || '[]' ); } catch ( e ) { conds = []; }
			var visible = true;
			( conds || [] ).forEach( function ( cond ) {
				if ( typeof cond === 'string' && cond.indexOf( 'When ' ) === 0 ) {
					var parts = cond.split( ' ' );
					if ( parts.length >= 4 && parts[ 2 ] === 'is' ) {
						var depVal = parts.slice( 3 ).join( ' ' ).trim().replace( /['"]/g, '' );
						if ( lqCurrent( parts[ 1 ] ) !== depVal ) { visible = false; }
					}
				}
			} );
			card.style.display = visible ? '' : 'none';
		} );
	}

	// Merge local answers into the save payload (mirrors the App):
	//   jurisdictionAnswers[qid] (+ _street/_zip/_city for plain address),
	//   canonical visdp_* columns for the V.i.S.d.P. composite,
	//   blogJournalisticContent for the journalistic toggle.
	function collectLocalAnswers( payload ) {
		var host = lqHost(); if ( !host ) { return; }
		payload.jurisdictionAnswers = payload.jurisdictionAnswers || {};
		Array.prototype.forEach.call( host.querySelectorAll( '.biscotti-lw-local-q' ), function ( card ) {
			if ( card.style.display === 'none' ) { return; }
			var qid = card.getAttribute( 'data-qid' ); if ( !qid ) { return; }
			var idl = qid.toLowerCase();
			var radio = card.querySelector( 'input[name="lwlq-' + qid + '"]:checked' );
			if ( radio ) {
				payload.jurisdictionAnswers[ qid ] = radio.value;
				if ( idl.indexOf( 'journalistic' ) !== -1 ) { payload.blogJournalisticContent = ( radio.value === 'yes' ); }
				return;
			}
			var visdpInputs = card.querySelectorAll( '.lw-localq-visdp' );
			if ( visdpInputs.length ) {
				Array.prototype.forEach.call( visdpInputs, function ( inp ) {
					var key = inp.getAttribute( 'data-visdp' ); var val = ( inp.value || '' ).trim();
					if ( !key ) { return; }
					if ( key.indexOf( 'visdp_' ) === 0 ) {
						payload[ key.replace( /_([a-z])/g, function ( m, c ) { return c.toUpperCase(); } ) ] = val; // visdp_name -> visdpName
					} else {
						payload.jurisdictionAnswers[ key ] = val;
					}
				} );
				return;
			}
			var addrInputs = card.querySelectorAll( '.lw-localq-addr' );
			if ( addrInputs.length ) {
				Array.prototype.forEach.call( addrInputs, function ( inp ) {
					payload.jurisdictionAnswers[ qid + inp.getAttribute( 'data-sub' ) ] = ( inp.value || '' ).trim();
				} );
				return;
			}
			var txt = card.querySelector( '.lw-localq-text' );
			if ( txt ) { payload.jurisdictionAnswers[ qid ] = ( txt.value || '' ).trim(); }
		} );
	}

	function fetchLocalQuestions( code ) {
		if ( !code ) { renderLocalQuestions( [], {} ); return; }
		$.ajax( {
			url: cfg.ajaxUrl, method: 'POST',
			data: { action: 'biscotti_proxy', nonce: cfg.nonce, proxy_action: 'get-jurisdiction-questions', payload: JSON.stringify( { code: code } ) }
		} )
			.done( function ( res ) {
				var qs = ( res && res.success && res.data && Array.isArray( res.data.questions ) ) ? res.data.questions : [];
				renderLocalQuestions( qs, {} );
			} )
			.fail( function () { renderLocalQuestions( [], {} ); } );
	}

	// Build the save payload — VALID LegalEntity columns only.
	function collectPayload() {
		var rep = gv( 'lw-representative' );
		var p = {
			jurisdiction: gv( 'lw-jurisdiction' ),
			targetAudience: radio( 'lw-targetAudience', 'B2C' ),
			businessCategory: gv( 'lw-businessCategory' ),
			businessSubcategory: gv( 'lw-businessSubcategory' ),
			businessDescription: gv( 'lw-businessDescription' ),
			hasEcommerce: gc( 'lw-hasEcommerce' ),
			hasNewsletter: gc( 'lw-hasNewsletter' ),
			employeeCount: parseInt( gv( 'lw-employeeCount' ), 10 ) || null,
			entityType: ( function () { var s = document.getElementById( 'lw-companyTypeId' ); var o = s && s.options[ s.selectedIndex ]; return ( o && o.getAttribute( 'data-entity-type' ) ) || gv( 'lw-entityType' ) || 'COMPANY'; } )(),
			companyTypeId: gv( 'lw-companyTypeId' ),
			state: gv( 'lw-state' ),
			companyName: gv( 'lw-companyName' ),
			street: gv( 'lw-street' ),
			zip: gv( 'lw-zip' ),
			city: gv( 'lw-city' ),
			country: gv( 'lw-country' ) || 'DE',
			email: gv( 'lw-email' ),
			phone: gv( 'lw-phone' ),
			dpoName: gv( 'lw-dpoName' ),
			dpoEmail: gv( 'lw-dpoEmail' ),
			representatives: rep ? [ { name: rep, role: 'CEO' } ] : [],
			socialMediaProfiles: checks( '.lw-social-cb' ),
			// Contract details (valid columns)
			offer_type: radio( 'lw-offerType', 'invitatio' ),
			contract_conclusion: radio( 'lw-contractConclusion', 'confirmation_email' ),
			prices_include_vat: document.getElementById( 'lw-pricesIncludeVat' ) ? gc( 'lw-pricesIncludeVat' ) : true,
			payment_methods: checks( '.lw-payment-cb' ),
			delivery_type: radio( 'lw-deliveryType', 'physical' ),
			liability_cap: gv( 'lw-liabilityCap' ) || 'contract_value',
			retention_of_title: document.getElementById( 'lw-retentionOfTitle' ) ? gc( 'lw-retentionOfTitle' ) : true,
			// Marketplace (valid columns; only present when the step is rendered)
			marketplaceType: gv( 'lw-marketplaceType' ),
			marketplaceSellerVerification: gv( 'lw-marketplaceSellerVerification' ),
			marketplaceDsaCompliant: document.getElementById( 'lw-marketplaceDsaCompliant' ) ? gc( 'lw-marketplaceDsaCompliant' ) : undefined,
			marketplaceP2bCompliant: document.getElementById( 'lw-marketplaceP2bCompliant' ) ? gc( 'lw-marketplaceP2bCompliant' ) : undefined,
			marketplaceRankingCriteria: gv( 'lw-marketplaceRankingCriteria' ),
			// AVV data categories → valid `dataCategories` column
			dataCategories: checks( '.lw-avv-cat-cb' )
		};
		// Map jurisdiction-specific registration field ids -> canonical LegalEntity
		// columns (cuit->vatId, siret->registerNumber, …) via the shared field map.
		// Always also persist the raw {fieldId: value} set into jurisdictionAnswers so
		// nothing is lost and the round-trip is verifiable for every country.
		var fmap = ( SCHEMA && SCHEMA.fieldColumnMap ) || {};
		var answers = {};
		Array.prototype.forEach.call( document.querySelectorAll( '#lw-registration-fields [data-lw-rf]' ), function ( inp ) {
			var fid = inp.getAttribute( 'data-lw-rf' );
			if ( ! fid ) { return; }
			var val = ( inp.value || '' ).trim();
			answers[ fid ] = val;
			var col = fmap[ fid ] || ( /^(vatId|taxNumber|registerCourt|registerNumber|economicId)$/.test( fid ) ? fid : null );
			if ( col && val ) { p[ col ] = val; }
		} );
		if ( Object.keys( answers ).length ) { p.jurisdictionAnswers = answers; }
		// Merge jurisdiction-specific local-requirements answers (V.i.S.d.P. / §18
		// MStV, …) into the same payload: jurisdictionAnswers + canonical visdp_*
		// columns + blogJournalisticContent. Mirrors the App's save.
		collectLocalAnswers( p );
		return p;
	}

	// Persist the AGB questionnaire answers (rendered inline in the Contract step)
	// as part of the wizard's single Save. No-op when the catalog isn't present.
	// The collector + presence check are exposed by agb-questionnaire.js.
	function saveAgb() {
		if ( typeof window.biscottiAgbHasForm !== 'function' || ! window.biscottiAgbHasForm() ) { return; }
		if ( typeof window.biscottiAgbCollectAnswers !== 'function' ) { return; }
		$.ajax( {
			url: cfg.ajaxUrl,
			method: 'POST',
			data: {
				action: 'biscotti_proxy',
				nonce: cfg.nonce,
				proxy_action: 'save-agb-data',
				payload: JSON.stringify( { agbData: window.biscottiAgbCollectAnswers() } )
			}
		} );
	}

	function saveEntity( cb ) {
		navStatus( '⏳ ' + t( 'saving', 'Saving…' ) );
		// One Save persists everything: legal entity + (if present) AGB answers.
		saveAgb();
		$.ajax( {
			url: cfg.ajaxUrl,
			method: 'POST',
			data: {
				action: 'biscotti_proxy',
				nonce: cfg.nonce,
				proxy_action: 'save-legal-entity',
				payload: JSON.stringify( collectPayload() )
			}
		} )
			.done( function ( res ) {
				if ( res && res.success ) {
					navStatus( '✅ ' + t( 'saved', 'Saved!' ), '#16a34a' );
					setTimeout( function () { navStatus( '' ); }, 2500 );
					if ( cb ) { cb( true ); }
				} else {
					navStatus( '❌ ' + ( ( res && res.data ) || t( 'error', 'Error' ) ), '#dc2626' );
					if ( cb ) { cb( false ); }
				}
			} )
			.fail( function () { navStatus( '❌ ' + t( 'connectionError', 'Connection error' ), '#dc2626' ); if ( cb ) { cb( false ); } } );
	}

	function computeCompliance() {
		var container = document.getElementById( 'lw-compliance-results' );
		if ( ! container ) { return; }
		var code = gv( 'lw-jurisdiction' ) || WD.jurisdiction;
		var j = code && WD.jurLookup ? WD.jurLookup[ code ] : null;
		if ( ! j ) {
			container.innerHTML = '<p class="biscotti-empty-state">⚠️ ' + t( 'selectJurisdiction', 'Please select a jurisdiction first.' ) + '</p>';
			return;
		}
		var model = ( j.model || 'NOTICE' ).toString();
		var needsBanner = model !== 'NO_REQUIREMENT' && model.toLowerCase() !== 'none';
		var empCount = parseInt( gv( 'lw-employeeCount' ), 10 ) || 0;
		var dpoReq = empCount >= 20 || gc( 'lw-hasEcommerce' );
		function pill( cls, txt ) { return '<span class="biscotti-pill ' + cls + '">' + txt + '</span>'; }
		var modelCls = /OPT_IN|opt-in|STRICT/.test( model ) ? 'biscotti-pill-green' : /OPT_OUT|opt-out/.test( model ) ? 'biscotti-pill-amber' : 'biscotti-pill-gray';
		container.innerHTML =
			'<div class="biscotti-lw-comp-grid">' +
			'<div><span class="lw-comp-label">' + t( 'consentModel', 'Consent Model' ) + '</span> ' + pill( modelCls, model.toUpperCase().replace( /_/g, ' ' ) ) + ( j.framework ? ' <span class="description">(' + j.framework + ')</span>' : '' ) + '</div>' +
			'<div><span class="lw-comp-label">' + t( 'cookieBanner', 'Cookie Banner' ) + '</span> ' + pill( needsBanner ? 'biscotti-pill-green' : 'biscotti-pill-gray', needsBanner ? t( 'required', 'Required' ) : t( 'notRequired', 'Not required' ) ) + '</div>' +
			'<div><span class="lw-comp-label">' + t( 'dpoRequired', 'DPO' ) + '</span> ' + pill( dpoReq ? 'biscotti-pill-amber' : 'biscotti-pill-gray', dpoReq ? t( 'recommended', 'Recommended' ) : t( 'notRequired', 'Not required' ) ) + '</div>' +
			'<div><span class="lw-comp-label">' + t( 'jurisdiction', 'Jurisdiction' ) + '</span> ' + pill( 'biscotti-pill-blue', j.name ) + '</div>' +
			'</div>';
	}

	// Re-render the Identity step's jurisdiction-specific controls (legal forms,
	// tax-ID/registration fields, state dropdown) from a schema jurisdiction object.
	// Built with the DOM API (textContent) — no HTML injection, no eval.
	function renderIdentitySchema( j ) {
		if ( ! j ) { return; }
		var sel = document.getElementById( 'lw-companyTypeId' );
		if ( sel ) {
			var prevCt = sel.value;
			sel.innerHTML = '';
			var o0 = document.createElement( 'option' ); o0.value = ''; o0.textContent = '— ' + t( 'select', 'Select' ) + ' —'; sel.appendChild( o0 );
			( j.companyTypes || [] ).forEach( function ( ct ) {
				var o = document.createElement( 'option' );
				o.value = ct.id || ''; o.textContent = ct.label || ct.id || '';
				o.setAttribute( 'data-entity-type', ICON_ENUM[ ct.icon ] || 'COMPANY' );
				sel.appendChild( o );
			} );
			if ( prevCt ) { sel.value = prevCt; }
		}
		var rf = document.getElementById( 'lw-registration-fields' );
		if ( rf ) {
			rf.innerHTML = '';
			var fields = j.registrationFields || {};
			Object.keys( fields ).forEach( function ( fid ) {
				var cfg = fields[ fid ] || {};
				var p = document.createElement( 'p' ); p.className = 'biscotti-form-row';
				var lab = document.createElement( 'label' ); lab.textContent = ( cfg.label || fid ) + ( cfg.required ? ' *' : '' );
				var inp = document.createElement( 'input' );
				inp.type = 'text'; inp.id = 'lw-rf-' + fid; inp.className = 'biscotti-svc-input';
				inp.setAttribute( 'data-lw-rf', fid );
				if ( cfg.placeholder ) { inp.placeholder = cfg.placeholder; }
				p.appendChild( lab ); p.appendChild( inp ); rf.appendChild( p );
			} );
		}
		var sw = document.getElementById( 'lw-state-wrap' );
		if ( sw ) {
			var states = j.states || [];
			var stateLabel = ( j.addressFormat && j.addressFormat.stateLabel ) || t( 'stateProvince', 'State / Province' );
			sw.innerHTML = '';
			if ( states.length ) {
				var p2 = document.createElement( 'p' ); p2.className = 'biscotti-form-row';
				var l2 = document.createElement( 'label' ); l2.textContent = stateLabel; p2.appendChild( l2 );
				var ss = document.createElement( 'select' ); ss.id = 'lw-state'; ss.className = 'biscotti-svc-input';
				var so0 = document.createElement( 'option' ); so0.value = ''; so0.textContent = '— ' + t( 'select', 'Select' ) + ' —'; ss.appendChild( so0 );
				states.forEach( function ( st ) { var o = document.createElement( 'option' ); o.value = st.id || ''; o.textContent = st.name || st.id || ''; ss.appendChild( o ); } );
				p2.appendChild( ss ); sw.appendChild( p2 );
			} else {
				var hid = document.createElement( 'input' ); hid.type = 'hidden'; hid.id = 'lw-state'; sw.appendChild( hid );
			}
		}
		// Derive country code from the selected jurisdiction.
		var jid = j.id || SCHEMA.jurisdictionId || '';
		var cc = '';
		( SCHEMA.countries || [] ).some( function ( c ) { if ( c.jurisdictionId === jid ) { cc = c.code; return true; } return false; } );
		var cEl = document.getElementById( 'lw-country' );
		if ( cEl && cc ) { cEl.value = cc; }
	}

	// Fetch the schema for a newly-selected jurisdiction (DATA via the disclosed proxy).
	function fetchJurisdictionSchema( code ) {
		if ( ! code ) { return; }
		navStatus( '⏳ ' + t( 'loading', 'Loading…' ) );
		$.ajax( {
			url: cfg.ajaxUrl,
			method: 'POST',
			data: { action: 'biscotti_proxy', nonce: cfg.nonce, proxy_action: 'get-jurisdiction-schema', payload: JSON.stringify( { code: code } ) }
		} )
			.done( function ( res ) {
				if ( res && res.success && res.data && res.data.jurisdiction ) {
					SCHEMA.jurisdictionId = res.data.jurisdictionId;
					SCHEMA.jurisdiction = res.data.jurisdiction;
					if ( res.data.countries ) { SCHEMA.countries = res.data.countries; }
					if ( res.data.fieldColumnMap ) { SCHEMA.fieldColumnMap = res.data.fieldColumnMap; }
					renderIdentitySchema( res.data.jurisdiction );
				}
				navStatus( '' );
			} )
			.fail( function () { navStatus( '' ); } );
	}

	$( function () {
		// Jurisdiction change → re-render jurisdiction-specific identity fields + recompute compliance.
		$( '#lw-jurisdiction' ).on( 'change', function () { WD.jurisdiction = this.value; fetchJurisdictionSchema( this.value ); fetchLocalQuestions( this.value ); computeCompliance(); } );

		// Re-evaluate local-question conditional visibility (e.g. show V.i.S.d.P.
		// fields only when "publishes journalistic content" = yes).
		$( document ).on( 'change', '.lw-localq-input', applyLocalConditions );

		// Disclaimer gate.
		$( '#lw-disclaimerAccepted' ).on( 'change', function () {
			var card = document.getElementById( 'lw-gen-card' );
			if ( card ) {
				card.style.opacity = this.checked ? '1' : '0.5';
				card.style.pointerEvents = this.checked ? 'auto' : 'none';
			}
		} );

		// Navigation.
		$( '#lw-btn-next' ).on( 'click', function () {
			if ( currentStep < WD.totalSteps ) {
				saveEntity( function () { showStep( currentStep + 1 ); } );
			} else {
				saveEntity();
			}
		} );
		$( '#lw-btn-back' ).on( 'click', function () { if ( currentStep > 1 ) { showStep( currentStep - 1 ); } } );

		// Clickable progress steps (back freely; forward one step saves).
		$( '.biscotti-lw-step' ).on( 'click', function () {
			var target = parseInt( this.getAttribute( 'data-step' ), 10 );
			if ( target < currentStep ) { showStep( target ); }
			else if ( target === currentStep + 1 ) { saveEntity( function () { showStep( target ); } ); }
		} );

		// Copy shortcode.
		$( document ).on( 'click', '.biscotti-doc-sc', function () {
			var sc = this.textContent;
			if ( navigator.clipboard ) { navigator.clipboard.writeText( sc ); }
			if ( window.BiscottiAdmin && BiscottiAdmin.showToast ) { BiscottiAdmin.showToast( 'success', t( 'copied', 'Copied!' ) ); }
		} );

		// Document generation.
		$( document ).on( 'click', '.lw-gen-btn', function () {
			var $btn = $( this );
			var type = $btn.data( 'type' );
			var status = document.getElementById( 'lw-gen-status' );
			$btn.prop( 'disabled', true ).text( t( 'generating', 'Generating…' ) );
			if ( status ) { status.textContent = t( 'generating', 'Generating…' ); status.style.color = '#64748b'; }
			$.ajax( {
				url: cfg.ajaxUrl,
				method: 'POST',
				data: {
					action: 'biscotti_proxy',
					nonce: cfg.nonce,
					proxy_action: 'generate-document',
					payload: JSON.stringify( { documentType: type, language: 'de' } )
				}
			} )
				.done( function ( res ) {
					$btn.prop( 'disabled', false );
					if ( res && res.success ) {
						$btn.text( '🔄 ' + t( 'regenerate', 'Regenerate' ) );
						var ver = res.data && res.data.document && res.data.document.version ? res.data.document.version : 1;
						$btn.closest( 'tr' ).find( '.lw-doc-status' ).html( '<span class="biscotti-pill biscotti-pill-green">v' + ver + '</span>' );
						if ( status ) { status.textContent = '✅ ' + t( 'saved', 'Generated!' ); status.style.color = '#16a34a'; }
					} else {
						$btn.text( '✨ ' + t( 'generate', 'Generate' ) );
						if ( status ) { status.textContent = '❌ ' + ( ( res && res.data ) || t( 'error', 'Error' ) ); status.style.color = '#dc2626'; }
					}
				} )
				.fail( function () {
					$btn.prop( 'disabled', false ).text( '✨ ' + t( 'generate', 'Generate' ) );
					if ( status ) { status.textContent = '❌ ' + t( 'connectionError', 'Connection error' ); status.style.color = '#dc2626'; }
				} );
		} );

		// Render the jurisdiction-specific local-requirements (seat country) for first
		// paint from the injected single-source data; re-fetched on jurisdiction change.
		renderLocalQuestions( LOCALQ, LOCALA );

		showStep( 1 );
	} );
} )( jQuery );
