/**
 * Agency Pulse — Admin Menu Organizer — Settings page
 *
 * Handles cloud backup push/pull, License & Connection UI,
 * and Plugin Access Control mode/grant/revoke.
 * Data supplied via aamoSettingsData (wp_localize_script).
 *
 * @package Agency_Pulse_Admin_Menu
 * @since   1.0.0
 */

/* global aamoSettingsData, jQuery */
( function ( $, data ) {
	'use strict';

	function setStatus( $el, msg ) {
		$el.text( msg );
	}

	function post( action, nonce, extraData, onSuccess, onError, onAlways ) {
		var payload = $.extend( { action: action, nonce: nonce }, extraData || {} );
		$.post( data.ajaxUrl, payload )
			.done( function ( resp ) {
				if ( resp && resp.success ) {
					onSuccess( resp.data || {} );
				} else {
					var msg = ( resp && resp.data && resp.data.message )
						? resp.data.message
						: data.i18n.error;
					onError( msg );
				}
			} )
			.fail( function () {
				onError( data.i18n.error );
			} )
			.always( onAlways );
	}

	$( function () {
		// ── File picker ───────────────────────────────────────────────────────

		$( '#aamo-import-file' ).on( 'change', function () {
			var name = this.files && this.files[0] ? this.files[0].name : data.i18n.noFile;
			$( '#aamo-import-file-name' ).text( name );
		} );

		// ── Backup buttons ────────────────────────────────────────────────────

		var $pushBtn    = $( '#aamo-backup-push' );
		var $pushStatus = $( '#aamo-backup-push-status' );
		var $pullBtn    = $( '#aamo-backup-pull' );
		var $pullStatus = $( '#aamo-backup-pull-status' );

		$pushBtn.on( 'click', function () {
			$pushBtn.prop( 'disabled', true );
			setStatus( $pushStatus, data.i18n.pushing );

			post(
				data.actionPush, data.noncePush, null,
				function () { setStatus( $pushStatus, data.i18n.pushSuccess ); },
				function ( msg ) { setStatus( $pushStatus, msg ); },
				function ()      { $pushBtn.prop( 'disabled', ! data.proActive ); }
			);
		} );

		$pullBtn.on( 'click', function () {
			if ( ! window.confirm( data.i18n.pullConfirm ) ) {
				return;
			}

			$pullBtn.prop( 'disabled', true );
			setStatus( $pullStatus, data.i18n.pulling );

			post(
				data.actionPull, data.noncePull, null,
				function ( respData ) {
					setStatus( $pullStatus, respData.message || data.i18n.pullSuccess );
					setTimeout( function () { window.location.reload(); }, 1200 );
				},
				function ( msg ) { setStatus( $pullStatus, msg ); },
				function ()      { $pullBtn.prop( 'disabled', ! data.proActive ); }
			);
		} );

		// ── License & Connection ──────────────────────────────────────────────

		var $licenseWrap = $( '#aamo-license-wrap' );

		/**
		 * Show the correct state panel and sync the backup buttons.
		 *
		 * @param {string} status  One of: inactive, pending_email, active, slot_full, revoked.
		 * @param {Object} [extra] Additional data from the AJAX response (slot_id, etc.).
		 */
		function updateLicenseUI( status, extra ) {
			$licenseWrap.find( '.aamo-license-state' ).hide();
			$licenseWrap.find( '.aamo-license-state[data-status="' + status + '"]' ).show();

			if ( 'active' === status && extra && extra.slot_id ) {
				$licenseWrap.find( '.aamo-slot-id' ).text(
					'Slot #' + extra.slot_id
				);
			}

			var isActive = 'active' === status;
			data.proActive = isActive ? 1 : 0;
			$pushBtn.prop( 'disabled', ! isActive );
			$pullBtn.prop( 'disabled', ! isActive );
			$( '#aamo-backup-wrap .aamo-settings-actions, #aamo-access-control-wrap .aamo-ac-controls, #aamo-dashboard-msg-wrap .aamo-dm-controls' )
				.toggleClass( 'aamo-panel-locked', ! isActive );
		}

		// Sync the initial state rendered by PHP.
		updateLicenseUI( data.licenseStatus || 'inactive' );

		// Connect — initial key submission.
		$( '#aamo-ao-connect-btn' ).on( 'click', function () {
			var key = $( '#aamo-plugin-key' ).val().trim();
			if ( ! key ) {
				setStatus( $( '#aamo-connect-status' ), data.i18n.error );
				return;
			}

			var $btn = $( this );
			$btn.prop( 'disabled', true );
			setStatus( $( '#aamo-connect-status' ), data.aoI18n.connecting );

			$.post( data.ajaxUrl, {
				action:         data.actionAoConnect,
				nonce:          data.nonceAoConnect,
				plugin_key:     key,
				connect_action: 'connect'
			} )
			.done( function ( resp ) {
				if ( resp && resp.data && resp.data.status ) {
					if ( 'active' === resp.data.status ) {
						window.location.reload();
						return;
					}
					updateLicenseUI( resp.data.status, resp.data );
					setStatus( $( '#aamo-connect-status' ), resp.data.message || '' );
				} else if ( resp && ! resp.success ) {
					setStatus( $( '#aamo-connect-status' ), ( resp.data && resp.data.message ) ? resp.data.message : data.i18n.error );
				}
			} )
			.fail( function () {
				setStatus( $( '#aamo-connect-status' ), data.i18n.error );
			} )
			.always( function () {
				$btn.prop( 'disabled', false );
			} );
		} );

		// Check connection — after user clicks email confirmation link.
		$( '#aamo-ao-check-btn' ).on( 'click', function () {
			var $btn = $( this );
			$btn.prop( 'disabled', true );
			setStatus( $( '#aamo-check-status' ), data.aoI18n.checking );

			$.post( data.ajaxUrl, {
				action:         data.actionAoConnect,
				nonce:          data.nonceAoConnect,
				connect_action: 'check_connection'
			} )
			.done( function ( resp ) {
				if ( resp && resp.data && resp.data.status ) {
					if ( 'active' === resp.data.status ) {
						window.location.reload();
						return;
					}
					updateLicenseUI( resp.data.status, resp.data );
					setStatus( $( '#aamo-check-status' ), resp.data.message || '' );
				} else if ( resp && ! resp.success ) {
					setStatus( $( '#aamo-check-status' ), ( resp.data && resp.data.message ) ? resp.data.message : data.i18n.error );
				}
			} )
			.fail( function () {
				setStatus( $( '#aamo-check-status' ), data.i18n.error );
			} )
			.always( function () {
				$btn.prop( 'disabled', false );
			} );
		} );

		// Disconnect — clear local state, release slot via dashboard externally.
		$( '#aamo-ao-disconnect-btn' ).on( 'click', function () {
			var $btn = $( this );
			$btn.prop( 'disabled', true );

			$.post( data.ajaxUrl, {
				action:         data.actionAoConnect,
				nonce:          data.nonceAoConnect,
				connect_action: 'disconnect'
			} )
			.done( function ( resp ) {
				if ( resp && resp.success ) {
					updateLicenseUI( 'inactive' );
				}
			} )
			.always( function () {
				$btn.prop( 'disabled', false );
			} );
		} );

		// Retry after slot_full — show the inactive/key-entry panel.
		$( '#aamo-ao-retry-btn' ).on( 'click', function () {
			updateLicenseUI( 'inactive' );
		} );

		// ── Plugin Access Control ─────────────────────────────────────────────

		var ac = {
			i18n:             data.acI18n             || {},
			nonceSetMode:     data.nonceSetMode        || '',
			nonceGrant:       data.nonceGrant          || '',
			nonceRevoke:      data.nonceRevoke         || '',
			actionSetMode:    data.actionSetMode       || '',
			actionGrant:      data.actionGrant         || '',
			actionRevoke:     data.actionRevoke        || '',
			canEnableCapOnly: !! data.canEnableCapOnly
		};

		var $applyBtn     = $( '#aamo-apply-mode' );
		var $applyStatus  = $( '#aamo-apply-mode-status' );
		var $grantBtn     = $( '#aamo-grant-cap' );
		var $revokeBtn    = $( '#aamo-revoke-cap' );
		var $grantStatus  = $( '#aamo-grant-status' );
		var $capOnlyRadio = $( '#aamo-cap-only-radio' );

		function getSelectedUserId() {
			return parseInt( $( '#aamo-grant-user-select' ).val(), 10 ) || 0;
		}

		function updateCapOnlyRadio( canEnable ) {
			ac.canEnableCapOnly = !! canEnable;
			$capOnlyRadio.prop( 'disabled', ! ac.canEnableCapOnly );
			$capOnlyRadio.closest( '.aamo-access-mode-option' )
				.toggleClass( 'aamo-access-mode-disabled', ! ac.canEnableCapOnly );

			if ( ! ac.canEnableCapOnly && $capOnlyRadio.is( ':checked' ) ) {
				$( 'input[name="aamo_access_mode"][value="default"]' ).prop( 'checked', true );
			}
		}

		function renderHoldersList( holders ) {
			var $list    = $( '#aamo-holders-list' );
			var $heading = $( '<h4 class="aamo-settings-subheading-sm"></h4>' )
				.text( ac.i18n.usersWithAccess );

			$list.empty().append( $heading );

			if ( ! holders || holders.length === 0 ) {
				$( '<p class="aamo-settings-note" id="aamo-no-holders"></p>' )
					.text( ac.i18n.noHolders )
					.appendTo( $list );
				return;
			}

			var $table = $( '<table class="aamo-holders-table"><tbody id="aamo-holders-tbody"></tbody></table>' );
			var $tbody = $table.find( 'tbody' );

			$.each( holders, function ( i, h ) {
				var $tr  = $( '<tr>' ).attr( 'data-user-id', h.id );
				var $td1 = $( '<td>' ).text( h.name + ' (' + h.email + ')' );
				var $btn = $( '<button type="button" class="button button-small aamo-revoke-holder"></button>' )
					.text( ac.i18n.revoke )
					.attr( 'data-user-id', h.id );
				var $td2 = $( '<td>' ).append( $btn );
				$tr.append( $td1, $td2 );
				$tbody.append( $tr );
			} );

			$list.append( $table );
		}

		// Apply Mode.
		$applyBtn.on( 'click', function () {
			var mode = $( 'input[name="aamo_access_mode"]:checked' ).val();
			if ( ! mode ) {
				return;
			}

			$applyBtn.prop( 'disabled', true ).text( ac.i18n.applying );
			setStatus( $applyStatus, '' );

			$.post( data.ajaxUrl, {
				action: ac.actionSetMode,
				nonce:  ac.nonceSetMode,
				mode:   mode
			} )
			.done( function ( resp ) {
				if ( resp && resp.success ) {
					if ( resp.data && resp.data.will_lose_access ) {
						var proceed = window.confirm( ac.i18n.lockoutWarning );
						if ( ! proceed ) {
							setStatus( $applyStatus, ac.i18n.lockoutReminder );
							$applyBtn.prop( 'disabled', false ).text( 'Apply Mode' );
							return;
						}
					}
					window.location.reload();
				} else {
					var msg = ( resp && resp.data && resp.data.message )
						? resp.data.message
						: ac.i18n.error;
					setStatus( $applyStatus, msg );
					$applyBtn.prop( 'disabled', false ).text( 'Apply Mode' );
				}
			} )
			.fail( function () {
				setStatus( $applyStatus, ac.i18n.error );
				$applyBtn.prop( 'disabled', false ).text( 'Apply Mode' );
			} );
		} );

		// Grant Permission.
		$grantBtn.on( 'click', function () {
			var userId = getSelectedUserId();
			if ( ! userId ) {
				setStatus( $grantStatus, ac.i18n.error );
				return;
			}

			$grantBtn.prop( 'disabled', true );
			$revokeBtn.prop( 'disabled', true );
			setStatus( $grantStatus, '' );

			$.post( data.ajaxUrl, {
				action:  ac.actionGrant,
				nonce:   ac.nonceGrant,
				user_id: userId
			} )
			.done( function ( resp ) {
				if ( resp && resp.success ) {
					setStatus( $grantStatus, ac.i18n.grantSuccess );
					renderHoldersList( resp.data.holders );
					updateCapOnlyRadio( resp.data.canEnableCapOnly );
				} else {
					var msg = ( resp && resp.data && resp.data.message )
						? resp.data.message
						: ac.i18n.error;
					setStatus( $grantStatus, msg );
				}
			} )
			.fail( function () {
				setStatus( $grantStatus, ac.i18n.error );
			} )
			.always( function () {
				$grantBtn.prop( 'disabled', false );
				$revokeBtn.prop( 'disabled', false );
			} );
		} );

		// Revoke Permission (main form button — acts on the selected user).
		$revokeBtn.on( 'click', function () {
			var userId = getSelectedUserId();
			if ( ! userId ) {
				setStatus( $grantStatus, ac.i18n.error );
				return;
			}

			$grantBtn.prop( 'disabled', true );
			$revokeBtn.prop( 'disabled', true );
			setStatus( $grantStatus, '' );

			$.post( data.ajaxUrl, {
				action:  ac.actionRevoke,
				nonce:   ac.nonceRevoke,
				user_id: userId
			} )
			.done( function ( resp ) {
				if ( resp && resp.success ) {
					setStatus( $grantStatus, ac.i18n.revokeSuccess );
					renderHoldersList( resp.data.holders );
					updateCapOnlyRadio( resp.data.canEnableCapOnly );
				} else {
					var msg = ( resp && resp.data && resp.data.message )
						? resp.data.message
						: ac.i18n.error;
					setStatus( $grantStatus, msg );
				}
			} )
			.fail( function () {
				setStatus( $grantStatus, ac.i18n.error );
			} )
			.always( function () {
				$grantBtn.prop( 'disabled', false );
				$revokeBtn.prop( 'disabled', false );
			} );
		} );

		// ── Dashboard Message ─────────────────────────────────────────────────

		var dm = {
			nonce:  data.nonceDashboard   || '',
			action: data.actionDashboard  || '',
			i18n:   data.dmI18n           || {}
		};

		var $dmSave   = $( '#aamo-dm-save' );
		var $dmStatus = $( '#aamo-dm-status' );

		function getDashboardContent() {
			var editor = typeof tinymce !== 'undefined' && tinymce.get( 'aamo_message_content' );
			return editor ? editor.getContent() : $( '#aamo_message_content' ).val();
		}

		$dmSave.on( 'click', function () {
			$dmSave.prop( 'disabled', true ).text( dm.i18n.saving );
			setStatus( $dmStatus, '' );

			$.post( data.ajaxUrl, {
				action:     dm.action,
				nonce:      dm.nonce,
				enabled:    $( '#aamo-dm-enabled' ).is( ':checked' ) ? '1' : '0',
				show_first: $( '#aamo-dm-show-first' ).is( ':checked' ) ? '1' : '0',
				title:      $( '#aamo-dm-title' ).val(),
				content:    getDashboardContent()
			} )
			.done( function ( resp ) {
				if ( resp && resp.success ) {
					setStatus( $dmStatus, ( resp.data && resp.data.message ) ? resp.data.message : dm.i18n.saved );
				} else {
					var msg = ( resp && resp.data && resp.data.message ) ? resp.data.message : dm.i18n.error;
					setStatus( $dmStatus, msg );
				}
			} )
			.fail( function () {
				setStatus( $dmStatus, dm.i18n.error );
			} )
			.always( function () {
				$dmSave.prop( 'disabled', false ).text( 'Save Dashboard Message' );
			} );
		} );

		// Inline Revoke buttons in the holders list (delegated — list re-renders on grant/revoke).
		$( '#aamo-holders-list' ).on( 'click', '.aamo-revoke-holder', function () {
			var userId = parseInt( $( this ).data( 'user-id' ), 10 );
			if ( ! userId ) {
				return;
			}

			var $btn = $( this ).prop( 'disabled', true );
			setStatus( $grantStatus, '' );

			$.post( data.ajaxUrl, {
				action:  ac.actionRevoke,
				nonce:   ac.nonceRevoke,
				user_id: userId
			} )
			.done( function ( resp ) {
				if ( resp && resp.success ) {
					setStatus( $grantStatus, ac.i18n.revokeSuccess );
					renderHoldersList( resp.data.holders );
					updateCapOnlyRadio( resp.data.canEnableCapOnly );
				} else {
					var msg = ( resp && resp.data && resp.data.message )
						? resp.data.message
						: ac.i18n.error;
					setStatus( $grantStatus, msg );
					$btn.prop( 'disabled', false );
				}
			} )
			.fail( function () {
				setStatus( $grantStatus, ac.i18n.error );
				$btn.prop( 'disabled', false );
			} );
		} );


		// ── Template Library ──────────────────────────────────────────────────

		var tl            = data.tlI18n || {};
		var $tlWrap       = $( '#aamo-template-wrap' );

		// Only wire up if the panel exists and is not locked.
		if ( $tlWrap.length && ! $tlWrap.hasClass( 'aamo-panel-locked' ) ) {

			var $tlName       = $( '#aamo-tl-name' );
			var $tlDesc       = $( '#aamo-tl-desc' );
			var $tlSaveBtn    = $( '#aamo-tl-save' );
			var $tlSaveStatus = $( '#aamo-tl-save-status' );
			var $tlNameError  = $( '.aamo-tl-name-error' );
			var $tlRefresh    = $( '#aamo-tl-refresh' );
			var $tlList       = $( '#aamo-tl-list' );

			function tlSetStatus( $el, msg ) {
				$el.text( msg );
			}

			function tlShowNameError( msg ) {
				$tlNameError.text( msg ).show();
			}

			function tlClearNameError() {
				$tlNameError.hide().text( '' );
			}

			function tlFormatDate( iso ) {
				if ( ! iso ) { return ''; }
				try {
					return new Date( iso ).toLocaleDateString( undefined, {
						year: 'numeric', month: 'short', day: 'numeric'
					} );
				} catch ( e ) {
					return iso.slice( 0, 10 );
				}
			}

			// ── Render ─────────────────────────────────────────────────────────

			function tlRenderList( templates ) {
				$tlList.empty();

				if ( ! templates || templates.length === 0 ) {
					var $empty = $( '<p>' ).addClass( 'aamo-settings-note' );
					$empty[ 0 ].textContent = tl.empty;
					$tlList.append( $empty );
					return;
				}

				$.each( templates, function ( i, tmpl ) {
					var $row     = $( '<div>' ).addClass( 'aamo-tl-row' );
					var $meta    = $( '<div>' ).addClass( 'aamo-tl-row-meta' );
					var $name    = $( '<div>' ).addClass( 'aamo-tl-row-name' );
					var $desc    = $( '<div>' ).addClass( 'aamo-tl-row-desc' );
					var $date    = $( '<div>' ).addClass( 'aamo-tl-row-date' );
					var $actions = $( '<div>' ).addClass( 'aamo-tl-row-actions' );
					var $status  = $( '<span>' ).addClass( 'aamo-tl-row-status' );
					var $apply   = $( '<button>' ).addClass( 'button aamo-tl-apply' )
						.attr( 'type', 'button' )
						.attr( 'data-slug', tmpl.slug )
						.attr( 'data-name', tmpl.name );
					var $del     = $( '<button>' ).addClass( 'button aamo-tl-delete' )
						.attr( 'type', 'button' )
						.attr( 'data-slug', tmpl.slug )
						.attr( 'data-name', tmpl.name );

					// Use textContent for all user-supplied strings — never innerHTML.
					$name[ 0 ].textContent  = tmpl.name;
					$desc[ 0 ].textContent  = tmpl.description || '—';
					$date[ 0 ].textContent  = tlFormatDate( tmpl.created_at );
					$apply[ 0 ].textContent = 'Apply';
					$del[ 0 ].textContent   = 'Delete';

					$meta.append( $name, $desc );
					$actions.append( $apply, $del, $status );
					$row.append( $meta, $date, $actions );
					$tlList.append( $row );
				} );
			}

			function tlShowListError( msg ) {
				$tlList.empty();
				var $err = $( '<p>' ).addClass( 'aamo-settings-note' );
				$err[ 0 ].textContent = msg;
				var $retry = $( '<a>' ).attr( 'href', '#' ).css( 'margin-left', '6px' );
				$retry[ 0 ].textContent = 'Refresh List';
				$retry.on( 'click', function ( e ) { e.preventDefault(); tlLoadList(); } );
				$err.append( $retry );
				$tlList.append( $err );
			}

			// ── Load list ──────────────────────────────────────────────────────

			function tlLoadList() {
				$tlList.empty();
				var $loading = $( '<p>' ).addClass( 'aamo-settings-note aamo-tl-loading' );
				$loading[ 0 ].textContent = tl.loading;
				$tlList.append( $loading );

				$.post( data.ajaxUrl, {
					action: data.actionTlList,
					nonce:  data.nonceTlList,
				} )
				.done( function ( resp ) {
					if ( resp && resp.success && resp.data && resp.data.templates ) {
						tlRenderList( resp.data.templates );
					} else {
						var msg = ( resp && resp.data && resp.data.message )
							? resp.data.message : tl.loadError;
						tlShowListError( msg );
					}
				} )
				.fail( function () {
					tlShowListError( tl.loadError );
				} );
			}

			// Auto-load on page open.
			tlLoadList();

			$tlRefresh.on( 'click', tlLoadList );

			// ── Save ───────────────────────────────────────────────────────────

			$tlSaveBtn.on( 'click', function () {
				var name = $.trim( $tlName.val() );
				tlClearNameError();
				tlSetStatus( $tlSaveStatus, '' );

				if ( '' === name ) {
					tlShowNameError( tl.nameRequired );
					$tlName.trigger( 'focus' );
					return;
				}

				$tlSaveBtn.prop( 'disabled', true );
				tlSetStatus( $tlSaveStatus, tl.saving );

				$.post( data.ajaxUrl, {
					action:      data.actionTlSave,
					nonce:       data.nonceTlSave,
					name:        name,
					description: $.trim( $tlDesc.val() ),
				} )
				.done( function ( resp ) {
					if ( resp && resp.success ) {
						var msg = resp.data && resp.data.message ? resp.data.message : tl.saved;
						tlSetStatus( $tlSaveStatus, msg );
						tlLoadList();
					} else {
						// Distinguish name_taken from generic errors.
						if ( resp && resp.data && resp.data.name_taken ) {
							tlShowNameError( resp.data.message || tl.nameTaken );
							tlSetStatus( $tlSaveStatus, '' );
						} else {
							var errMsg = ( resp && resp.data && resp.data.message )
								? resp.data.message : tl.error;
							tlSetStatus( $tlSaveStatus, errMsg );
						}
					}
				} )
				.fail( function () {
					tlSetStatus( $tlSaveStatus, tl.error );
				} )
				.always( function () {
					$tlSaveBtn.prop( 'disabled', false );
				} );
			} );

			// Clear name error when the user starts typing.
			$tlName.on( 'input', tlClearNameError );

			// ── Apply / Delete (event delegation on list container) ────────────

			$tlList.on( 'click', '.aamo-tl-apply', function () {
				var $btn  = $( this );
				var slug  = $btn.data( 'slug' );
				var $row    = $btn.closest( '.aamo-tl-row' );
				var $del    = $row.find( '.aamo-tl-delete' );
				var $status = $row.find( '.aamo-tl-row-status' );

				// eslint-disable-next-line no-alert
				if ( ! window.confirm( tl.applyConfirm ) ) { return; }

				$btn.prop( 'disabled', true );
				$del.prop( 'disabled', true );
				$status.text( tl.applying );

				$.post( data.ajaxUrl, {
					action: data.actionTlApply,
					nonce:  data.nonceTlApply,
					slug:   slug,
				} )
				.done( function ( resp ) {
					if ( resp && resp.success ) {
						window.location.reload();
					} else {
						var msg = ( resp && resp.data && resp.data.message )
							? resp.data.message : tl.error;
						$status.text( msg );
						$btn.prop( 'disabled', false );
						$del.prop( 'disabled', false );
					}
				} )
				.fail( function () {
					$status.text( tl.error );
					$btn.prop( 'disabled', false );
					$del.prop( 'disabled', false );
				} );
			} );

			$tlList.on( 'click', '.aamo-tl-delete', function () {
				var $btn  = $( this );
				var slug  = $btn.data( 'slug' );
				var name  = $btn.data( 'name' );
				var confirmMsg = ( tl.deleteConfirm || 'Delete "%s"? This cannot be undone.' )
					.replace( '%s', name );

				// eslint-disable-next-line no-alert
				if ( ! window.confirm( confirmMsg ) ) { return; }

				var $row    = $btn.closest( '.aamo-tl-row' );
				var $apply  = $row.find( '.aamo-tl-apply' );
				var $status = $row.find( '.aamo-tl-row-status' );

				$btn.prop( 'disabled', true );
				$apply.prop( 'disabled', true );
				$status.text( tl.deleting );

				$.post( data.ajaxUrl, {
					action: data.actionTlDelete,
					nonce:  data.nonceTlDelete,
					slug:   slug,
				} )
				.done( function ( resp ) {
					if ( resp && resp.success ) {
						$row.fadeOut( 200, function () {
							$row.remove();
							if ( $tlList.find( '.aamo-tl-row' ).length === 0 ) {
								var $empty = $( '<p>' ).addClass( 'aamo-settings-note' );
								$empty[ 0 ].textContent = tl.empty;
								$tlList.append( $empty );
							}
						} );
					} else {
						var msg = ( resp && resp.data && resp.data.message )
							? resp.data.message : tl.error;
						$status.text( msg );
						$btn.prop( 'disabled', false );
						$apply.prop( 'disabled', false );
					}
				} )
				.fail( function () {
					$status.text( tl.error );
					$btn.prop( 'disabled', false );
					$apply.prop( 'disabled', false );
				} );
			} );


		} // end if $tlWrap exists and not locked

		// ── Admin Bar Customizer ───────────────────────────────────────────────

		var cust          = data.custI18n || {};
		var $brandingWrap = $( '#aamo-branding-wrap' );

		if ( $brandingWrap.length && ! $brandingWrap.hasClass( 'aamo-panel-locked' ) ) {

			var $brandingEnabled     = $( '#aamo-branding-enabled' );
			var $brandingIconFields  = $( '#aamo-branding-icon-fields' );
			var $brandingIconUrl     = $( '#aamo-branding-icon-url' );
			var $brandingPreview     = $( '#aamo-branding-preview' );
			var $brandingPreviewWrap = $( '#aamo-branding-preview-wrap' );
			var $brandingClear       = $( '#aamo-branding-clear' );
			var $brandingSave        = $( '#aamo-branding-save' );
			var $brandingStatus      = $( '#aamo-branding-status' );

			// Enable toggle — show/hide icon fields.
			$brandingEnabled.on( 'change', function () {
				$brandingIconFields.toggle( this.checked );
			} );

			// Link mode radio — show/hide custom URL + new-tab fields.
			$( '[name="aamo_link_mode"]' ).on( 'change', function () {
				var isCustom = 'custom' === this.value;
				$( '#aamo-branding-link-url, #aamo-branding-link-target-wrap' ).toggle( isCustom );
			} );

			// Media Library picker.
			var brandingFrame;
			$( '#aamo-branding-choose' ).on( 'click', function ( e ) {
				e.preventDefault();
				if ( brandingFrame ) { brandingFrame.open(); return; }
				brandingFrame = wp.media( {
					title:    cust.selectIcon,
					button:   { text: cust.useThisImage },
					multiple: false,
					library:  { type: 'image' },
				} );
				brandingFrame.on( 'select', function () {
					var attachment = brandingFrame.state().get( 'selection' ).first().toJSON();
					$brandingIconUrl.val( attachment.url );
					$brandingPreview.attr( 'src', attachment.url );
					$brandingPreviewWrap.show();
					$brandingClear.show();
				} );
				brandingFrame.open();
			} );

			// Clear icon.
			$brandingClear.on( 'click', function ( e ) {
				e.preventDefault();
				$brandingIconUrl.val( '' );
				$brandingPreviewWrap.hide();
				$brandingClear.hide();
			} );

			// Save.
			$brandingSave.on( 'click', function () {
				$brandingSave.prop( 'disabled', true );
				$brandingStatus.text( cust.saving );

				$.post( data.ajaxUrl, {
					action:       data.actionBranding,
					nonce:        data.nonceBranding,
					site_name:    $.trim( $( '#aamo-branding-site-name' ).val() ),
					enabled:      $brandingEnabled.is( ':checked' ) ? '1' : '0',
					icon_url:     $brandingIconUrl.val(),
					icon_alt:     $.trim( $( '#aamo-branding-alt' ).val() ),
					link_mode:    $( '[name="aamo_link_mode"]:checked' ).val() || 'wordpress',
					link_url:     $.trim( $( '#aamo-branding-link-url' ).val() ),
					link_target:  $( '#aamo-branding-link-target' ).is( ':checked' ) ? '1' : '0',
					hide_submenu: $( '#aamo-branding-hide-submenu' ).is( ':checked' ) ? '1' : '0',
				} )
				.done( function ( resp ) {
					var msg = ( resp && resp.success )
						? cust.saved
						: ( resp && resp.data && resp.data.message ? resp.data.message : cust.error );
					$brandingStatus.text( msg );
				} )
				.fail( function () { $brandingStatus.text( cust.error ); } )
				.always( function () { $brandingSave.prop( 'disabled', false ); } );
			} );

		} // end admin bar customizer

		// ── Admin Footer Customizer ────────────────────────────────────────────

		var $footerWrap = $( '#aamo-footer-wrap' );

		if ( $footerWrap.length && ! $footerWrap.hasClass( 'aamo-panel-locked' ) ) {

			var $footerEnabled      = $( '#aamo-footer-enabled' );
			var $footerFields       = $( '#aamo-footer-fields' );
			var $footerShowVersion  = $( '#aamo-footer-show-version' );
			var $footerRightTextRow = $( '#aamo-footer-right-text-row' );
			var $footerSave         = $( '#aamo-footer-save' );
			var $footerStatus       = $( '#aamo-footer-status' );

			// Enable toggle.
			$footerEnabled.on( 'change', function () {
				$footerFields.toggle( this.checked );
			} );

			// Show-version toggle — hide/show custom right text field.
			$footerShowVersion.on( 'change', function () {
				$footerRightTextRow.toggle( ! this.checked );
			} );

			// Save.
			$footerSave.on( 'click', function () {
				$footerSave.prop( 'disabled', true );
				$footerStatus.text( cust.saving );

				// Footer editor uses quicktags only (no TinyMCE) so read the
				// textarea value directly — no tinyMCE.get() needed.
				var leftContent = $( '#aamo_footer_content' ).val();

				$.post( data.ajaxUrl, {
					action:       data.actionFooter,
					nonce:        data.nonceFooter,
					enabled:      $footerEnabled.is( ':checked' ) ? '1' : '0',
					left_content: leftContent,
					show_version: $footerShowVersion.is( ':checked' ) ? '1' : '0',
					right_text:   $.trim( $( '#aamo-footer-right-text' ).val() ),
				} )
				.done( function ( resp ) {
					var msg = ( resp && resp.success )
						? cust.saved
						: ( resp && resp.data && resp.data.message ? resp.data.message : cust.error );
					$footerStatus.text( msg );
				} )
				.fail( function () { $footerStatus.text( cust.error ); } )
				.always( function () { $footerSave.prop( 'disabled', false ); } );
			} );

		} // end footer customizer

		// ── Color Customizer ───────────────────────────────────────────────────

		var $colorWrap = $( '#aamo-color-wrap' );

		if ( $colorWrap.length && ! $colorWrap.hasClass( 'aamo-panel-locked' ) ) {

			var $colorEnabled = $( '#aamo-color-enabled' );
			var $colorFields  = $( '#aamo-color-fields' );
			var $colorSave    = $( '#aamo-color-save' );
			var $colorReset   = $( '#aamo-color-reset' );
			var $colorStatus  = $( '#aamo-color-status' );

			// Initialize all color pickers (only if wp-color-picker is loaded).
			if ( $.fn.wpColorPicker ) {
				$( '.aamo-color-input' ).wpColorPicker();
			}

			// Enable toggle.
			$colorEnabled.on( 'change', function () {
				$colorFields.toggle( this.checked );
			} );

			// Collect all color slot values into a plain object.
			function collectColors() {
				var vals = { enabled: $colorEnabled.is( ':checked' ) ? '1' : '0' };
				$( '.aamo-color-input' ).each( function () {
					vals[ $( this ).data( 'slot' ) ] = $( this ).val();
				} );
				return vals;
			}

			// Save.
			$colorSave.on( 'click', function () {
				$colorSave.prop( 'disabled', true );
				$colorStatus.text( cust.saving );

				$.post( data.ajaxUrl, $.extend( {
					action: data.actionColorSave,
					nonce:  data.nonceColorSave,
				}, collectColors() ) )
				.done( function ( resp ) {
					var msg = ( resp && resp.success )
						? cust.colorSaved
						: ( resp && resp.data && resp.data.message ? resp.data.message : cust.error );
					$colorStatus.text( msg );
					if ( resp && resp.success ) {
						setTimeout( function () { window.location.reload(); }, 800 );
					}
				} )
				.fail( function () {
					$colorStatus.text( cust.error );
					$colorSave.prop( 'disabled', false );
				} );
			} );

			// Reset to defaults — saves defaults server-side, then updates pickers client-side.
			$colorReset.on( 'click', function () {
				$colorReset.prop( 'disabled', true );
				$colorStatus.text( cust.saving );

				$.post( data.ajaxUrl, {
					action: data.actionColorReset,
					nonce:  data.nonceColorReset,
				} )
				.done( function ( resp ) {
					if ( resp && resp.success && resp.data && resp.data.colors ) {
						var colors = resp.data.colors;
						$( '.aamo-color-input' ).each( function () {
							var slot = $( this ).data( 'slot' );
							if ( colors[ slot ] ) {
								$( this ).val( colors[ slot ] ).trigger( 'change' );
								if ( $.fn.wpColorPicker ) {
									$( this ).wpColorPicker( 'color', colors[ slot ] );
								}
							}
						} );
					}
					var msg = ( resp && resp.success )
						? cust.colorReset
						: ( resp && resp.data && resp.data.message ? resp.data.message : cust.error );
					$colorStatus.text( msg );
				} )
				.fail( function () { $colorStatus.text( cust.error ); } )
				.always( function () { $colorReset.prop( 'disabled', false ); } );
			} );

		} // end color customizer

		// ── Reset to Defaults ────────────────────────────────────────────────
		var $resetBtn    = $( '#aamo-reset-customization' );
		var $resetStatus = $( '#aamo-reset-customization-status' );
		var $resetMenu   = $( '#aamo-reset-menu-checkbox' );
		var $resetLabels = $( '#aamo-reset-labels-checkbox' );
		var $nukeMenus   = $( '#aamo-nuke-menus-checkbox' );

		if ( $resetBtn.length && data.nonceResetCustomization ) {
			var ri = data.resetI18n || {};

			// When nuke is checked, disable and uncheck the subordinate options.
			$nukeMenus.on( 'change', function () {
				var nuked = $nukeMenus.is( ':checked' );
				$resetMenu.prop( 'disabled', nuked ).prop( 'checked', nuked ? false : $resetMenu.prop( 'checked' ) );
				$resetLabels.prop( 'disabled', nuked ).prop( 'checked', nuked ? false : $resetLabels.prop( 'checked' ) );
			} );

			$resetBtn.on( 'click', function () {
				var withNuke   = $nukeMenus.is( ':checked' );
				var withMenu   = ! withNuke && $resetMenu.is( ':checked' );
				var withLabels = ! withNuke && $resetLabels.is( ':checked' );

				var msg;
				if ( withNuke ) {
					msg = ri.confirmNuke || 'This will delete all custom menu configurations and role assignments. Continue?';
				} else if ( withMenu || withLabels ) {
					msg = ri.confirmWithMenu || 'This will reset all admin customization settings and affect saved menu data. Continue?';
				} else {
					msg = ri.confirm || 'This will reset all admin customization settings to defaults. Continue?';
				}

				if ( ! window.confirm( msg ) ) {
					return;
				}

				$resetBtn.prop( 'disabled', true );
				$resetStatus.text( ri.resetting || '' );

				$.post( data.ajaxUrl, {
					action:       data.actionResetCustomization,
					nonce:        data.nonceResetCustomization,
					reset_menu:   withMenu   ? '1' : '0',
					reset_labels: withLabels ? '1' : '0',
					nuke_menus:   withNuke   ? '1' : '0',
				} )
				.done( function ( response ) {
					if ( response && response.success ) {
						$resetStatus.text( ri.success || 'Reset complete.' );
					} else {
						var errMsg = ( response && response.data && response.data.message )
							? response.data.message
							: ( ri.error || 'An error occurred.' );
						$resetStatus.text( errMsg );
					}
				} )
				.fail( function () { $resetStatus.text( ri.error || 'An error occurred.' ); } )
				.always( function () { $resetBtn.prop( 'disabled', false ); } );
			} );
		}

	} );

} )( jQuery, window.aamoSettingsData || {} );

/* global jQuery */
( function ( $ ) {
	'use strict';

	var TABS = {
		'#tab-colors': { tab: '#aamo-tab-colors', panel: '#aamo-panel-colors' },
		'#tab-layout': { tab: '#aamo-tab-layout', panel: '#aamo-panel-layout' },
	};
	var DEFAULT_HASH = '#tab-colors';

	function activateTab( hash ) {
		var target = TABS[ hash ] || TABS[ DEFAULT_HASH ];
		$.each( TABS, function ( h, pair ) {
			$( pair.tab ).toggleClass( 'nav-tab-active', pair === target );
			$( pair.panel ).toggleClass( 'is-active', pair === target );
		} );
	}

	$( function () {
		activateTab( window.location.hash );
		$( '.nav-tab-wrapper' ).on( 'click', '.nav-tab', function ( e ) {
			e.preventDefault();
			var hash = $( this ).attr( 'href' );
			window.location.hash = hash;
			activateTab( hash );
		} );
	} );
} )( jQuery );
