(function($) {
	'use strict';

	const WPPS_REFRESH_ICON = '<svg class="wp-powersuite-refresh-icon" width="16" height="16" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false"><path d="M17.65 6.35A7.958 7.958 0 0 0 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18c-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/></svg>';

	const MenuOrganizer = {
		currentMenu: [],
		editingItem: null,
		usersMap: {},

		md5Hex: function(str) {
			function md5cycle(x, k) {
				let a = x[0], b = x[1], c = x[2], d = x[3];
				a = ff(a, b, c, d, k[0], 7, -680876936);
				d = ff(d, a, b, c, k[1], 12, -389564586);
				c = ff(c, d, a, b, k[2], 17, 606105819);
				b = ff(b, c, d, a, k[3], 22, -1044525330);
				a = ff(a, b, c, d, k[4], 7, -176418897);
				d = ff(d, a, b, c, k[5], 12, 1200080426);
				c = ff(c, d, a, b, k[6], 17, -1473231341);
				b = ff(b, c, d, a, k[7], 22, -45705983);
				a = ff(a, b, c, d, k[8], 7, 1770035416);
				d = ff(d, a, b, c, k[9], 12, -1958414417);
				c = ff(c, d, a, b, k[10], 17, -42063);
				b = ff(b, c, d, a, k[11], 22, -1990404162);
				a = ff(a, b, c, d, k[12], 7, 1804603682);
				d = ff(d, a, b, c, k[13], 12, -40341101);
				c = ff(c, d, a, b, k[14], 17, -1502002290);
				b = ff(b, c, d, a, k[15], 22, 1236535329);
				a = gg(a, b, c, d, k[1], 5, -165796510);
				d = gg(d, a, b, c, k[6], 9, -1069501632);
				c = gg(c, d, a, b, k[11], 14, 643717713);
				b = gg(b, c, d, a, k[0], 20, -373897302);
				a = gg(a, b, c, d, k[5], 5, -701558691);
				d = gg(d, a, b, c, k[10], 9, 38016083);
				c = gg(c, d, a, b, k[15], 14, -660478335);
				b = gg(b, c, d, a, k[4], 20, -405537848);
				a = gg(a, b, c, d, k[9], 5, 568446438);
				d = gg(d, a, b, c, k[14], 9, -1019803690);
				c = gg(c, d, a, b, k[3], 14, -187363961);
				b = gg(b, c, d, a, k[8], 20, 1163531501);
				a = gg(a, b, c, d, k[13], 5, -1444681467);
				d = gg(d, a, b, c, k[2], 9, -51403784);
				c = gg(c, d, a, b, k[7], 14, 1735328473);
				b = gg(b, c, d, a, k[12], 20, -1926607734);
				a = hh(a, b, c, d, k[5], 4, -378558);
				d = hh(d, a, b, c, k[8], 11, -2022574463);
				c = hh(c, d, a, b, k[11], 16, 1839030562);
				b = hh(b, c, d, a, k[14], 23, -35309556);
				a = hh(a, b, c, d, k[1], 4, -1530992060);
				d = hh(d, a, b, c, k[4], 11, 1272893353);
				c = hh(c, d, a, b, k[7], 16, -155497632);
				b = hh(b, c, d, a, k[10], 23, -1094730640);
				a = hh(a, b, c, d, k[13], 4, 681279174);
				d = hh(d, a, b, c, k[0], 11, -358537222);
				c = hh(c, d, a, b, k[3], 16, -722521979);
				b = hh(b, c, d, a, k[6], 23, 76029189);
				a = hh(a, b, c, d, k[9], 4, -640364487);
				d = hh(d, a, b, c, k[12], 11, -421815835);
				c = hh(c, d, a, b, k[15], 16, 530742520);
				b = hh(b, c, d, a, k[2], 23, -995338651);
				a = ii(a, b, c, d, k[0], 6, -198630844);
				d = ii(d, a, b, c, k[7], 10, 1126891415);
				c = ii(c, d, a, b, k[14], 15, -1416354905);
				b = ii(b, c, d, a, k[5], 21, -57434055);
				a = ii(a, b, c, d, k[12], 6, 1700485571);
				d = ii(d, a, b, c, k[3], 10, -1894986606);
				c = ii(c, d, a, b, k[10], 15, -1051523);
				b = ii(b, c, d, a, k[1], 21, -2054922799);
				a = ii(a, b, c, d, k[8], 6, 1873313359);
				d = ii(d, a, b, c, k[15], 10, -30611744);
				c = ii(c, d, a, b, k[6], 15, -1560198380);
				b = ii(b, c, d, a, k[13], 21, 1309151649);
				a = ii(a, b, c, d, k[4], 6, -145523070);
				d = ii(d, a, b, c, k[11], 10, -1120210379);
				c = ii(c, d, a, b, k[2], 15, 718787259);
				b = ii(b, c, d, a, k[9], 21, -343485551);
				x[0] = add32(a, x[0]);
				x[1] = add32(b, x[1]);
				x[2] = add32(c, x[2]);
				x[3] = add32(d, x[3]);
			}
			function cmn(q, a, b, x, s, t) {
				a = add32(add32(a, q), add32(x, t));
				return add32((a << s) | (a >>> (32 - s)), b);
			}
			function ff(a, b, c, d, x, s, t) { return cmn((b & c) | ((~b) & d), a, b, x, s, t); }
			function gg(a, b, c, d, x, s, t) { return cmn((b & d) | (c & (~d)), a, b, x, s, t); }
			function hh(a, b, c, d, x, s, t) { return cmn(b ^ c ^ d, a, b, x, s, t); }
			function ii(a, b, c, d, x, s, t) { return cmn(c ^ (b | (~d)), a, b, x, s, t); }
			function md51(s) {
				const n = s.length;
				const state = [1732584193, -271733879, -1732584194, 271733878];
				let i;
				for (i = 64; i <= n; i += 64) {
					md5cycle(state, md5blk(s.substring(i - 64, i)));
				}
				s = s.substring(i - 64);
				const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
				for (i = 0; i < s.length; i++) {
					tail[i >> 2] |= s.charCodeAt(i) << ((i % 4) << 3);
				}
				tail[i >> 2] |= 0x80 << ((i % 4) << 3);
				if (i > 55) {
					md5cycle(state, tail);
					for (i = 0; i < 16; i++) {
						tail[i] = 0;
					}
				}
				tail[14] = n * 8;
				md5cycle(state, tail);
				return state;
			}
			function md5blk(s) {
				const md5blks = [];
				for (let i = 0; i < 64; i += 4) {
					md5blks[i >> 2] =
						s.charCodeAt(i) +
						(s.charCodeAt(i + 1) << 8) +
						(s.charCodeAt(i + 2) << 16) +
						(s.charCodeAt(i + 3) << 24);
				}
				return md5blks;
			}
			function rhex(n) {
				let s = '';
				for (let j = 0; j < 4; j++) {
					s += ((n >> (j * 8 + 4)) & 0x0f).toString(16) + ((n >> (j * 8)) & 0x0f).toString(16);
				}
				return s;
			}
			function hex(x) {
				return x.map(rhex).join('');
			}
			function add32(a, b) {
				return (a + b) & 0xffffffff;
			}
			return hex(md51(str));
		},

		sanitizeMenuSlug: function(slug) {
			slug = String(slug || '').trim();
			if (!slug) {
				return '';
			}
			if (/^https?:\/\//i.test(slug)) {
				return slug;
			}
			// Match PHP: keep / : # + etc. Only strip control chars and HTML breakers.
			slug = slug.replace(/[\r\n\t\0]/g, '');
			if (/[<>"']/.test(slug)) {
				return '';
			}
			return slug;
		},

		resolveCustomMenuSlug: function(menuSlug, url) {
			const target = (url && /^https?:\/\//i.test(url)) ? url : (menuSlug || '');
			if (/^https?:\/\//i.test(target)) {
				return 'wpps-link-' + this.md5Hex(target).substring(0, 12);
			}
			return this.sanitizeMenuSlug(menuSlug);
		},

		getItemSlug: function(item) {
			if (!item) {
				return '';
			}
			if (item.is_custom) {
				return this.resolveCustomMenuSlug(item.menu_slug || '', item.url || '');
			}
			return this.sanitizeMenuSlug(item.menu_slug || '');
		},

		normalizeMenuPositions: function() {
			const self = this;
			this.currentMenu.forEach(function(item, index) {
				item.position = index;
				if (item.submenu && item.submenu.length) {
					self.normalizeSubmenuPositions(item.submenu);
				}
			});
		},

		normalizeSubmenuPositions: function(submenuItems) {
			const self = this;
			submenuItems.forEach(function(sub, index) {
				sub.position = index;
				if (sub.submenu && sub.submenu.length) {
					self.normalizeSubmenuPositions(sub.submenu);
				}
			});
		},

		findParentIndexBySlug: function(parentSlug) {
			if (!parentSlug) {
				return -1;
			}
			const self = this;
			return this.currentMenu.findIndex(function(item) {
				if (item.parent_slug && !item.is_separator) {
					return false;
				}
				return self.getItemSlug(item) === parentSlug || (item.menu_slug || '') === parentSlug;
			});
		},

		getRelocatedItemsForParent: function(parentIndex) {
			const parent = this.currentMenu[parentIndex];
			if (!parent) {
				return [];
			}
			const parentSlug = this.getItemSlug(parent);
			const parentMenuSlug = parent.menu_slug || '';
			const self = this;
			const relocated = [];
			this.currentMenu.forEach(function(item, idx) {
				const ps = item.parent_slug || '';
				if (!ps || item.is_separator) {
					return;
				}
				if (ps === parentSlug || ps === parentMenuSlug) {
					relocated.push({ index: idx, item: item, slug: self.getItemSlug(item) });
				}
			});
			return relocated;
		},

		buildDefaultChildOrder: function(parentIndex) {
			const parent = this.currentMenu[parentIndex];
			if (!parent) {
				return [];
			}
			const self = this;
			const relocatedSlugs = {};
			const order = [];
			this.getRelocatedItemsForParent(parentIndex).forEach(function(entry) {
				relocatedSlugs[entry.slug] = true;
			});
			(parent.submenu || []).forEach(function(sub) {
				const slug = self.getItemSlug(sub);
				if (slug && !relocatedSlugs[slug]) {
					order.push(slug);
				}
			});
			this.getRelocatedItemsForParent(parentIndex).forEach(function(entry) {
				if (entry.slug && order.indexOf(entry.slug) === -1) {
					order.push(entry.slug);
				}
			});
			return order;
		},

		getChildOrderForParent: function(parentIndex) {
			const parent = this.currentMenu[parentIndex];
			if (!parent) {
				return [];
			}
			if (parent.submenu_child_order && parent.submenu_child_order.length) {
				return parent.submenu_child_order.slice();
			}
			return this.buildDefaultChildOrder(parentIndex);
		},

		setChildOrderForParent: function(parentIndex, order) {
			if (!this.currentMenu[parentIndex]) {
				return;
			}
			this.currentMenu[parentIndex].submenu_child_order = order.slice();
		},

		removeSlugFromAllChildOrders: function(slug) {
			if (!slug) {
				return;
			}
			this.currentMenu.forEach(function(item) {
				if (!item.submenu_child_order || !item.submenu_child_order.length) {
					return;
				}
				item.submenu_child_order = item.submenu_child_order.filter(function(s) {
					return s !== slug;
				});
			});
		},

		addSlugToParentChildOrder: function(parentSlug, childSlug) {
			if (!parentSlug || !childSlug) {
				return;
			}
			const parentIndex = this.findParentIndexBySlug(parentSlug);
			if (parentIndex === -1) {
				return;
			}
			const order = this.getChildOrderForParent(parentIndex);
			if (order.indexOf(childSlug) === -1) {
				order.push(childSlug);
			}
			this.setChildOrderForParent(parentIndex, order);
		},

		submenuExpandKey: function(parentIndex, subPath) {
			const path = (subPath === undefined || subPath === null || subPath === '') ? '_root' : String(subPath);
			return parentIndex + ':' + path;
		},

		renderMovedSubitemHtml: function(parentIndex, movedIdx, expandedMoved, expandedMoveUnder) {
			const self = this;
			const movedItem = this.currentMenu[movedIdx];
			if (!movedItem) {
				return '';
			}
			const movedTitle = this.stripHtml(movedItem.title || '');
			const movedHidden = movedItem.hidden || false;
			const movedHasSubs = movedItem.submenu && movedItem.submenu.length > 0;
			const movedExpanded = expandedMoved[movedIdx] === true;
			const expandedMoveMoved = expandedMoveUnder[movedIdx] === true;
			let html = '';
			// Flex row for the item itself; dropdown / nested list are full-width siblings below.
			html += '<div class="wpps-menu-subitem wpps-menu-subitem-moved' + (movedHidden ? ' wpps-menu-item-hidden' : '') + '" data-parent-index="' + parentIndex + '" data-moved-index="' + movedIdx + '">';
			html += '<div class="wpps-menu-subitem-main">';
			html += '<div class="wpps-menu-subitem-content">';
			html += '<span class="dashicons dashicons-move wpps-submenu-moved-icon" title="Moved under parent"></span>';
			html += '<input type="text" class="wpps-subitem-title wpps-moved-item-title" data-moved-index="' + movedIdx + '" value="' + self.escapeAttr(movedTitle) + '" />';
			html += '</div>';
			html += '<a href="#" class="wpps-edit-moved-item wpps-action-link wpps-action-link-edit" data-moved-index="' + movedIdx + '">Edit</a>';
			html += '<label class="wpps-checkbox-label wpps-checkbox-label-auto">';
			html += '<input type="checkbox" class="wpps-toggle-hidden wpps-checkbox-input" data-index="' + movedIdx + '"' + (movedHidden ? ' checked' : '') + ' />';
			html += '<span class="wpps-label-text">Hide</span></label>';
			html += '<a href="#" class="wpps-toggle-move-under wpps-action-link wpps-action-link-edit" data-index="' + movedIdx + '">';
			html += (movedItem.parent_slug ? 'Move (under ' + self.escapeHtml(self.getParentTitle(movedItem.parent_slug) || movedItem.parent_slug) + ')' : 'Move under');
			html += '</a>';
			if (movedHasSubs) {
				html += '<a href="#" class="wpps-toggle-moved-submenu wpps-action-link" data-moved-index="' + movedIdx + '">' + (movedExpanded ? 'Hide Submenu' : 'Show Submenu') + '</a>';
			}
			html += '</div>'; // .wpps-menu-subitem-main

			html += '<div class="wpps-move-under-dropdown wpps-move-under-dropdown--moved" data-index="' + movedIdx + '" style="display: ' + (expandedMoveMoved ? 'block' : 'none') + ';">';
			html += '<label class="wpps-move-under-label">' + self.escapeHtml('Move under:') + '</label>';
			html += '<select class="wpps-move-under-select" data-index="' + movedIdx + '">';
			html += '<option value="">' + self.escapeHtml('— Top level —') + '</option>';
			this.currentMenu.forEach(function(m, i) {
				if (i === movedIdx || m.is_separator || !(m.menu_slug || '') || (m.parent_slug && m.parent_slug !== '')) return;
				const slug = self.getItemSlug(m) || m.menu_slug || '';
				const title = self.stripHtml(m.title || slug);
				const sel = (movedItem.parent_slug || '') === slug || (movedItem.parent_slug || '') === (m.menu_slug || '') ? ' selected' : '';
				html += '<option value="' + self.escapeAttr(slug) + '"' + sel + '>' + self.escapeHtml(title) + '</option>';
			});
			html += '</select>';
			html += '</div>';

			if (movedHasSubs) {
				html += '<div class="wpps-menu-subsubitems" data-moved-index="' + movedIdx + '" data-parent-index="' + parentIndex + '" style="display: ' + (movedExpanded ? 'block' : 'none') + ';">';
				movedItem.submenu.forEach(function(msub, msubIdx) {
					const msubTitle = self.stripHtml(msub.title || '');
					html += '<div class="wpps-menu-subsubitem" data-moved-index="' + movedIdx + '" data-sub-index="' + msubIdx + '">';
					html += '<span class="dashicons dashicons-move wpps-submenu-drag-hint" title="Drag to reorder"></span>';
					html += '<input type="text" class="wpps-subsubitem-title" data-moved-index="' + movedIdx + '" data-sub-index="' + msubIdx + '" value="' + self.escapeAttr(msubTitle) + '" />';
					html += '</div>';
				});
				html += '</div>';
			}
			html += '</div>'; // .wpps-menu-subitem-moved
			return html;
		},

		init: function() {
			const self = this;
			
			if (typeof wppsMenuOrganizerInitialMenu !== 'undefined' && wppsMenuOrganizerInitialMenu && wppsMenuOrganizerInitialMenu.length > 0) {
				this.currentMenu = wppsMenuOrganizerInitialMenu;
				if (typeof wppsMenuOrganizerUsersMap !== 'undefined' && wppsMenuOrganizerUsersMap && typeof wppsMenuOrganizerUsersMap === 'object') {
					this.usersMap = wppsMenuOrganizerUsersMap;
				}
				this.renderMenu();
			} else {
				this.loadMenu();
			}

			try {
				if (window.sessionStorage.getItem('wppsMenuOrganizerSaved') === '1') {
					window.sessionStorage.removeItem('wppsMenuOrganizerSaved');
					this.showNotice('success', wppsMenuOrganizer.strings.saved || 'Menu configuration saved successfully!');
				}
			} catch (e) {}

			this.bindEvents();
		},

		bindEvents: function() {
			const self = this;

			$(document).on('click', '.wpps-save-menu', function() {
				self.saveMenu();
			});

			$(document).on('click', '.wpps-restore-menu', function() {
				if (confirm(wppsMenuOrganizer.strings.confirmRestore || 'Are you sure you want to restore the default menu? This will remove all customizations.')) {
					self.restoreMenu();
				}
			});

			$(document).on('click', '.wpps-refresh-menu', function(e) {
				e.preventDefault();
				const $btn = $(this);
				$btn.prop('disabled', true).html(WPPS_REFRESH_ICON + ' ' + (wppsMenuOrganizer.strings.refreshing || 'Refreshing...'));
				window.location.href = window.location.href;
			});

			$(document).on('click', '.wpps-modal-close, .wpps-modal-cancel', function() {
				self.closeEditModal();
			});

			$(document).on('click', '.wpps-modal-save', function() {
				self.saveMenuItem();
			});
		$(document).on('click', '.wpps-modal', function(e) {
			if ($(e.target).hasClass('wpps-modal')) {
				self.closeEditModal();
				self.closeAddModal();
			}
		});

		$(document).on('click', '.wpps-add-menu-item', function() {
			self.openAddModal('menu');
		});

		$(document).on('click', '.wpps-add-submenu-item', function(e) {
			e.preventDefault();
			const parentIndex = parseInt($(this).data('parent-index'), 10);
			const subPath = $(this).attr('data-sub-path');
			if (!isNaN(parentIndex)) {
				self.openAddModal('submenu', parentIndex, subPath !== undefined ? String(subPath) : '');
			}
		});

		$(document).on('click', '.wpps-add-separator', function() {
			self.addSeparator();
		});

		$(document).on('click', '.wpps-add-menu-save', function() {
			self.saveNewMenuItem();
		});
		$(document).on('change', 'input[name="wpps-add-menu-roles"]', function() {
			const roleType = $(this).val();
			if (roleType === 'specific') {
				$('#wpps-add-menu-roles-list').slideDown(200);
			} else {
				$('#wpps-add-menu-roles-list').slideUp(200);
				$('#wpps-add-menu-roles-list input[type="checkbox"]').prop('checked', false);
			}
		});

		$(document).on('click', '.wpps-edit-custom-item', function(e) {
			e.preventDefault();
			e.stopPropagation();
			const index = parseInt($(this).data('index'), 10);
			self.openEditCustomModal(index);
		});

		$(document).on('click', '.wpps-delete-custom-item', function(e) {
			e.preventDefault();
			e.stopPropagation();
			const index = parseInt($(this).data('index'), 10);
			if (confirm(wppsMenuOrganizer.strings.confirmDelete || 'Are you sure you want to delete this menu item?')) {
				self.deleteCustomItem(index);
			}
		});

		$(document).on('click', '.wpps-edit-custom-subitem', function(e) {
			e.preventDefault();
			e.stopPropagation();
			const parentIndex = parseInt($(this).data('parent-index'), 10);
			const subPath = self.resolveSubPathFromEl($(this));
			self.openEditCustomSubModal(parentIndex, subPath);
		});

		$(document).on('click', '.wpps-delete-custom-subitem', function(e) {
			e.preventDefault();
			e.stopPropagation();
			const parentIndex = parseInt($(this).data('parent-index'), 10);
			const subPath = self.resolveSubPathFromEl($(this));
			if (confirm(wppsMenuOrganizer.strings.confirmDeleteSub || 'Are you sure you want to delete this submenu item?')) {
				self.deleteCustomSubItem(parentIndex, subPath);
			}
		});
		$(document).on('click', '#wpps-add-menu-item-modal .wpps-modal-close, #wpps-add-menu-item-modal .wpps-modal-cancel', function() {
			self.closeAddModal();
		});
		},

		loadMenu: function() {
			const self = this;
			
			$.ajax({
				url: wppsMenuOrganizer.ajaxUrl,
				type: 'POST',
				data: {
					action: 'wpps_get_menu_config',
					nonce: wppsMenuOrganizer.nonce,
				},
				success: function(response) {
					if (response.success && response.data.menu_config && response.data.menu_config.length) {
						self.currentMenu = response.data.menu_config;
						if (response.data.users_map && typeof response.data.users_map === 'object') {
							self.usersMap = response.data.users_map;
						}
						self.renderMenu();
					} else if (response.success) {
						// Server cannot rebuild the list over admin-ajax — full page load required.
						window.location.reload();
					} else {
						$('.wpps-menu-items-list').empty().append(
							$('<div class="wpps-loading-message"></div>').text(response.data?.message || 'Error loading menu items.')
						);
					}
				},
				error: function() {
					$('.wpps-menu-items-list').empty().append(
						$('<div class="wpps-loading-message"></div>').text('Error loading menu items. Please refresh the page.')
					);
				}
			});
		},

		/**
		 * Large SVG data-URIs are omitted from editor JSON (payload safety).
		 * Copy the real icon visuals from the live #adminmenu after render.
		 */
		syncEditorIconsFromSidebar: function() {
			const $adminMenu = $('#adminmenu');
			const $placeholders = $('.wpps-menu-item-icon .wpps-svg-icon-placeholder');
			if (!$adminMenu.length || !$placeholders.length) {
				return;
			}

			const bySlug = {};
			const byTitle = {};

			const remember = function(key, $img) {
				if (!key || !key.length || !$img || !$img.length || bySlug[key]) {
					return;
				}
				bySlug[key] = $img;
			};

			$adminMenu.children('li').each(function() {
				const $li = $(this);
				if ($li.hasClass('wp-menu-separator') || $li.hasClass('wpps-show-all-toggle')) {
					return;
				}
				const $a = $li.children('a').first();
				const $img = $a.children('.wp-menu-image').first();
				if (!$img.length) {
					return;
				}

				const href = $a.attr('href') || '';
				const rawHref = href.split('#')[0];

				if (rawHref) {
					remember(rawHref, $img);
					try {
						const url = new URL(rawHref, window.location.origin);
						const page = url.searchParams.get('page');
						if (page) {
							remember(page, $img);
							remember('admin.php?page=' + page, $img);
						}
						const file = (url.pathname.split('/').pop() || '') + url.search;
						if (file) {
							remember(file, $img);
							remember(file.replace(/^\//, ''), $img);
						}
					} catch (e) {}

					const adminIdx = rawHref.indexOf('wp-admin/');
					if (adminIdx !== -1) {
						remember(rawHref.substring(adminIdx + 9), $img);
					} else if (!/^https?:\/\//i.test(rawHref)) {
						remember(rawHref.replace(/^\.\//, '').replace(/^\//, ''), $img);
					}
				}

				const title = $.trim(
					$a.find('.wp-menu-name').clone().children().remove().end().text()
				).toLowerCase();
				if (title && !byTitle[title]) {
					byTitle[title] = $img;
				}
			});

			$placeholders.each(function() {
				const $placeholder = $(this);
				const $iconWrap = $placeholder.closest('.wpps-menu-item-icon');
				const $row = $placeholder.closest('.wpps-menu-item');
				const slug = $row.attr('data-menu-slug') || '';
				const title = $.trim(($row.find('.wpps-menu-item-title').val() || '')).toLowerCase();

				let $src = null;
				if (slug) {
					$src = bySlug[slug]
						|| bySlug[slug.replace(/^admin\.php\?page=/i, '')]
						|| bySlug['admin.php?page=' + slug];
				}
				if ((!$src || !$src.length) && title) {
					$src = byTitle[title];
				}
				if (!$src || !$src.length) {
					return;
				}

				const bg = ($src.attr('style') || '').match(/background-image\s*:\s*url\((['"]?)(.*?)\1\)/i);
				const $srcImg = $src.children('img').first();
				let replacement = null;

				if (bg && bg[2]) {
					replacement = $('<span class="wpps-icon-from-sidebar" aria-hidden="true"></span>').css({
						backgroundImage: 'url(' + bg[2] + ')'
					});
				} else if ($srcImg.length && $srcImg.attr('src')) {
					replacement = $('<img class="wpps-icon-img wpps-icon-from-sidebar" alt="" />').attr('src', $srcImg.attr('src'));
				} else {
					const classes = ($src.attr('class') || '').split(/\s+/).filter(function(c) {
						return c.indexOf('dashicons-') === 0;
					});
					if (classes.length) {
						replacement = $('<span></span>').addClass('dashicons ' + classes.join(' '));
					}
				}

				if (!replacement) {
					return;
				}

				$placeholder.replaceWith(replacement);
				$iconWrap.attr('title', $iconWrap.hasClass('wpps-icon-clickable') ? 'Click to edit icon' : '');
			});
		},

		renderMenu: function() {
			const self = this;
			const $container = $('.wpps-menu-items-list');
			
			if (!this.currentMenu || this.currentMenu.length === 0) {
				$container.html('<div class="wpps-loading-message">No menu items found.</div>');
				return;
			}

			const expandedSubmenus = {};
			$('.wpps-menu-subitems').each(function() {
				const parentIndex = $(this).data('parent-index');
				const subPath = $(this).attr('data-sub-path');
				const key = self.submenuExpandKey(parentIndex, subPath);
				if ($(this).is(':visible')) {
					expandedSubmenus[key] = true;
				}
			});
			if (this._forceExpandParentIndex !== undefined && this._forceExpandParentIndex !== null) {
				expandedSubmenus[this.submenuExpandKey(this._forceExpandParentIndex, '')] = true;
				this._forceExpandParentIndex = null;
			}
			const expandedMoved = {};
			$('.wpps-menu-subsubitems').each(function() {
				const movedIndex = $(this).data('moved-index');
				if ($(this).is(':visible')) {
					expandedMoved[movedIndex] = true;
				}
			});
			const expandedMoveUnder = {};
			$('.wpps-move-under-dropdown').each(function() {
				const idx = $(this).data('index');
				if ($(this).is(':visible')) {
					expandedMoveUnder[idx] = true;
				}
			});
			// After changing parent, close the move-under dropdown (avoid stale open state).
			if (this._closeMoveUnderIndex !== undefined && this._closeMoveUnderIndex !== null) {
				delete expandedMoveUnder[this._closeMoveUnderIndex];
				this._closeMoveUnderIndex = null;
			}

			const parentSlugToIndex = {};
			self.currentMenu.forEach(function(it, idx) {
				const slug = self.getItemSlug(it);
				if (slug) {
					parentSlugToIndex[slug] = idx;
				}
				if (it.menu_slug && !parentSlugToIndex[it.menu_slug]) {
					parentSlugToIndex[it.menu_slug] = idx;
				}
			});
			const movedByParentIndex = {};
			self.currentMenu.forEach(function(it, idx) {
				const ps = it.parent_slug || '';
				if (ps && !it.is_separator) {
					const parentIdx = parentSlugToIndex[ps];
					if (parentIdx !== undefined) {
						if (!movedByParentIndex[parentIdx]) movedByParentIndex[parentIdx] = [];
						movedByParentIndex[parentIdx].push(idx);
					}
				}
			});

			let html = '';
			
			self.currentMenu.forEach(function(item, index) {
				if (item.parent_slug && !item.is_separator) {
					return;
				}
				const itemTitle = self.stripHtml(item.title || '');
				const itemIcon = item.icon || 'dashicons-admin-generic';
				const isHidden = item.hidden || false;
				const isSeparator = item.is_separator || false;
				const isCustom = item.is_custom || false;
				
				html += '<div class="wpps-menu-row" data-menu-key="' + index + '" data-menu-slug="' + self.escapeAttr(self.getItemSlug(item) || item.menu_slug || '') + '">';
				html += '<div class="wpps-menu-item' + (isHidden ? ' wpps-menu-item-hidden' : '') + (isSeparator ? ' wpps-menu-item-separator' : '') + '" data-menu-key="' + index + '" data-menu-slug="' + self.escapeAttr(self.getItemSlug(item) || item.menu_slug || '') + '">';
				
				html += '<span class="dashicons dashicons-menu wpps-menu-drag-handle"></span>';
				
				const isIconClickable = !isSeparator && !isCustom;
				html += '<div class="wpps-menu-item-icon wpps-edit-menu-item-icon' + (isIconClickable ? ' wpps-icon-clickable' : '') + '" data-index="' + index + '" title="' + (isIconClickable ? 'Click to edit icon' : '') + '">';
				if (isSeparator) {
					html += '<span class="dashicons dashicons-minus"></span>';
				} else if (item.icon_is_svg) {
					html += '<span class="dashicons dashicons-format-image wpps-svg-icon-placeholder" title="SVG icon"></span>';
				} else if (itemIcon && itemIcon.startsWith('dashicons-')) {
					html += '<span class="dashicons ' + self.escapeAttr(itemIcon) + '"></span>';
				} else if (itemIcon && (itemIcon.startsWith('http') || itemIcon.startsWith('data'))) {
					html += '<img src="' + self.escapeAttr(itemIcon) + '" class="wpps-icon-img" />';
				} else {
					html += '<span class="dashicons dashicons-admin-generic"></span>';
				}
				if (isIconClickable) {
					html += '<span class="dashicons dashicons-edit wpps-icon-edit-overlay"></span>';
				}
				html += '</div>';
				
				html += '<div class="wpps-menu-item-content">';
				html += '<input type="text" id="wpps-menu-item-title-' + index + '" name="wpps-menu-item-title-' + index + '" class="wpps-menu-item-title" data-index="' + index + '" data-type="menu" value="' + self.escapeAttr(itemTitle) + '" />';
				html += '<div class="wpps-menu-item-actions">';
				
				const hideRules = item.hide_rules || { type: 'all', roles: [], users: [], mode: 'toggle' };
				const hideMode = hideRules.mode || 'remove';
				
				if (isCustom && !isSeparator) {
					html += '<a href="#" class="wpps-edit-custom-item wpps-action-link wpps-action-link-edit" data-index="' + index + '">';
					html += 'Edit';
					html += '</a>';
					html += '<a href="#" class="wpps-delete-custom-item wpps-action-link wpps-action-link-delete" data-index="' + index + '">';
					html += 'Delete';
					html += '</a>';
				} else if (isSeparator) {
					if (isHidden) {
						html += '<a href="#" class="wpps-toggle-hide-rules wpps-action-link wpps-action-link-edit" data-index="' + index + '">';
						html += 'Show Hide Rules';
						html += '</a>';
					}
					
					html += '<label class="wpps-checkbox-label">';
					html += '<input type="checkbox" id="wpps-toggle-hidden-' + index + '" name="wpps-toggle-hidden-' + index + '" class="wpps-toggle-hidden wpps-checkbox-input" data-index="' + index + '"' + (isHidden ? ' checked' : '') + ' />';
					html += '<span class="wpps-label-text">Hide</span>';
					html += '</label>';
					
					html += '<a href="#" class="wpps-delete-custom-item wpps-action-link wpps-action-link-delete" data-index="' + index + '">';
					html += 'Delete';
					html += '</a>';
				} else {
					if (isHidden) {
						html += '<a href="#" class="wpps-toggle-hide-rules wpps-action-link wpps-action-link-edit" data-index="' + index + '">';
						html += 'Show Hide Rules';
						html += '</a>';
					}
					
					html += '<label class="wpps-checkbox-label">';
					html += '<input type="checkbox" id="wpps-toggle-hidden-' + index + '" name="wpps-toggle-hidden-' + index + '" class="wpps-toggle-hidden wpps-checkbox-input" data-index="' + index + '"' + (isHidden ? ' checked' : '') + ' />';
					html += '<span class="wpps-label-text">Hide</span>';
					html += '</label>';
				}
				
				if (!isSeparator) {
					const rootSubKeyForLabel = self.submenuExpandKey(index, '');
					const isSubmenuExpanded = expandedSubmenus[rootSubKeyForLabel] === true || expandedSubmenus[index] === true;
					const hasNativeSubs = item.submenu && item.submenu.length > 0;
					const hasMovedSubs = movedByParentIndex[index] && movedByParentIndex[index].length > 0;
					if (hasNativeSubs || hasMovedSubs) {
						html += '<a href="#" class="wpps-toggle-submenu wpps-action-link wpps-action-link-edit" data-parent-index="' + index + '">';
						html += (isSubmenuExpanded ? 'Hide Submenu' : 'Show Submenu');
						html += '</a>';
					}
					html += '<a href="#" class="wpps-toggle-move-under wpps-action-link wpps-action-link-edit" data-index="' + index + '">';
					html += (item.parent_slug ? 'Move (under ' + self.escapeHtml(self.getParentTitle(item.parent_slug) || item.parent_slug) + ')' : 'Move under');
					html += '</a>';
				}
				
				html += '</div>';
				html += '</div>';
				html += '</div>';

				if (!isSeparator) {
					const expandedMove = expandedMoveUnder[index] === true;
					html += '<div class="wpps-move-under-dropdown" data-index="' + index + '" style="display: ' + (expandedMove ? 'block' : 'none') + ';">';
					html += '<label class="wpps-move-under-label">' + self.escapeHtml('Move under:') + '</label>';
					html += '<select class="wpps-move-under-select" data-index="' + index + '">';
					html += '<option value="">' + self.escapeHtml('— Top level —') + '</option>';
					self.currentMenu.forEach(function(m, i) {
						if (i === index || m.is_separator || !(m.menu_slug || '') || (m.parent_slug && m.parent_slug !== '')) return;
						const slug = self.getItemSlug(m) || m.menu_slug || '';
						const title = self.stripHtml(m.title || slug);
						const sel = (item.parent_slug || '') === slug || (item.parent_slug || '') === (m.menu_slug || '') ? ' selected' : '';
						html += '<option value="' + self.escapeAttr(slug) + '"' + sel + '>' + self.escapeHtml(title) + '</option>';
					});
					html += '</select>';
					html += '</div>';
				}

				if (isHidden) {
					html += '<div class="wpps-hide-rules-dropdown" data-index="' + index + '">';
					html += '<div class="wpps-hide-rules-options">';
					html += '<label class="wpps-hide-rules-label">';
					html += '<input type="radio" id="wpps-hide-rule-' + index + '-all" name="wpps-hide-rule-' + index + '" value="all" class="wpps-hide-rule-type wpps-hide-rules-input" data-index="' + index + '"' + (hideRules.type === 'all' ? ' checked' : '') + ' />';
					html += '<span>Hide for all</span>';
					html += '</label>';
					html += '<label class="wpps-hide-rules-label">';
					html += '<input type="radio" id="wpps-hide-rule-' + index + '-specific" name="wpps-hide-rule-' + index + '" value="specific" class="wpps-hide-rule-type wpps-hide-rules-input" data-index="' + index + '"' + (hideRules.type === 'specific' ? ' checked' : '') + ' />';
					html += '<span>Hide for Specific Role(s)</span>';
					html += '</label>';
					html += '<label class="wpps-hide-rules-label">';
					html += '<input type="radio" id="wpps-hide-rule-' + index + '-except" name="wpps-hide-rule-' + index + '" value="except" class="wpps-hide-rule-type wpps-hide-rules-input" data-index="' + index + '"' + (hideRules.type === 'except' ? ' checked' : '') + ' />';
					html += '<span>Hide for all except</span>';
					html += '</label>';
					html += '</div>';
					html += '<div class="wpps-hide-rules-mode" data-index="' + index + '">';
					html += '<p class="wpps-hide-rules-mode-label">' + self.escapeHtml('Visibility:') + '</p>';
					html += '<label class="wpps-hide-rules-label">';
					html += '<input type="radio" id="wpps-hide-mode-' + index + '-toggle" name="wpps-hide-mode-' + index + '" value="toggle" class="wpps-hide-rule-mode wpps-hide-rules-input" data-index="' + index + '"' + (hideMode === 'toggle' ? ' checked' : '') + ' />';
					html += '<span>' + self.escapeHtml(wppsMenuOrganizer.strings.hideModeToggle || 'Collapse under "Show All"') + '</span>';
					html += '</label>';
					html += '<label class="wpps-hide-rules-label">';
					html += '<input type="radio" id="wpps-hide-mode-' + index + '-remove" name="wpps-hide-mode-' + index + '" value="remove" class="wpps-hide-rule-mode wpps-hide-rules-input" data-index="' + index + '"' + (hideMode === 'remove' ? ' checked' : '') + ' />';
					html += '<span>' + self.escapeHtml(wppsMenuOrganizer.strings.hideModeRemove || 'Remove from menu') + '</span>';
					html += '</label>';
					html += '</div>';
					
					const eligibleRoles = item.eligible_roles || {};
					if (hideRules.type === 'specific' || hideRules.type === 'except') {
						html += '<div class="wpps-hide-rules-roles" data-index="' + index + '">';
						if (Object.keys(eligibleRoles).length > 0) {
							for (const roleKey in eligibleRoles) {
								if (Object.prototype.hasOwnProperty.call(eligibleRoles, roleKey)) {
									const roleLabel = eligibleRoles[roleKey];
									const isRoleSelected = hideRules.roles && hideRules.roles.indexOf(roleKey) !== -1;
									html += '<label class="wpps-hide-rules-label">';
									html += '<input type="checkbox" id="wpps-hide-rule-role-' + index + '-' + self.escapeAttr(roleKey) + '" name="wpps-hide-rule-role-' + index + '[]" class="wpps-hide-rule-role wpps-hide-rules-input" data-index="' + index + '" data-role="' + self.escapeAttr(roleKey) + '" value="' + self.escapeAttr(roleKey) + '"' + (isRoleSelected ? ' checked' : '') + ' />';
									html += '<span>' + self.escapeHtml(roleLabel) + '</span>';
									html += '</label>';
								}
							}
						} else {
							html += '<p class="wpps-hide-rules-no-roles">No roles eligible for this menu item.</p>';
						}
						html += '</div>';
					} else {
						html += '<div class="wpps-hide-rules-roles" data-index="' + index + '" style="display: none;"></div>';
					}
					
					html += '<div class="wpps-hide-rules-users" data-index="' + index + '">';
					html += '<p class="wpps-hide-rules-users-label">' + self.escapeHtml('Hide for specific user(s):') + '</p>';
					html += '<input type="text" class="wpps-hide-rules-user-search regular-text" data-index="' + index + '" placeholder="' + self.escapeAttr('Search users...') + '" />';
					html += '<div class="wpps-hide-rules-users-selected" data-index="' + index + '">';
					const usersMap = self.usersMap || {};
					const hideUsers = hideRules.users || [];
					const seenUids = {};
					hideUsers.forEach(function(uid) {
						const id = parseInt(uid, 10);
						if (seenUids[id]) return;
						seenUids[id] = true;
						const u = usersMap[id] || usersMap[String(id)];
						if (u) {
							html += '<span class="wpps-hide-rules-user-tag" data-index="' + index + '" data-user-id="' + id + '">';
							html += self.escapeHtml(u.display_name || u.user_login || 'User ' + id) + ' <span class="wpps-remove-user">&times;</span>';
							html += '</span>';
						}
					});
					html += '</div>';
					html += '</div>';
					
					html += '</div>';
				}

				if (!isSeparator) {
					const rootSubKey = self.submenuExpandKey(index, '');
					const isExpanded = expandedSubmenus[rootSubKey] === true || expandedSubmenus[index] === true;
					html += '<div class="wpps-menu-subitems" data-parent-index="' + index + '" data-sub-path="" style="display: ' + (isExpanded ? 'block' : 'none') + ';">';

					const childOrder = self.getChildOrderForParent(index);
					const relocatedBySlug = {};
					(self.getRelocatedItemsForParent(index) || []).forEach(function(entry) {
						relocatedBySlug[entry.slug] = entry;
					});
					const renderedSlugs = {};

					childOrder.forEach(function(slug) {
						if (!slug || renderedSlugs[slug]) {
							return;
						}
						if (relocatedBySlug[slug]) {
							html += self.renderMovedSubitemHtml(index, relocatedBySlug[slug].index, expandedMoved, expandedMoveUnder);
							renderedSlugs[slug] = true;
							return;
						}
						const subIndex = (item.submenu || []).findIndex(function(sub) {
							return self.getItemSlug(sub) === slug;
						});
						if (subIndex !== -1) {
							html += self.renderSubmenuTree(index, [item.submenu[subIndex]], '', 0, expandedSubmenus, false, String(subIndex));
							renderedSlugs[slug] = true;
						}
					});

					(item.submenu || []).forEach(function(sub, subIndex) {
						const slug = self.getItemSlug(sub);
						if (!slug || renderedSlugs[slug] || relocatedBySlug[slug]) {
							return;
						}
						html += self.renderSubmenuTree(index, [sub], '', 0, expandedSubmenus, false, String(subIndex));
						renderedSlugs[slug] = true;
					});

					Object.keys(relocatedBySlug).forEach(function(slug) {
						if (renderedSlugs[slug]) {
							return;
						}
						html += self.renderMovedSubitemHtml(index, relocatedBySlug[slug].index, expandedMoved, expandedMoveUnder);
						renderedSlugs[slug] = true;
					});

					html += '<button type="button" class="button button-small wpps-add-submenu-item" data-parent-index="' + index + '" data-sub-path="">';
					html += self.escapeHtml('Add Submenu Item');
					html += '</button>';
					html += '</div>';
				}

				html += '</div>'; // .wpps-menu-row
			});

			html += '<div class="wpps-menu-actions-footer">';
			html += '<button type="button" class="button wpps-add-menu-item">';
			html += self.escapeHtml('Add Menu Item');
			html += '</button>';
			html += '<button type="button" class="button wpps-add-separator">';
			html += self.escapeHtml('Add Separator');
			html += '</button>';
			html += '</div>';
			
			if ($container.hasClass('ui-sortable')) {
				try { $container.sortable('destroy'); } catch (e) {}
			}
			$container.find('.ui-sortable-placeholder').remove();
			$container.html(html);
			self.syncEditorIconsFromSidebar();
			self.initSubmenuSortables();

			$container.sortable({
				items: '> .wpps-menu-row',
				axis: 'y',
				placeholder: 'wpps-menu-row ui-sortable-placeholder',
				tolerance: 'pointer',
				// Match submenu: drag from the row itself, not only the hamburger icon.
				cancel: 'input, button, a, select, textarea, label, .wpps-menu-subitems, .wpps-move-under-dropdown, .wpps-hide-rules-dropdown, .wpps-menu-item-actions, .wpps-menu-actions-footer',
				start: function() {
					$('.wpps-menu-subitems.ui-sortable, .wpps-menu-subsubitems.ui-sortable').each(function() {
						try { $(this).sortable('disable'); } catch (e) {}
					});
				},
				stop: function() {
					$('.wpps-menu-subitems.ui-sortable, .wpps-menu-subsubitems.ui-sortable').each(function() {
						try { $(this).sortable('enable'); } catch (e) {}
					});
				},
				update: function() {
					self.updateMenuOrder();
				}
			});

			$(document).off('click', '.wpps-icon-clickable').on('click', '.wpps-icon-clickable', function(e) {
				e.stopPropagation();
				const index = parseInt($(this).data('index'), 10);
				self.openEditModal(index);
			});

			$(document).off('click', '.wpps-toggle-submenu').on('click', '.wpps-toggle-submenu', function(e) {
				e.preventDefault();
				e.stopPropagation();
				const parentIndex = $(this).data('parent-index');
				const $submenu = $('.wpps-menu-subitems[data-parent-index="' + parentIndex + '"]');
				const $link = $(this);
				
				if ($submenu.is(':visible')) {
					$submenu.slideUp(200);
					$link.text('Show Submenu');
				} else {
					$submenu.slideDown(200, function() {
						self.initSubmenuSortables();
					});
					$link.text('Hide Submenu');
				}
			});

			$(document).off('click', '.wpps-edit-moved-item').on('click', '.wpps-edit-moved-item', function(e) {
				e.preventDefault();
				e.stopPropagation();
				const movedIdx = parseInt($(this).data('moved-index'), 10);
				if (isNaN(movedIdx) || !self.currentMenu[movedIdx]) {
					return;
				}
				if (self.currentMenu[movedIdx].is_custom) {
					self.openEditCustomModal(movedIdx);
				} else {
					self.openEditModal(movedIdx);
				}
			});

			$(document).off('click', '.wpps-toggle-nested-submenu').on('click', '.wpps-toggle-nested-submenu', function(e) {
				e.preventDefault();
				const parentIndex = parseInt($(this).data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($(this));
				const $nested = $('.wpps-menu-subitems[data-parent-index="' + parentIndex + '"][data-sub-path="' + subPath + '"]');
				const $link = $(this);
				if ($nested.is(':visible')) {
					$nested.slideUp(200);
					$link.text('Show nested');
				} else {
					$nested.slideDown(200, function() {
						self.initSubmenuSortables();
					});
					const count = ($nested.find('> .wpps-menu-subitem').length);
					$link.text('Hide nested' + (count ? ' (' + count + ')' : ''));
				}
			});

			$(document).off('click', '.wpps-toggle-moved-submenu').on('click', '.wpps-toggle-moved-submenu', function(e) {
				e.preventDefault();
				e.stopPropagation();
				const movedIdx = $(this).data('moved-index');
				const $sub = $('.wpps-menu-subsubitems[data-moved-index="' + movedIdx + '"]');
				const $link = $(this);
				if ($sub.is(':visible')) {
					$sub.slideUp(200);
					$link.text('Show Submenu');
				} else {
					$sub.slideDown(200);
					$link.text('Hide Submenu');
				}
			});

			$(document).off('blur', '.wpps-moved-item-title').on('blur', '.wpps-moved-item-title', function() {
				const movedIdx = parseInt($(this).data('moved-index'), 10);
				const newTitle = $(this).val() || '';
				if (!isNaN(movedIdx) && self.currentMenu[movedIdx] && newTitle) {
					self.currentMenu[movedIdx].title = newTitle.trim();
				}
			});

			$(document).off('blur', '.wpps-subsubitem-title').on('blur', '.wpps-subsubitem-title', function() {
				const movedIdx = parseInt($(this).data('moved-index'), 10);
				const subIdx = parseInt($(this).data('sub-index'), 10);
				const newTitle = $(this).val() || '';
				if (!isNaN(movedIdx) && !isNaN(subIdx) && self.currentMenu[movedIdx] && self.currentMenu[movedIdx].submenu && self.currentMenu[movedIdx].submenu[subIdx] && newTitle) {
					self.currentMenu[movedIdx].submenu[subIdx].title = newTitle.trim();
				}
			});

			$(document).off('change', '.wpps-toggle-hidden').on('change', '.wpps-toggle-hidden', function(e) {
				e.stopPropagation();
				const index = parseInt($(this).data('index'), 10);
				const isHidden = $(this).is(':checked');
				if (self.currentMenu[index]) {
					self.currentMenu[index].hidden = isHidden;
					if (isHidden && !self.currentMenu[index].hide_rules) {
						self.currentMenu[index].hide_rules = { type: 'all', roles: [], users: [], mode: 'toggle' };
					}
					self.renderMenu();
				}
			});

			$(document).off('click', '.wpps-toggle-move-under').on('click', '.wpps-toggle-move-under', function(e) {
				e.preventDefault();
				e.stopPropagation();
				const index = parseInt($(this).data('index'), 10);
				const $dropdown = $('.wpps-move-under-dropdown[data-index="' + index + '"]');
				const $link = $(this);
				if ($dropdown.is(':visible')) {
					$dropdown.slideUp(200);
					const item = self.currentMenu[index];
					$link.text(item && item.parent_slug ? 'Move (under ' + (self.getParentTitle(item.parent_slug) || item.parent_slug) + ')' : 'Move under');
				} else {
					$dropdown.slideDown(200);
					$link.text('Move under');
				}
			});

			$(document).off('change', '.wpps-move-under-select').on('change', '.wpps-move-under-select', function() {
				const index = parseInt($(this).data('index'), 10);
				const parentSlug = $(this).val() || '';
				if (!self.currentMenu[index]) {
					return;
				}
				const childSlug = self.getItemSlug(self.currentMenu[index]);
				self.removeSlugFromAllChildOrders(childSlug);
				self.currentMenu[index].parent_slug = parentSlug;
				self._closeMoveUnderIndex = index;
				if (parentSlug) {
					self.addSlugToParentChildOrder(parentSlug, childSlug);
					const parentIdx = self.findParentIndexBySlug(parentSlug);
					if (parentIdx !== -1) {
						self._forceExpandParentIndex = parentIdx;
					}
				}
				self.renderMenu();
			});

			$(document).off('click', '.wpps-toggle-hide-rules').on('click', '.wpps-toggle-hide-rules', function(e) {
				e.preventDefault();
				e.stopPropagation();
				const index = parseInt($(this).data('index'), 10);
				const $dropdown = $('.wpps-hide-rules-dropdown[data-index="' + index + '"]');
				const $link = $(this);
				
				if ($dropdown.is(':visible')) {
					$dropdown.slideUp(200);
					$link.text('Show Hide Rules');
				} else {
					$dropdown.slideDown(200);
					$link.text('Hide Rules');
				}
			});

			$(document).off('change', '.wpps-hide-rule-type').on('change', '.wpps-hide-rule-type', function() {
				const index = parseInt($(this).data('index'), 10);
				const ruleType = $(this).val();
				const $rolesContainer = $('.wpps-hide-rules-roles[data-index="' + index + '"]');
				
				if (self.currentMenu[index]) {
					if (!self.currentMenu[index].hide_rules) {
						self.currentMenu[index].hide_rules = { type: ruleType, roles: [], users: [], mode: 'toggle' };
					} else {
						self.currentMenu[index].hide_rules.type = ruleType;
						if (ruleType === 'specific' || ruleType === 'except') {
							self.currentMenu[index].hide_rules.mode = 'remove';
						}
					}
					
					if (ruleType === 'specific' || ruleType === 'except') {
						if ($rolesContainer.find('.wpps-hide-rule-role').length === 0) {
							$rolesContainer.empty();
							const eligibleRoles = self.currentMenu[index].eligible_roles || {};
							if (Object.keys(eligibleRoles).length > 0) {
								for (const roleKey in eligibleRoles) {
									if (Object.prototype.hasOwnProperty.call(eligibleRoles, roleKey)) {
										const roleLabel = eligibleRoles[roleKey];
										const isRoleSelected = self.currentMenu[index].hide_rules.roles && self.currentMenu[index].hide_rules.roles.indexOf(roleKey) !== -1;
										$rolesContainer.append(
										$('<label>').addClass('wpps-hide-rules-label').append(
											$('<input>').attr({ type: 'checkbox', class: 'wpps-hide-rule-role wpps-hide-rules-input', 'data-index': index, 'data-role': roleKey }).prop('checked', isRoleSelected)
										).append($('<span>').text(roleLabel))
										);
									}
								}
							} else {
								$rolesContainer.append($('<p>').addClass('wpps-hide-rules-no-roles').text('No roles eligible for this menu item.'));
							}
						}
						$rolesContainer.slideDown(200);
					} else {
						$rolesContainer.slideUp(200);
					}
				}
			});

			$(document).off('change', '.wpps-hide-rule-mode').on('change', '.wpps-hide-rule-mode', function() {
				const index = parseInt($(this).data('index'), 10);
				const mode = $(this).val();
				if (self.currentMenu[index]) {
					if (!self.currentMenu[index].hide_rules) {
						self.currentMenu[index].hide_rules = { type: 'all', roles: [], users: [], mode: mode };
					} else {
						self.currentMenu[index].hide_rules.mode = mode;
					}
				}
			});

			$(document).off('change', '.wpps-submenu-hide-rule-mode').on('change', '.wpps-submenu-hide-rule-mode', function() {
				const parentIndex = parseInt($(this).data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($(this));
				const mode = $(this).val();
				const sub = self.getSubmenuItemByPath(parentIndex, subPath);
				if (sub) {
					if (!sub.hide_rules) {
						sub.hide_rules = { type: 'all', roles: [], users: [], mode: mode };
					} else {
						sub.hide_rules.mode = mode;
					}
				}
			});

			$(document).off('change', '.wpps-hide-rule-role').on('change', '.wpps-hide-rule-role', function() {
				const index = parseInt($(this).data('index'), 10);
				const roleKey = $(this).data('role');
				const isChecked = $(this).is(':checked');
				
				if (self.currentMenu[index] && self.currentMenu[index].hide_rules) {
					if (!self.currentMenu[index].hide_rules.roles) {
						self.currentMenu[index].hide_rules.roles = [];
					}
					
					const roleIndex = self.currentMenu[index].hide_rules.roles.indexOf(roleKey);
					if (isChecked && roleIndex === -1) {
						self.currentMenu[index].hide_rules.roles.push(roleKey);
					} else if (!isChecked && roleIndex !== -1) {
						self.currentMenu[index].hide_rules.roles.splice(roleIndex, 1);
					}
				}
			});

			$(document).off('input', '.wpps-hide-rules-user-search').on('input', '.wpps-hide-rules-user-search', function() {
				const index = parseInt($(this).data('index'), 10);
				const term = $(this).val().trim();
				const $input = $(this);
				const $container = $input.closest('.wpps-hide-rules-users');
				let $dropdown = $container.find('.wpps-user-search-dropdown');
				if (term.length < 2) {
					$dropdown.remove();
					return;
				}
				clearTimeout(self._userSearchTimeout);
				self._userSearchTimeout = setTimeout(function() {
					$.ajax({
						url: wppsMenuOrganizer.ajaxUrl,
						type: 'POST',
						data: {
							action: 'wpps_search_users',
							nonce: wppsMenuOrganizer.nonce,
							term: term
						},
						success: function(response) {
							if (response.success && response.data.users && response.data.users.length > 0) {
								$dropdown.remove();
								const selectedIds = (self.currentMenu[index] && self.currentMenu[index].hide_rules && self.currentMenu[index].hide_rules.users) ? self.currentMenu[index].hide_rules.users.map(function(id) { return parseInt(id, 10); }) : [];
								$dropdown = $('<div class="wpps-user-search-dropdown"></div>');
								response.data.users.forEach(function(u) {
									if (selectedIds.indexOf(parseInt(u.id, 10)) !== -1) return;
									const $opt = $('<div class="wpps-user-search-option" data-user-id="' + u.id + '" data-display="' + self.escapeAttr(u.display_name || u.user_login) + '" data-login="' + self.escapeAttr(u.user_login) + '">' + self.escapeHtml(u.display_name || u.user_login) + '</div>');
									$dropdown.append($opt);
								});
								if ($dropdown.children().length === 0) {
									$dropdown.append($('<div class="wpps-user-search-empty">' + (wppsMenuOrganizer.strings.allSelected || 'All matching users already selected.') + '</div>'));
								}
								$container.append($dropdown);
								$dropdown.find('.wpps-user-search-option').on('click', function(e) {
									e.preventDefault();
									e.stopPropagation();
									const uid = parseInt($(this).data('user-id'), 10);
									const displayName = $(this).data('display');
									const userLogin = $(this).data('login');
									if (self.currentMenu[index] && self.currentMenu[index].hide_rules) {
										if (!self.currentMenu[index].hide_rules.users) self.currentMenu[index].hide_rules.users = [];
										if (self.currentMenu[index].hide_rules.users.indexOf(uid) === -1) {
											self.currentMenu[index].hide_rules.users.push(uid);
											self.usersMap[uid] = { display_name: displayName, user_login: userLogin };
										}
									}
									const $selected = $container.find('.wpps-hide-rules-users-selected');
									const $tag = $('<span class="wpps-hide-rules-user-tag" data-index="' + index + '" data-user-id="' + uid + '">' + self.escapeHtml(displayName || userLogin || 'User ' + uid) + ' <span class="wpps-remove-user">&times;</span></span>');
									$selected.append($tag);
									$(this).remove();
									if ($dropdown.find('.wpps-user-search-option').length === 0) {
										$dropdown.html('<div class="wpps-user-search-empty">' + (wppsMenuOrganizer.strings.allSelected || 'All matching users already selected.') + '</div>');
									}
									$input.val('').focus();
								});
							} else {
								$dropdown.remove();
							}
						}
					});
				}, 300);
			});

			$(document).off('click', '.wpps-hide-rules-user-tag .wpps-remove-user').on('click', '.wpps-hide-rules-user-tag .wpps-remove-user', function(e) {
				e.preventDefault();
				const $tag = $(this).closest('.wpps-hide-rules-user-tag');
				const index = parseInt($tag.data('index'), 10);
				const uid = parseInt($tag.data('user-id'), 10);
				if (self.currentMenu[index] && self.currentMenu[index].hide_rules && self.currentMenu[index].hide_rules.users) {
					const idx = self.currentMenu[index].hide_rules.users.indexOf(uid);
					if (idx !== -1) self.currentMenu[index].hide_rules.users.splice(idx, 1);
				}
				self.renderMenu();
			});

			$(document).off('input', '.wpps-submenu-hide-rules-user-search').on('input', '.wpps-submenu-hide-rules-user-search', function() {
				const parentIndex = parseInt($(this).data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($(this));
				const term = $(this).val().trim();
				const $input = $(this);
				const $container = $input.closest('.wpps-submenu-hide-rules-users');
				let $dropdown = $container.find('.wpps-user-search-dropdown');
				if (term.length < 2) {
					$dropdown.remove();
					return;
				}
				clearTimeout(self._userSearchTimeout);
				self._userSearchTimeout = setTimeout(function() {
					$.ajax({
						url: wppsMenuOrganizer.ajaxUrl,
						type: 'POST',
						data: { action: 'wpps_search_users', nonce: wppsMenuOrganizer.nonce, term: term },
						success: function(response) {
							if (response.success && response.data.users && response.data.users.length > 0) {
								$dropdown.remove();
								const sub = self.getSubmenuItemByPath(parentIndex, subPath);
								const selectedIds = (sub && sub.hide_rules && sub.hide_rules.users) ? sub.hide_rules.users.map(function(id) { return parseInt(id, 10); }) : [];
								$dropdown = $('<div class="wpps-user-search-dropdown"></div>');
								response.data.users.forEach(function(u) {
									if (selectedIds.indexOf(parseInt(u.id, 10)) !== -1) return;
									$dropdown.append($('<div class="wpps-user-search-option" data-user-id="' + u.id + '" data-display="' + self.escapeAttr(u.display_name || u.user_login) + '" data-login="' + self.escapeAttr(u.user_login) + '">' + self.escapeHtml(u.display_name || u.user_login) + '</div>'));
								});
								if ($dropdown.children().length === 0) {
									$dropdown.append($('<div class="wpps-user-search-empty">' + (wppsMenuOrganizer.strings.allSelected || 'All matching users already selected.') + '</div>'));
								}
								$container.append($dropdown);
								$dropdown.find('.wpps-user-search-option').on('click', function(e) {
									e.preventDefault();
									e.stopPropagation();
									const uid = parseInt($(this).data('user-id'), 10);
									const displayName = $(this).data('display');
									const userLogin = $(this).data('login');
									const s = self.getSubmenuItemByPath(parentIndex, subPath);
									if (s && s.hide_rules) {
										if (!s.hide_rules.users) s.hide_rules.users = [];
										if (s.hide_rules.users.indexOf(uid) === -1) {
											s.hide_rules.users.push(uid);
											self.usersMap[uid] = { display_name: displayName, user_login: userLogin };
										}
									}
									const $selected = $container.find('.wpps-hide-rules-users-selected, .wpps-submenu-hide-rules-users-selected');
									const $tag = $('<span class="wpps-submenu-hide-rules-user-tag" data-parent-index="' + parentIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '" data-user-id="' + uid + '">' + self.escapeHtml(displayName || userLogin || 'User ' + uid) + ' <span class="wpps-remove-user">&times;</span></span>');
									$selected.append($tag);
									$(this).remove();
									if ($dropdown.find('.wpps-user-search-option').length === 0) {
										$dropdown.html('<div class="wpps-user-search-empty">' + (wppsMenuOrganizer.strings.allSelected || 'All matching users already selected.') + '</div>');
									}
									$input.val('').focus();
								});
							} else {
								$dropdown.remove();
							}
						}
					});
				}, 300);
			});

			$(document).off('click', '.wpps-submenu-hide-rules-user-tag .wpps-remove-user').on('click', '.wpps-submenu-hide-rules-user-tag .wpps-remove-user', function(e) {
				e.preventDefault();
				const $tag = $(this).closest('.wpps-submenu-hide-rules-user-tag');
				const parentIndex = parseInt($tag.data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($tag);
				const uid = parseInt($tag.data('user-id'), 10);
				const sub = self.getSubmenuItemByPath(parentIndex, subPath);
				if (sub && sub.hide_rules && sub.hide_rules.users) {
					const idx = sub.hide_rules.users.indexOf(uid);
					if (idx !== -1) {
						sub.hide_rules.users.splice(idx, 1);
					}
				}
				self.renderMenu();
			});

			$(document).off('blur', '.wpps-menu-item-title').on('blur', '.wpps-menu-item-title', function() {
				const index = parseInt($(this).data('index'), 10);
				const newTitle = $(this).val() || '';
				if (self.currentMenu[index] && newTitle) {
					self.currentMenu[index].title = newTitle.trim();
				}
			});

			$(document).off('blur', '.wpps-subitem-title').on('blur', '.wpps-subitem-title', function() {
				const parentIndex = parseInt($(this).data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($(this));
				const newTitle = $(this).val() || '';
				const sub = self.getSubmenuItemByPath(parentIndex, subPath);
				if (sub && newTitle) {
					sub.title = newTitle.trim();
				}
			});

			$(document).off('change', '.wpps-toggle-submenu-hidden').on('change', '.wpps-toggle-submenu-hidden', function(e) {
				e.stopPropagation();
				const parentIndex = parseInt($(this).data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($(this));
				const isHidden = $(this).is(':checked');
				const sub = self.getSubmenuItemByPath(parentIndex, subPath);
				if (sub) {
					sub.hidden = isHidden;
					if (isHidden && !sub.hide_rules) {
						sub.hide_rules = { type: 'all', roles: [], users: [], mode: 'toggle' };
					}
					self.renderMenu();
				}
			});

			$(document).off('click', '.wpps-toggle-submenu-hide-rules').on('click', '.wpps-toggle-submenu-hide-rules', function(e) {
				e.preventDefault();
				e.stopPropagation();
				const parentIndex = parseInt($(this).data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($(this));
				const $dropdown = $('.wpps-submenu-hide-rules-dropdown[data-parent-index="' + parentIndex + '"][data-sub-path="' + subPath + '"]');
				const $link = $(this);
				
				if ($dropdown.is(':visible')) {
					$dropdown.slideUp(200);
					$link.text('Show Hide Rules');
				} else {
					$dropdown.slideDown(200);
					$link.text('Hide Rules');
				}
			});

			$(document).off('change', '.wpps-submenu-hide-rule-type').on('change', '.wpps-submenu-hide-rule-type', function() {
				const parentIndex = parseInt($(this).data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($(this));
				const ruleType = $(this).val();
				const $rolesContainer = $('.wpps-submenu-hide-rules-roles[data-parent-index="' + parentIndex + '"][data-sub-path="' + subPath + '"]');
				const sub = self.getSubmenuItemByPath(parentIndex, subPath);

				if (sub) {
					if (!sub.hide_rules) {
						sub.hide_rules = { type: ruleType, roles: [], users: [], mode: 'toggle' };
					} else {
						sub.hide_rules.type = ruleType;
						if (ruleType === 'specific' || ruleType === 'except') {
							sub.hide_rules.mode = 'remove';
						}
					}

					if (ruleType === 'specific' || ruleType === 'except') {
						if ($rolesContainer.find('.wpps-submenu-hide-rule-role').length === 0) {
							$rolesContainer.empty();
							const eligibleRoles = sub.eligible_roles || {};
							if (Object.keys(eligibleRoles).length > 0) {
								for (const roleKey in eligibleRoles) {
									if (Object.prototype.hasOwnProperty.call(eligibleRoles, roleKey)) {
										const roleLabel = eligibleRoles[roleKey];
										const isRoleSelected = sub.hide_rules.roles && sub.hide_rules.roles.indexOf(roleKey) !== -1;
										$rolesContainer.append(
											$('<label>').addClass('wpps-hide-rules-label').append(
												$('<input>').attr({ type: 'checkbox', class: 'wpps-submenu-hide-rule-role wpps-hide-rules-input', 'data-parent-index': parentIndex, 'data-sub-path': subPath, 'data-role': roleKey }).prop('checked', isRoleSelected)
											).append($('<span>').text(roleLabel))
										);
									}
								}
							} else {
								$rolesContainer.append($('<p>').css({ color: '#646970', fontSize: '12px', margin: 0 }).text('No roles eligible for this submenu item.'));
							}
						}
						$rolesContainer.slideDown(200);
					} else {
						$rolesContainer.slideUp(200);
					}
				}
			});

			$(document).off('change', '.wpps-submenu-hide-rule-role').on('change', '.wpps-submenu-hide-rule-role', function() {
				const parentIndex = parseInt($(this).data('parent-index'), 10);
				const subPath = self.resolveSubPathFromEl($(this));
				const roleKey = $(this).data('role');
				const isChecked = $(this).is(':checked');
				const sub = self.getSubmenuItemByPath(parentIndex, subPath);

				if (sub && sub.hide_rules) {
					if (!sub.hide_rules.roles) {
						sub.hide_rules.roles = [];
					}

					const roleIndex = sub.hide_rules.roles.indexOf(roleKey);
					if (isChecked && roleIndex === -1) {
						sub.hide_rules.roles.push(roleKey);
					} else if (!isChecked && roleIndex !== -1) {
						sub.hide_rules.roles.splice(roleIndex, 1);
					}
				}
			});
		},

		initSubmenuSortables: function() {
			const self = this;
			$('.wpps-menu-subitems').each(function() {
				const $submenu = $(this);
				if ($submenu.hasClass('ui-sortable')) {
					try { $submenu.sortable('destroy'); } catch (e) {}
				}
				$submenu.sortable({
					items: '> .wpps-menu-subitem',
					axis: 'y',
					placeholder: 'wpps-menu-subitem ui-sortable-placeholder',
					tolerance: 'pointer',
					cancel: 'input, button, a, select, textarea, label, .wpps-move-under-dropdown, .wpps-menu-subsubitems',
					update: function() {
						const parentIndex = parseInt($submenu.data('parent-index'), 10);
						const listParentPath = $submenu.attr('data-sub-path');
						self.updateSubmenuOrder(parentIndex, listParentPath !== undefined ? String(listParentPath) : '');
					}
				});
			});

			// Nested children of a relocated item (e.g. Posts → under Dashboard).
			$('.wpps-menu-subsubitems').each(function() {
				const $list = $(this);
				if ($list.hasClass('ui-sortable')) {
					try { $list.sortable('destroy'); } catch (e) {}
				}
				$list.sortable({
					items: '> .wpps-menu-subsubitem',
					axis: 'y',
					placeholder: 'wpps-menu-subsubitem ui-sortable-placeholder',
					tolerance: 'pointer',
					cancel: 'input, button, a',
					update: function() {
						const movedIdx = parseInt($list.data('moved-index'), 10);
						const item = !isNaN(movedIdx) ? self.currentMenu[movedIdx] : null;
						if (!item || !item.submenu || !item.submenu.length) {
							return;
						}
						const newOrder = [];
						$list.children('.wpps-menu-subsubitem').each(function() {
							const subIdx = parseInt($(this).attr('data-sub-index'), 10);
							if (!isNaN(subIdx) && item.submenu[subIdx]) {
								newOrder.push(item.submenu[subIdx]);
							}
						});
						if (newOrder.length !== item.submenu.length) {
							return;
						}
						item.submenu = newOrder;
						$list.children('.wpps-menu-subsubitem').each(function(i) {
							$(this).attr('data-sub-index', i);
							$(this).find('.wpps-subsubitem-title').attr('data-sub-index', i);
						});
					}
				});
			});
		},

		updateSubmenuOrder: function(parentIndex, listParentPath) {
			const self = this;
			if (listParentPath === undefined) {
				listParentPath = '';
			}

			const $submenu = $('.wpps-menu-subitems[data-parent-index="' + parentIndex + '"][data-sub-path="' + listParentPath + '"]');
			if (!$submenu.length) {
				return;
			}

			// Root submenu: persist interleaved native + moved order without re-render
			// (re-render was collapsing the open submenu panel).
			if (listParentPath === '') {
				const childOrder = [];
				const nativeOrdered = [];
				$submenu.children('.wpps-menu-subitem').each(function() {
					const movedIdx = $(this).attr('data-moved-index');
					const path = $(this).attr('data-sub-path');
					if (movedIdx !== undefined && movedIdx !== null && movedIdx !== '') {
						const idx = parseInt(movedIdx, 10);
						const moved = !isNaN(idx) ? self.currentMenu[idx] : null;
						if (moved) {
							const slug = self.getItemSlug(moved);
							if (slug) {
								childOrder.push(slug);
							}
						}
						return;
					}
					if (path !== undefined && path !== null && path !== '') {
						const item = self.getSubmenuItemByPath(parentIndex, path);
						if (item) {
							nativeOrdered.push(item);
							const slug = self.getItemSlug(item);
							if (slug) {
								childOrder.push(slug);
							}
						}
					}
				});

				if (self.currentMenu[parentIndex]) {
					const prevNative = self.currentMenu[parentIndex].submenu || [];
					if (nativeOrdered.length === prevNative.length || prevNative.length === 0 || nativeOrdered.length > 0) {
						self.currentMenu[parentIndex].submenu = nativeOrdered;
					}
					self.setChildOrderForParent(parentIndex, childOrder);
				}

				let nativeI = 0;
				$submenu.children('.wpps-menu-subitem').each(function() {
					const movedIdx = $(this).attr('data-moved-index');
					if (movedIdx !== undefined && movedIdx !== null && movedIdx !== '') {
						return;
					}
					const newPath = String(nativeI);
					$(this).attr('data-sub-path', newPath).attr('data-sub-index', nativeI);
					$(this).find('[data-sub-path]').each(function() {
						const cur = String($(this).attr('data-sub-path') || '');
						if (cur.indexOf('.') === -1) {
							$(this).attr('data-sub-path', newPath);
						}
					});
					nativeI++;
				});
				return;
			}

			const items = this.getSubmenuItemsArray(parentIndex, listParentPath);
			if (!items) {
				return;
			}

			const newSubOrder = [];
			$submenu.children('.wpps-menu-subitem').each(function() {
				const path = $(this).attr('data-sub-path');
				const item = path ? self.getSubmenuItemByPath(parentIndex, path) : null;
				if (item) {
					newSubOrder.push(item);
				}
			});

			if (newSubOrder.length === items.length) {
				items.length = 0;
				Array.prototype.push.apply(items, newSubOrder);
				$submenu.children('.wpps-menu-subitem').each(function(i) {
					const newPath = listParentPath + '-' + i;
					const oldPath = String($(this).attr('data-sub-path') || '');
					$(this).attr('data-sub-path', newPath).attr('data-sub-index', i);
					$(this).find('[data-sub-path]').each(function() {
						const cur = String($(this).attr('data-sub-path') || '');
						if (cur === oldPath || cur.indexOf(oldPath + '-') === 0) {
							$(this).attr('data-sub-path', newPath + cur.substring(oldPath.length));
						}
					});
				});
			}
		},

		updateMenuOrder: function() {
			const self = this;
			const used = {};
			const newOrder = [];

			const takeItem = function(index) {
				if (isNaN(index) || !self.currentMenu[index] || used[index]) {
					return null;
				}
				used[index] = true;
				return self.currentMenu[index];
			};

			const findTopLevelBySlug = function(slug) {
				if (!slug) {
					return -1;
				}
				for (let i = 0; i < self.currentMenu.length; i++) {
					if (used[i]) {
						continue;
					}
					const item = self.currentMenu[i];
					if (!item || (item.parent_slug && !item.is_separator)) {
						continue;
					}
					if (self.getItemSlug(item) === slug || (item.menu_slug || '') === slug) {
						return i;
					}
				}
				return -1;
			};

			// Read DOM order via attributes (not jQuery .data() cache) + stable slugs.
			$('.wpps-menu-items-list > .wpps-menu-row').each(function() {
				const $row = $(this);
				const slug = String($row.attr('data-menu-slug') || '');
				let index = parseInt($row.attr('data-menu-key'), 10);
				let item = null;

				if (slug) {
					const bySlug = findTopLevelBySlug(slug);
					if (bySlug !== -1) {
						item = takeItem(bySlug);
					}
				}
				if (!item) {
					item = takeItem(index);
				}
				if (item) {
					newOrder.push(item);
				}
			});

			// Never drop items the DOM did not list (relocated, edge cases).
			self.currentMenu.forEach(function(item, index) {
				if (used[index] || !item) {
					return;
				}
				newOrder.push(item);
				used[index] = true;
			});

			if (newOrder.length !== self.currentMenu.length) {
				return;
			}

			this.currentMenu = newOrder;
			this.normalizeMenuPositions();
			// Re-render so data-moved-index / parent indices stay aligned after array reorder.
			this.renderMenu();
		},

		openEditModal: function(index) {
			const item = this.currentMenu[index];
			if (!item) {
				return;
			}

			this.editingItem = { type: 'menu', index: index };

			const icon = item.icon || '';
			const isSeparator = item.is_separator || false;

			$('#wpps-edit-menu-key').val(index);
			$('#wpps-edit-menu-slug').val(item.menu_slug || '');
			$('#wpps-edit-is-submenu').val('0');
			$('#wpps-edit-sub-index').val('');
			$('#wpps-edit-menu-icon').val(icon);

			if (isSeparator) {
				$('#wpps-edit-icon-row').hide();
			} else {
				$('#wpps-edit-icon-row').show();
			}

			$('#wpps-modal-title').text(isSeparator ? 'Edit Separator' : 'Edit Menu Item');
			$('#wpps-edit-menu-item-modal').addClass('active').show();
		},

		openEditSubmenuModal: function(parentIndex, subIndex) {
			const item = this.currentMenu[parentIndex];
			if (!item || !item.submenu || !item.submenu[subIndex]) {
				return;
			}

			$('#wpps-edit-menu-item-modal').removeClass('active').hide();
		},

		closeEditModal: function() {
			$('#wpps-edit-menu-item-modal').removeClass('active').hide();
			$('#wpps-edit-icon-row').show();
			this.editingItem = null;
		},

		saveMenuItem: function() {
			const isSubmenu = $('#wpps-edit-is-submenu').val() === '1';
			
			if (!isSubmenu) {
				const index = parseInt($('#wpps-edit-menu-key').val(), 10);
				if (isNaN(index) || !this.currentMenu[index]) {
					return;
				}

				const item = this.currentMenu[index];
				item.icon = $('#wpps-edit-menu-icon').val() || item.icon;
			}

			this.closeEditModal();
			this.renderMenu();
		},

		saveMenu: function() {
			const self = this;
			const $button = $('.wpps-save-menu');
			const originalText = $button.text();

			$button.prop('disabled', true).text(wppsMenuOrganizer.strings.saving || 'Saving...');

			this.normalizeMenuPositions();

			$.ajax({
				url: wppsMenuOrganizer.ajaxUrl,
				type: 'POST',
				data: {
					action: 'wpps_save_menu_config',
					nonce: wppsMenuOrganizer.nonce,
					menu_config: JSON.stringify(this.currentMenu),
				},
				success: function(response) {
					if (response.success) {
						// Full reload: the sidebar and editor list are only rebuilt
						// reliably on a real admin page load, never over admin-ajax.
						try {
							window.sessionStorage.setItem('wppsMenuOrganizerSaved', '1');
						} catch (e) {}
						window.location.reload();
						return;
					}
					alert(response.data?.message || wppsMenuOrganizer.strings.error || 'An error occurred.');
					$button.prop('disabled', false).text(originalText);
				},
				error: function() {
					alert(wppsMenuOrganizer.strings.error || 'An error occurred. Please try again.');
					$button.prop('disabled', false).text(originalText);
				}
			});
		},

		restoreMenu: function() {
			const self = this;
			const $button = $('.wpps-restore-menu');
			const originalText = $button.text();

			$button.prop('disabled', true).text(wppsMenuOrganizer.strings.restoring || 'Restoring...');

			$.ajax({
				url: wppsMenuOrganizer.ajaxUrl,
				type: 'POST',
				data: {
					action: 'wpps_restore_menu_config',
					nonce: wppsMenuOrganizer.nonce,
				},
				success: function(response) {
					if (response.success) {
						// Full reload: admin-ajax has no $menu globals; page bootstrap rebuilds the editor list.
						self.showNotice('success', wppsMenuOrganizer.strings.restored || 'Menu restored to defaults successfully!');
						window.location.reload();
						return;
					}
					alert(response.data?.message || wppsMenuOrganizer.strings.error || 'An error occurred.');
					$button.prop('disabled', false).text(originalText);
				},
				error: function() {
					alert(wppsMenuOrganizer.strings.error || 'An error occurred. Please try again.');
					$button.prop('disabled', false).text(originalText);
				}
			});
		},

		resolveSubPathFromEl: function($el) {
			if ($el.attr('data-sub-path') !== undefined) {
				return String($el.attr('data-sub-path'));
			}
			const subIndex = parseInt($el.attr('data-sub-index'), 10);
			return isNaN(subIndex) ? '' : String(subIndex);
		},

		getSubmenuItemsArray: function(menuIndex, parentPath) {
			if (!this.currentMenu[menuIndex]) {
				return null;
			}
			if (parentPath === '' || parentPath === undefined) {
				if (!this.currentMenu[menuIndex].submenu) {
					this.currentMenu[menuIndex].submenu = [];
				}
				return this.currentMenu[menuIndex].submenu;
			}
			const parts = String(parentPath).split('-');
			let items = this.currentMenu[menuIndex].submenu;
			for (let i = 0; i < parts.length; i++) {
				const idx = parseInt(parts[i], 10);
				if (!items || !items[idx]) {
					return null;
				}
				if (!items[idx].submenu) {
					items[idx].submenu = [];
				}
				items = items[idx].submenu;
			}
			return items;
		},

		getSubmenuItemByPath: function(menuIndex, subPath) {
			if (subPath === undefined || subPath === null || subPath === '') {
				return null;
			}
			const parts = String(subPath).split('-');
			let items = this.currentMenu[menuIndex] && this.currentMenu[menuIndex].submenu;
			let item = null;
			for (let i = 0; i < parts.length; i++) {
				const idx = parseInt(parts[i], 10);
				if (!items || !items[idx]) {
					return null;
				}
				item = items[idx];
				items = item.submenu;
			}
			return item;
		},

		spliceSubmenuItemByPath: function(menuIndex, subPath) {
			if (subPath === '' || subPath === undefined) {
				return null;
			}
			const parts = String(subPath).split('-');
			const last = parseInt(parts.pop(), 10);
			let items = this.getSubmenuItemsArray(menuIndex, parts.join('-'));
			if (!items || isNaN(last) || !items[last]) {
				return null;
			}
			return items.splice(last, 1)[0];
		},

		walkAllSubmenuItems: function(callback) {
			const self = this;
			function walk(items, menuIndex, parentPath) {
				if (!items || !items.length) {
					return;
				}
				items.forEach(function(item, idx) {
					const path = parentPath === '' ? String(idx) : parentPath + '-' + idx;
					callback(item, menuIndex, path);
					if (item.submenu && item.submenu.length) {
						walk(item.submenu, menuIndex, path);
					}
				});
			}
			this.currentMenu.forEach(function(menuItem, menuIndex) {
				walk(menuItem.submenu || [], menuIndex, '');
			});
		},

		renderSubmenuTree: function(menuIndex, submenuItems, parentPath, depth, expandedSubmenus, wrapContainer, forcedRootPath) {
			const self = this;
			let html = '';
			const indent = 12 + (depth * 18);

			submenuItems.forEach(function(subItem, subIndex) {
				let subPath;
				if (
					forcedRootPath !== undefined &&
					forcedRootPath !== null &&
					parentPath === '' &&
					subIndex === 0 &&
					submenuItems.length === 1
				) {
					subPath = String(forcedRootPath);
				} else {
					subPath = parentPath === '' ? String(subIndex) : parentPath + '-' + subIndex;
				}
				const subItemTitle = self.stripHtml(subItem.title || '');
				const isSubHidden = subItem.hidden || false;
				const isSubCustom = subItem.is_custom || false;
				const subHideRules = subItem.hide_rules || { type: 'all', roles: [], users: [], mode: 'toggle' };
				const subHideMode = subHideRules.mode || 'remove';
				const hasChildren = subItem.submenu && subItem.submenu.length > 0;
				const childKey = menuIndex + ':' + subPath;
				const childrenExpanded = expandedSubmenus[childKey] === true;
				const pathToken = subPath.replace(/-/g, '_');
				const depthClass = depth > 0 ? ' wpps-menu-subitem-nested' : '';

				html += '<div class="wpps-menu-subitem' + depthClass + (isSubHidden ? ' wpps-menu-item-hidden' : '') + '" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '" data-sub-index="' + subIndex + '" style="margin-left:' + indent + 'px;">';
				html += '<div class="wpps-menu-subitem-content">';
				html += '<span class="dashicons dashicons-arrow-right-alt wpps-submenu-arrow"></span>';
				html += '<input type="text" id="wpps-subitem-title-' + menuIndex + '-' + pathToken + '" class="wpps-subitem-title" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '" data-type="submenu" value="' + self.escapeAttr(subItemTitle) + '" />';
				if (hasChildren) {
					html += '<a href="#" class="wpps-toggle-nested-submenu wpps-action-link wpps-action-link-edit" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">';
					html += childrenExpanded ? 'Hide nested' : 'Show nested (' + subItem.submenu.length + ')';
					html += '</a>';
				}
				html += '</div>';

				if (isSubCustom) {
					html += '<a href="#" class="wpps-edit-custom-subitem wpps-action-link wpps-action-link-edit" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">Edit</a>';
					html += '<a href="#" class="wpps-delete-custom-subitem wpps-action-link wpps-action-link-delete" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">Delete</a>';
				} else {
					if (isSubHidden) {
						html += '<a href="#" class="wpps-toggle-submenu-hide-rules wpps-action-link wpps-action-link-edit" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">Show Hide Rules</a>';
					}
					html += '<label class="wpps-checkbox-label wpps-checkbox-label-auto">';
					html += '<input type="checkbox" class="wpps-toggle-submenu-hidden wpps-checkbox-input" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '"' + (isSubHidden ? ' checked' : '') + ' />';
					html += '<span class="wpps-label-text">Hide</span></label>';
				}

				if (isSubHidden) {
					html += self.renderSubmenuHideRulesDropdown(menuIndex, subPath, pathToken, subItem, subHideRules, subHideMode);
				}

				if (hasChildren) {
					html += '<div class="wpps-menu-subitems wpps-menu-subitems-nested" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '" style="display:' + (childrenExpanded ? 'block' : 'none') + ';">';
					html += self.renderSubmenuTree(menuIndex, subItem.submenu, subPath, depth + 1, expandedSubmenus, false);
					html += '<button type="button" class="button button-small wpps-add-submenu-item" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">';
					html += self.escapeHtml('Add nested item');
					html += '</button></div>';
				}

				html += '</div>'; // .wpps-menu-subitem
			});

			if (wrapContainer) {
				const rootKey = menuIndex + ':_root';
				const isExpanded = expandedSubmenus[rootKey] === true;
				return '<div class="wpps-menu-subitems" data-parent-index="' + menuIndex + '" data-sub-path="" style="display:' + (isExpanded ? 'block' : 'none') + ';">' + html + '</div>';
			}

			return html;
		},

		renderSubmenuHideRulesDropdown: function(menuIndex, subPath, pathToken, subItem, subHideRules, subHideMode) {
			const self = this;
			let html = '<div class="wpps-submenu-hide-rules-dropdown" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">';
			html += '<div class="wpps-hide-rules-options">';
			['all', 'specific', 'except'].forEach(function(type) {
				html += '<label class="wpps-hide-rules-label"><input type="radio" name="wpps-submenu-hide-rule-' + menuIndex + '-' + pathToken + '" value="' + type + '" class="wpps-submenu-hide-rule-type wpps-hide-rules-input" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '"' + (subHideRules.type === type ? ' checked' : '') + ' /><span>Hide for ' + (type === 'all' ? 'all' : (type === 'specific' ? 'Specific Role(s)' : 'all except')) + '</span></label>';
			});
			html += '</div>';
			html += '<div class="wpps-submenu-hide-rules-mode" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">';
			html += '<p class="wpps-hide-rules-mode-label">' + self.escapeHtml('Visibility:') + '</p>';
			html += '<label class="wpps-hide-rules-label"><input type="radio" name="wpps-submenu-hide-mode-' + menuIndex + '-' + pathToken + '" value="toggle" class="wpps-submenu-hide-rule-mode wpps-hide-rules-input" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '"' + (subHideMode === 'toggle' ? ' checked' : '') + ' /><span>' + self.escapeHtml(wppsMenuOrganizer.strings.hideModeToggle || 'Collapse under "Show All"') + '</span></label>';
			html += '<label class="wpps-hide-rules-label"><input type="radio" name="wpps-submenu-hide-mode-' + menuIndex + '-' + pathToken + '" value="remove" class="wpps-submenu-hide-rule-mode wpps-hide-rules-input" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '"' + (subHideMode === 'remove' ? ' checked' : '') + ' /><span>' + self.escapeHtml(wppsMenuOrganizer.strings.hideModeRemove || 'Remove from menu') + '</span></label>';
			html += '</div>';

			const subEligibleRoles = subItem.eligible_roles || {};
			if (subHideRules.type === 'specific' || subHideRules.type === 'except') {
				html += '<div class="wpps-submenu-hide-rules-roles" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">';
				if (Object.keys(subEligibleRoles).length > 0) {
					for (const roleKey in subEligibleRoles) {
						if (Object.prototype.hasOwnProperty.call(subEligibleRoles, roleKey)) {
							const isRoleSelected = subHideRules.roles && subHideRules.roles.indexOf(roleKey) !== -1;
							html += '<label class="wpps-hide-rules-label"><input type="checkbox" class="wpps-submenu-hide-rule-role wpps-hide-rules-input" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '" data-role="' + self.escapeAttr(roleKey) + '" value="' + self.escapeAttr(roleKey) + '"' + (isRoleSelected ? ' checked' : '') + ' /><span>' + self.escapeHtml(subEligibleRoles[roleKey]) + '</span></label>';
						}
					}
				} else {
					html += '<p class="wpps-hide-rules-no-roles">No roles eligible for this submenu item.</p>';
				}
				html += '</div>';
			}

			html += '<div class="wpps-submenu-hide-rules-users" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">';
			html += '<p class="wpps-hide-rules-users-label">' + self.escapeHtml('Hide for specific user(s):') + '</p>';
			html += '<input type="text" class="wpps-submenu-hide-rules-user-search regular-text" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '" placeholder="' + self.escapeAttr('Search users...') + '" />';
			html += '<div class="wpps-submenu-hide-rules-users-selected" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '">';
			const subHideUsers = subHideRules.users || [];
			const subSeenUids = {};
			subHideUsers.forEach(function(uid) {
				const id = parseInt(uid, 10);
				if (subSeenUids[id]) return;
				subSeenUids[id] = true;
				const su = self.usersMap[id] || self.usersMap[String(id)];
				if (su) {
					html += '<span class="wpps-submenu-hide-rules-user-tag" data-parent-index="' + menuIndex + '" data-sub-path="' + self.escapeAttr(subPath) + '" data-user-id="' + id + '">' + self.escapeHtml(su.display_name || su.user_login || 'User ' + id) + ' <span class="wpps-remove-user">&times;</span></span>';
				}
			});
			html += '</div></div></div>';
			return html;
		},

		stripHtml: function(html) {
			if (!html) {
				return '';
			}
			const tmp = document.createElement('div');
			tmp.textContent = String(html);
			return tmp.textContent || '';
		},

		getParentTitle: function(slug) {
			if (!slug) return '';
			const self = this;
			const item = this.currentMenu.find(function(m) {
				return self.getItemSlug(m) === slug || (m.menu_slug || '') === slug;
			});
			return item ? this.stripHtml(item.title || slug) : '';
		},

		showNotice: function(type, message) {
			const $noticeContainer = $('.wpps-menu-organizer-notice');
			if ($noticeContainer.length === 0) return;

			const noticeClass = type === 'success' ? 'notice notice-success is-dismissible' : 'notice notice-error is-dismissible';
			$noticeContainer.html('<div class="' + noticeClass + '"><p>' + this.escapeHtml(message) + '</p><button type="button" class="notice-dismiss"><span class="screen-reader-text">Dismiss this notice.</span></button></div>');
			$noticeContainer.show();

			setTimeout(function() {
				$noticeContainer.fadeOut();
			}, 10000);
			$(document).off('click', '.wpps-menu-organizer-notice .notice-dismiss').on('click', '.wpps-menu-organizer-notice .notice-dismiss', function() {
				$noticeContainer.fadeOut();
			});
		},

		escapeHtml: function(text) {
			const map = {
				'&': '&amp;',
				'<': '&lt;',
				'>': '&gt;',
				'"': '&quot;',
				"'": '&#039;'
			};
			return text.replace(/[&<>"']/g, function(m) { return map[m]; });
		},

		escapeAttr: function(text) {
			return String(text).replace(/[&<>"']/g, function(m) {
				const map = {
					'&': '&amp;',
					'<': '&lt;',
					'>': '&gt;',
					'"': '&quot;',
					"'": '&#039;'
				};
				return map[m];
			});
		},

		openAddModal: function(type, parentIndex, subPath) {
			type = type || 'menu';
			$('#wpps-add-is-submenu').val(type === 'submenu' ? '1' : '0');
			if (type === 'submenu' && parentIndex !== undefined && parentIndex !== null && parentIndex !== '') {
				$('#wpps-add-parent-index').val(String(parentIndex));
			} else {
				$('#wpps-add-parent-index').val('');
			}
			$('#wpps-add-sub-path').val(subPath !== undefined && subPath !== null ? String(subPath) : '');
			$('#wpps-add-menu-title').val('');
			$('#wpps-add-menu-url').val('');
			$('#wpps-add-menu-icon').val('dashicons-admin-generic');
			$('#wpps-add-menu-roles-all').prop('checked', true);
			$('#wpps-add-menu-roles-specific').prop('checked', false);
			$('#wpps-add-menu-roles-list input[type="checkbox"]').prop('checked', false);
			$('#wpps-add-menu-roles-list').hide();
			$('#wpps-add-menu-open-new-tab').prop('checked', false);
			
			if (type === 'submenu') {
				$('#wpps-add-modal-title').text('Add Submenu Item');
				$('.wpps-add-menu-save').text('Add Submenu Item');
				$('#wpps-add-icon-row').hide();
			} else {
				$('#wpps-add-modal-title').text('Add Menu Item');
				$('.wpps-add-menu-save').text('Add Menu Item');
				$('#wpps-add-icon-row').show();
			}
			
			$('#wpps-add-menu-item-modal').addClass('active').fadeIn(200);
		},

		closeAddModal: function() {
			$('#wpps-add-menu-item-modal').fadeOut(200, function() {
				$(this).removeClass('active');
			});
			$('#wpps-add-menu-item-form')[0].reset();
			$('#wpps-add-menu-roles-list').hide();
			$('#wpps-add-parent-index').data('edit-index', null);
			$('#wpps-add-parent-index').data('edit-parent-index', null);
			$('#wpps-add-parent-index').data('edit-sub-index', null);
			$('#wpps-add-parent-index').data('edit-sub-path', null);
			$('#wpps-add-sub-path').val('');
		},

		saveNewMenuItem: function() {
			const self = this;
			const isSubmenu = $('#wpps-add-is-submenu').val() === '1';
			const parentIndexRaw = $('#wpps-add-parent-index').val();
			const parentIndex = parentIndexRaw === '' || parentIndexRaw === null || parentIndexRaw === undefined
				? NaN
				: parseInt(parentIndexRaw, 10);
			const title = $('#wpps-add-menu-title').val().trim();
			const menuSlug = $('#wpps-add-menu-url').val().trim();
			const icon = isSubmenu ? '' : ($('#wpps-add-menu-icon').val().trim() || 'dashicons-admin-generic');
			const rolesType = $('input[name="wpps-add-menu-roles"]:checked').val();
			const selectedRoles = rolesType === 'specific' ? 
				$('#wpps-add-menu-roles-list input[type="checkbox"]:checked').map(function() { return $(this).val(); }).get() : 
				[];
			const openNewTab = $('#wpps-add-menu-open-new-tab').is(':checked');

			let capability = 'read';

			if (!title || !menuSlug) {
				alert(wppsMenuOrganizer.strings.requiredFields || 'Title and URL/Menu Slug are required.');
				return;
			}

			if (rolesType === 'specific' && selectedRoles.length === 0) {
				alert(wppsMenuOrganizer.strings.selectRole || 'Please select at least one role when "Specific Role(s)" is selected.');
				return;
			}

			const targetUrl = menuSlug.startsWith('http') ? menuSlug : '';

			const editIndex = $('#wpps-add-parent-index').data('edit-index');
			const editParentIndex = $('#wpps-add-parent-index').data('edit-parent-index');
			const editSubIndex = $('#wpps-add-parent-index').data('edit-sub-index');
			const editSubPath = $('#wpps-add-parent-index').data('edit-sub-path');
			const addSubPath = $('#wpps-add-sub-path').val() || '';
			
			const eligibleRoles = {};
			if (rolesType === 'all') {
				if (typeof wppsMenuOrganizerRoles === 'object') {
					for (const roleKey in wppsMenuOrganizerRoles) {
						if (Object.prototype.hasOwnProperty.call(wppsMenuOrganizerRoles, roleKey)) {
							eligibleRoles[roleKey] = wppsMenuOrganizerRoles[roleKey];
						}
					}
				}
			} else if (rolesType === 'specific') {
				selectedRoles.forEach(function(roleKey) {
					if (wppsMenuOrganizerRoles && wppsMenuOrganizerRoles[roleKey]) {
						eligibleRoles[roleKey] = wppsMenuOrganizerRoles[roleKey];
					}
				});
			}

			const resolvedSlug = this.resolveCustomMenuSlug(menuSlug, targetUrl);

			if (editIndex !== undefined && editIndex !== null && this.currentMenu[editIndex] && this.currentMenu[editIndex].is_custom) {
				const item = this.currentMenu[editIndex];
				item.title = title;
				item.menu_slug = resolvedSlug;
				item.icon = icon;
				item.url = targetUrl;
				item.open_new_tab = openNewTab;
				item.eligible_roles = eligibleRoles;
				item.capability = capability;
				
				$('#wpps-add-parent-index').data('edit-index', null);
				this.closeAddModal();
				this.saveMenu();
				return;
			}

			const editPath = editSubPath || (editSubIndex !== undefined && editSubIndex !== null ? String(editSubIndex) : '');
			const editSubItem = isSubmenu && editPath ? this.getSubmenuItemByPath(editParentIndex, editPath) : null;
			if (editParentIndex !== undefined && editParentIndex !== null && editPath && editSubItem && editSubItem.is_custom) {
				const subItem = editSubItem;
				subItem.title = title;
				subItem.menu_slug = resolvedSlug;
				subItem.url = targetUrl;
				subItem.open_new_tab = openNewTab;
				subItem.eligible_roles = eligibleRoles;
				subItem.capability = capability;
				
				$('#wpps-add-parent-index').data('edit-parent-index', null);
				$('#wpps-add-parent-index').data('edit-sub-index', null);
				$('#wpps-add-parent-index').data('edit-sub-path', null);
				this.closeAddModal();
				this.saveMenu();
				return;
			}

			if (this.slugExistsInMenu(resolvedSlug, {
				editIndex: editIndex,
				editParentIndex: editParentIndex,
				editSubPath: editPath,
				isSubmenu: isSubmenu,
				parentIndex: parentIndex
			})) {
				alert(wppsMenuOrganizer.strings.duplicateSlug || 'A menu item with this slug already exists. Please use a unique slug.');
				return;
			}

			if (isSubmenu && parentIndexRaw !== '' && !isNaN(parentIndex) && this.currentMenu[parentIndex]) {
				const targetItems = this.getSubmenuItemsArray(parentIndex, addSubPath);
				if (!targetItems) {
					alert(wppsMenuOrganizer.strings.error || 'Could not add submenu item.');
					return;
				}

				const newSubItem = {
					title: title,
					menu_slug: resolvedSlug,
					icon: '',
					capability: capability,
					url: targetUrl,
					open_new_tab: openNewTab,
					page_title: title,
					hidden: false,
					is_custom: true,
					submenu: [],
					hide_rules: { type: 'all', roles: [], users: [], mode: 'toggle' },
					eligible_roles: eligibleRoles
				};

				targetItems.push(newSubItem);
				if (addSubPath === '') {
					const order = this.getChildOrderForParent(parentIndex);
					if (resolvedSlug && order.indexOf(resolvedSlug) === -1) {
						order.push(resolvedSlug);
						this.setChildOrderForParent(parentIndex, order);
					}
				}
				this.closeAddModal();
				this.renderMenu();
				self.showNotice('success', 'Submenu item added. Click Save Changes to update the admin menu.');
			} else {
				const newItem = {
					menu_key: 'custom_' + Date.now(),
					title: title,
					menu_slug: resolvedSlug,
					icon: icon,
					capability: capability,
					url: targetUrl,
					open_new_tab: openNewTab,
					page_title: title,
					position: this.currentMenu.length,
					parent_slug: '',
					hidden: false,
					is_separator: false,
					is_custom: true,
					submenu: [],
					hide_rules: { type: 'all', roles: [], users: [], mode: 'toggle' },
					eligible_roles: eligibleRoles
				};

				this.currentMenu.push(newItem);
				this.closeAddModal();
				this.renderMenu();
				self.showNotice('success', 'Menu item added. Click Save Changes to update the admin menu.');
			}
		},

		slugExistsInMenu: function(resolvedSlug, options) {
			options = options || {};
			const needle = (resolvedSlug || '').trim().toLowerCase();
			if (!needle) {
				return false;
			}

			let found = false;
			const self = this;
			this.walkAllSubmenuItems(function(sub, menuIndex, subPath) {
				if (found) {
					return;
				}
				if (options.editParentIndex !== undefined && options.editParentIndex !== null && menuIndex === options.editParentIndex && options.editSubPath === subPath) {
					return;
				}
				if (self.getItemSlug(sub).toLowerCase() === needle) {
					found = true;
				}
			});

			if (found) {
				return true;
			}

			return this.currentMenu.some(function(item, idx) {
				if (options.editIndex !== undefined && options.editIndex !== null && idx === options.editIndex) {
					return false;
				}
				return self.getItemSlug(item).toLowerCase() === needle;
			});
		},

		openEditCustomModal: function(index) {
			const item = this.currentMenu[index];
			if (!item || !item.is_custom) {
				return;
			}

			$('#wpps-add-parent-index').data('edit-index', index);

			$('#wpps-add-is-submenu').val('0');
			$('#wpps-add-menu-title').val(item.title || '');
			$('#wpps-add-menu-url').val(item.url || item.menu_slug || '');
			$('#wpps-add-menu-icon').val(item.icon || 'dashicons-admin-generic');
			
			const eligibleRoles = item.eligible_roles || {};
			const allRoles = wppsMenuOrganizerRoles || {};
			const hasAllRoles = Object.keys(eligibleRoles).length === Object.keys(allRoles).length;
			
			if (hasAllRoles) {
				$('#wpps-add-menu-roles-all').prop('checked', true);
				$('#wpps-add-menu-roles-specific').prop('checked', false);
				$('#wpps-add-menu-roles-list').hide();
			} else {
				$('#wpps-add-menu-roles-all').prop('checked', false);
				$('#wpps-add-menu-roles-specific').prop('checked', true);
				$('#wpps-add-menu-roles-list input[type="checkbox"]').prop('checked', false);
				for (const roleKey in eligibleRoles) {
					$('#wpps-add-menu-role-' + this.escapeAttr(roleKey)).prop('checked', true);
				}
				$('#wpps-add-menu-roles-list').show();
			}

			$('#wpps-add-menu-open-new-tab').prop('checked', item.open_new_tab || false);

			$('#wpps-add-modal-title').text('Edit Menu Item');
			$('.wpps-add-menu-save').text('Save Changes');
			$('#wpps-add-icon-row').show();

			$('#wpps-add-menu-item-modal').addClass('active').fadeIn(200);
		},

		deleteCustomItem: function(index) {
			if (this.currentMenu[index] && (this.currentMenu[index].is_custom || this.currentMenu[index].is_separator)) {
				this.removeSlugFromAllChildOrders(this.getItemSlug(this.currentMenu[index]));
				this.currentMenu.splice(index, 1);
				this.renderMenu();
				this.saveMenu();
			}
		},

		openEditCustomSubModal: function(parentIndex, subPath) {
			const subItem = this.getSubmenuItemByPath(parentIndex, subPath);
			if (!subItem || !subItem.is_custom) {
				return;
			}

			$('#wpps-add-parent-index').data('edit-parent-index', parentIndex);
			$('#wpps-add-parent-index').data('edit-sub-path', subPath);

			$('#wpps-add-is-submenu').val('1');
			$('#wpps-add-parent-index').val(parentIndex);
			$('#wpps-add-menu-title').val(subItem.title || '');
			$('#wpps-add-menu-url').val(subItem.url || subItem.menu_slug || '');
			
			const eligibleRoles = subItem.eligible_roles || {};
			const allRoles = wppsMenuOrganizerRoles || {};
			const hasAllRoles = Object.keys(eligibleRoles).length === Object.keys(allRoles).length;
			
			if (hasAllRoles) {
				$('#wpps-add-menu-roles-all').prop('checked', true);
				$('#wpps-add-menu-roles-specific').prop('checked', false);
				$('#wpps-add-menu-roles-list').hide();
			} else {
				$('#wpps-add-menu-roles-all').prop('checked', false);
				$('#wpps-add-menu-roles-specific').prop('checked', true);
				$('#wpps-add-menu-roles-list input[type="checkbox"]').prop('checked', false);
				for (const roleKey in eligibleRoles) {
					$('#wpps-add-menu-role-' + this.escapeAttr(roleKey)).prop('checked', true);
				}
				$('#wpps-add-menu-roles-list').show();
			}

			$('#wpps-add-menu-open-new-tab').prop('checked', subItem.open_new_tab || false);

			$('#wpps-add-modal-title').text('Edit Submenu Item');
			$('.wpps-add-menu-save').text('Save Changes');
			$('#wpps-add-icon-row').hide();

			$('#wpps-add-menu-item-modal').addClass('active').fadeIn(200);
		},

		deleteCustomSubItem: function(parentIndex, subPath) {
			const removed = this.spliceSubmenuItemByPath(parentIndex, subPath);
			if (removed && removed.is_custom) {
				this.removeSlugFromAllChildOrders(this.getItemSlug(removed));
				this.renderMenu();
				this.saveMenu();
			}
		},

		addSeparator: function() {
			const separatorSlug = 'separator-' + Date.now();
			
			// Build eligible roles - all roles for separators
			const eligibleRoles = {};
			if (typeof wppsMenuOrganizerRoles === 'object') {
				for (const roleKey in wppsMenuOrganizerRoles) {
					if (Object.prototype.hasOwnProperty.call(wppsMenuOrganizerRoles, roleKey)) {
						eligibleRoles[roleKey] = wppsMenuOrganizerRoles[roleKey];
					}
				}
			}
			
			const newSeparator = {
				menu_key: 'separator_' + Date.now(),
				title: 'Separator',
				menu_slug: separatorSlug,
				icon: '',
				capability: 'read',
				page_title: '',
				position: this.currentMenu.length,
				parent_slug: '',
				hidden: false,
				is_separator: true,
				is_custom: false,
				submenu: [],
				hide_rules: { type: 'all', roles: [], users: [], mode: 'toggle' },
				eligible_roles: eligibleRoles
			};

			this.currentMenu.push(newSeparator);
			// Keep local until the user clicks Save Changes (avoid full page reload).
			this.renderMenu();
		}
	};

	$(document).ready(function() {
		MenuOrganizer.init();
	});

})(jQuery);
