/**
 * SiteOrigin RSM Content Widgets — generic JSON import/export via admin AJAX.
 */
( function ( $ ) {
	'use strict';

	var data = window.rsmsparkCwWidgetAdmin || {};
	var i18n = data.i18n || {};
	var exportButtonSelector = '.rsmspark-cw-widget-export-json';
	var importButtonSelector = '.rsmspark-cw-widget-import-json';

	function t( key, fallback ) {
		return i18n[ key ] || fallback;
	}

	function widgetSlug( $trigger ) {
		return String( $trigger.attr( 'data-rsmspark-cw-widget' ) || '' ).trim();
	}

	function widgetForm( $trigger ) {
		var $form = $trigger.closest( '.siteorigin-widget-form' );
		if ( $form.length ) {
			return $form;
		}
		return $trigger
			.closest( '.so-content-tabs, .so-panels-dialog' )
			.find( '.siteorigin-widget-form' )
			.first();
	}

	function findFieldByPath( $form, path ) {
		var pattern = path
			.map( function ( part ) {
				return '[' + part + ']';
			} )
			.join( '' );
		var $fields = $form.find( "[name*='" + pattern + "']" );
		if ( $fields.length ) {
			return $fields.first();
		}
		return $();
	}

	function readFieldValue( $field ) {
		if ( ! $field.length ) {
			return '';
		}

		var type = ( $field.attr( 'type' ) || '' ).toLowerCase();

		if ( type === 'checkbox' ) {
			return $field.is( ':checked' );
		}

		if ( $field.is( 'select[multiple]' ) ) {
			return $field.val() || [];
		}

		return $field.val();
	}

	function setFieldValue( $field, value ) {
		if ( ! $field.length ) {
			return;
		}

		var type = ( $field.attr( 'type' ) || '' ).toLowerCase();

		if ( type === 'checkbox' ) {
			$field.prop( 'checked', !! value ).trigger( 'change' );
			return;
		}

		if ( $field.is( 'select[multiple]' ) ) {
			$field.val( Array.isArray( value ) ? value : [] ).trigger( 'change' );
			return;
		}

		$field.val( value == null ? '' : value ).trigger( 'change' );
	}

	function parseBracketPath( name ) {
		var parts = [];
		var re = /\[([^\]]*)\]/g;
		var match;

		while ( ( match = re.exec( name ) ) ) {
			parts.push( match[ 1 ] );
		}

		if ( parts.length <= 1 ) {
			return null;
		}

		return parts.slice( 1 );
	}

	function setByPath( target, path, value ) {
		var cursor = target;
		var i;

		for ( i = 0; i < path.length - 1; i++ ) {
			var key = path[ i ];
			if ( cursor[ key ] == null || typeof cursor[ key ] !== 'object' ) {
				cursor[ key ] = /^[0-9]+$/.test( String( path[ i + 1 ] ) )
					? []
					: {};
			}
			cursor = cursor[ key ];
		}

		cursor[ path[ path.length - 1 ] ] = value;
	}

	function parseFormToInstance( $form ) {
		var instance = {};

		$form.find( 'input, select, textarea' ).each( function () {
			var name = this.name || '';
			var path = parseBracketPath( name );

			if ( ! path || ! path.length ) {
				return;
			}

			var value = readFieldValue( $( this ) );
			var last = path[ path.length - 1 ];

			if ( last === 'export_json' || last === 'import_json' ) {
				return;
			}

			setByPath( instance, path, value );
		} );

		return instance;
	}

	function applyPathToForm( $form, path, value ) {
		if ( path.length === 0 ) {
			return;
		}

		var $field = findFieldByPath( $form, path );
		if ( ! $field.length ) {
			return;
		}

		setFieldValue( $field, value );
	}

	function walkInstance( $form, value, path ) {
		var key;

		if ( Array.isArray( value ) ) {
			value.forEach( function ( item, index ) {
				walkInstance( $form, item, path.concat( [ String( index ) ] ) );
			} );
			return;
		}

		if ( value && typeof value === 'object' ) {
			for ( key in value ) {
				if ( Object.prototype.hasOwnProperty.call( value, key ) ) {
					walkInstance( $form, value[ key ], path.concat( [ key ] ) );
				}
			}
			return;
		}

		applyPathToForm( $form, path, value );
	}

	function applyInstanceToForm( $form, instance ) {
		var key;

		for ( key in instance ) {
			if ( ! Object.prototype.hasOwnProperty.call( instance, key ) ) {
				continue;
			}
			if ( key === 'import_export' ) {
				continue;
			}
			walkInstance( $form, instance[ key ], [ key ] );
		}
	}

	function findField( $form, section, key ) {
		var pattern =
			"[name*='[" +
			section +
			'][' +
			key +
			"]'], [name*='-" +
			section +
			'-' +
			key +
			"'], [name*='_" +
			section +
			'_' +
			key +
			"']";
		var $fields = $form.find( pattern );
		if ( $fields.length ) {
			return $fields.first();
		}
		return $form
			.find( '[name*="' + section + '"][name*="' + key + '"]' )
			.first();
	}

	function readFieldInSection( $form, section, key ) {
		return readFieldValue( findField( $form, section, key ) );
	}

	function setExportFieldInSection( $form, section, key, value ) {
		var text = value == null ? '' : String( value );
		var $field = findField( $form, section, key );

		if ( $field.length ) {
			$field.val( text );
		}

		showSoExportJsonPreview( $form, text );
	}

	function showSoExportJsonPreview( $form, text ) {
		var $button = $form.find( exportButtonSelector ).first();
		if ( ! $button.length ) {
			return;
		}

		var exportText = String( text || '' );
		$form.data( 'rsmCwLastExportJson', exportText );

		var $fieldWrap = $button.closest(
			'.siteorigin-widget-field, .so-field-wrapper, .so-field-textarea, .so-field'
		);

		if ( ! $fieldWrap.length ) {
			$fieldWrap = $button.parent();
		}

		var $mount = $fieldWrap
			.children( '.rsmspark-cw-so-export-json-mount' )
			.first();

		if ( ! $mount.length ) {
			$mount = $( '<div class="rsmspark-cw-so-export-json-mount"></div>' );
			$button.closest( 'p' ).after( $mount );
		}

		$mount.empty();

		if ( ! exportText.trim() ) {
			return;
		}

		$mount.append(
			$( '<p class="description rsmspark-cw-so-export-json-label">' ).text(
				t(
					'exportLabel',
					'Generated export (also copied to your clipboard):'
				)
			),
			$(
				'<pre class="rsmspark-cw-so-export-json-preview" tabindex="0" role="textbox" aria-readonly="true"></pre>'
			).text( exportText )
		);

		var pre = $mount.find( '.rsmspark-cw-so-export-json-preview' )[ 0 ];
		if ( pre && pre.scrollIntoView ) {
			pre.scrollIntoView( { block: 'nearest', behavior: 'smooth' } );
		}
	}

	function isAppearanceWidgetsScreen() {
		return ( window.location.pathname || '' ).indexOf( 'widgets.php' ) !== -1;
	}

	function showExportJsonPanel( text ) {
		if (
			window.RsmCwExportJsonUi &&
			typeof window.RsmCwExportJsonUi.show === 'function'
		) {
			window.RsmCwExportJsonUi.show( text, {
				title: t( 'exportPanelTitle', 'JSON export ready' ),
				widgetArea: isAppearanceWidgetsScreen(),
			} );
		}
	}

	function refreshSoExportDisplay( $form, text ) {
		setExportFieldInSection( $form, 'import_export', 'export_json', text );
		showExportJsonPanel( text );

		if ( isAppearanceWidgetsScreen() ) {
			return;
		}

		[ 0, 50, 250 ].forEach( function ( delay ) {
			window.setTimeout( function () {
				showSoExportJsonPreview( $form, text );
				var $field = findField( $form, 'import_export', 'export_json' );
				if ( $field.length ) {
					$field.val( String( text || '' ) );
				}
			}, delay );
		} );
	}

	function postWidgetJson( payload ) {
		if ( ! data.ajaxUrl ) {
			return $.Deferred().reject().promise();
		}

		return $.post( data.ajaxUrl || '', payload );
	}

	function reportSetupError() {
		window.alert(
			t(
				'setupError',
				'Export could not start. Reload the widget form and try again.'
			)
		);
	}

	$( document ).on( 'click', exportButtonSelector, function ( event ) {
		event.preventDefault();
		event.stopPropagation();

		if ( ! data.ajaxUrl || ! data.nonce ) {
			reportSetupError();
			return;
		}

		var $trigger = $( this );
		var slug = widgetSlug( $trigger );
		var $form = widgetForm( $trigger );

		if ( ! slug || ! $form.length ) {
			reportSetupError();
			return;
		}

		postWidgetJson( {
			action: 'rsmspark_cw_widget_json',
			nonce: data.nonce || '',
			widget: slug,
			mode: 'export',
			instance: JSON.stringify( parseFormToInstance( $form ) ),
		} )
			.done( function ( response ) {
				if ( ! response || ! response.success || ! response.data ) {
					window.alert(
						t(
							'requestError',
							'Could not process widget JSON. Try again.'
						)
					);
					return;
				}

				var text = JSON.stringify( response.data, null, 2 );
				refreshSoExportDisplay( $form, text );

				if ( navigator.clipboard && navigator.clipboard.writeText ) {
					navigator.clipboard.writeText( text ).catch( function () {} );
				}
			} )
			.fail( function () {
				window.alert(
					t(
						'requestError',
						'Could not process widget JSON. Try again.'
					)
				);
			} );
	} );

	$( document ).on( 'click', importButtonSelector, function ( event ) {
		event.preventDefault();

		if ( ! data.ajaxUrl || ! data.nonce ) {
			reportSetupError();
			return;
		}

		var $trigger = $( this );
		var slug = widgetSlug( $trigger );
		var $form = widgetForm( $trigger );

		if ( ! slug || ! $form.length ) {
			reportSetupError();
			return;
		}

		var raw = String(
			readFieldInSection( $form, 'import_export', 'import_json' ) || ''
		);

		if ( ! raw.trim() ) {
			window.alert(
				t(
					'importError',
					'Paste valid RSM widget JSON export data (widget or block export).'
				)
			);
			return;
		}

		if (
			! window.confirm(
				t(
					'confirm',
					'Apply this import? Current settings will be overwritten.'
				)
			)
		) {
			return;
		}

		postWidgetJson( {
			action: 'rsmspark_cw_widget_json',
			nonce: data.nonce || '',
			widget: slug,
			mode: 'import',
			payload: raw,
			instance: JSON.stringify( parseFormToInstance( $form ) ),
		} )
			.done( function ( response ) {
				if ( ! response || ! response.success || ! response.data ) {
					window.alert(
						t(
							'importError',
							'Paste valid RSM widget JSON export data (widget or block export).'
						)
					);
					return;
				}

				applyInstanceToForm( $form, response.data.instance || {} );

				window.alert(
					t(
						'importApplied',
						'Import applied. Review repeater rows if counts changed.'
					)
				);
			} )
			.fail( function () {
				window.alert(
					t(
						'requestError',
						'Could not process widget JSON. Try again.'
					)
				);
			} );
	} );
}( jQuery ) );
