/**
 * AIEO DMM — shared product / variation picker.
 *
 * ONE implementation for every "product-based criteria" field across the DMM
 * admin (discounts, gifts, free-shipping, feeds, …). A hidden
 * `<select multiple class="aieo-prodpick-store" name="foo[]">` is the source of
 * truth (serialised on form submit); chips display it; a single shared modal
 * edits it. Each <option> carries data-text/type/status/parent so chips style
 * drafts/deleted (grey) + variations (badged) and a picked variation
 * round-trips as its own id.
 *
 * Public API (window.aieoProdPicker):
 *   - mount(rootEl)              — (re)scan rootEl for .aieo-prodpick wrappers
 *                                  (idempotent; safe after cloning rule rows).
 *   - hydrate(scope, field, pairs) — fill one picker from server-resolved pairs
 *                                  ([{id,text,type,status,parent_id}]); field=null
 *                                  + [] empties it (used for form reset).
 *
 * Open + chip-remove are DELEGATED at document level so cloned/late wrappers
 * work without re-binding. The modal + injected CSS are global singletons.
 */
(function () {
	'use strict';

	/* -------- i18n (from window.aieoDmm.i18n.picker, English fallbacks) ---- */
	function dict() { var c = window.aieoDmm || {}; return (c.i18n && c.i18n.picker) || {}; }
	function t(k, d) { var v = dict()[k]; return (v === undefined || v === null) ? d : v; }
	var T = {
		get deleted()    { return t('deleted', 'deleted'); },
		get draft()      { return t('draft', 'draft'); },
		get variations() { return t('variations', 'variations'); },
		get searching()  { return t('searching', 'Searching…'); },
		get none()       { return t('none', 'No products found.'); },
		get failed()     { return t('failed', 'Search failed.'); },
		get loadingV()   { return t('loadingV', 'Loading variations…'); },
		get noV()        { return t('noV', 'No variations.'); },
		get failV()      { return t('failV', 'Failed to load variations.'); },
		get cancel()     { return t('cancel', 'Cancel'); },
		get done()       { return t('done', 'Done'); },
		get ph()         { return t('ph', 'Search products by name or SKU…'); },
		get selOne()     { return t('selOne', 'item selected'); },
		get selMany()    { return t('selMany', 'items selected'); },
		get titleInc()   { return t('titleInc', 'Choose products to INCLUDE'); },
		get titleExc()   { return t('titleExc', 'Choose products to EXCLUDE'); },
		get remove()     { return t('remove', 'Remove'); }
	};

	/* -------- helpers ----------------------------------------------------- */
	// Build an admin-ajax URL, reading window.aieoDmm LAZILY at call time —
	// aieoDmm is localized in the footer, so capturing the nonce at parse time
	// would freeze it empty and every search would fail the nonce check.
	function ajaxUrl(query) {
		var c = window.aieoDmm || {};
		var ajax = c.ajaxurl || window.ajaxurl || '/wp-admin/admin-ajax.php';
		var nonce = c.nonce || '';
		return ajax + '?' + query + '&nonce=' + encodeURIComponent(nonce);
	}
	function searchAction(wrap)     { return (wrap && wrap.getAttribute('data-search-action'))     || 'aieo_dmm_product_search'; }
	function variationsAction(wrap) { return (wrap && wrap.getAttribute('data-variations-action')) || 'aieo_dmm_product_variations'; }
	function pEsc(s) { return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }
	function isGrey(st) { return st === 'draft' || st === 'private' || st === 'pending' || st === 'missing'; }

	/* -------- CSS (injected once) ----------------------------------------- */
	(function injectCss() {
		if (document.getElementById('aieo-prodpick-css')) { return; }
		var css =
			'.aieo-prodpick-rule{display:flex;flex-direction:column;gap:4px;margin:0 0 12px;}' +
			'.aieo-prodpick-rule>.aieo-prodpick-label{font-weight:600;margin-bottom:0;}' +
			'.aieo-prodpick-chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 4px;max-height:230px;overflow:auto;align-content:flex-start;}' +
			'.aieo-prodpick-chips .aieo-chip{display:inline-flex;align-items:center;gap:6px;background:#e7156b;color:#fff;border-radius:14px;padding:3px 10px;font-size:12px;line-height:1.5;max-width:100%;}' +
			'.aieo-prodpick-chips .aieo-chip.is-grey{background:#dcdcde;color:#50575e;}' +
			'.aieo-prodpick-chips .aieo-chip.is-var{background:#2271b1;}' +
			'.aieo-prodpick-chips .aieo-chip.is-var.is-grey{background:#c7d2da;color:#3c434a;}' +
			'.aieo-prodpick-chips .aieo-chip-x{cursor:pointer;font-weight:700;opacity:.85;}' +
			'.aieo-prodpick-chips .aieo-chip-x:hover{opacity:1;}' +
			'.aieo-prodpick-chips .aieo-chip-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:340px;}' +
			'.aieo-prodpick-empty{color:#787c82;font-size:12px;font-style:italic;}' +
			'.aieo-pm-overlay{position:fixed;inset:0;z-index:100000;background:rgba(15,23,42,.55);display:flex;align-items:center;justify-content:center;padding:16px;}' +
			'.aieo-pm-card{background:#fff;border-radius:10px;box-shadow:0 24px 48px rgba(0,0,0,.25);width:min(660px,100%);height:min(86vh,760px);display:flex;flex-direction:column;overflow:hidden;}' +
			'.aieo-pm-head{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid #e5e7eb;}' +
			'.aieo-pm-head h3{margin:0;font-size:15px;}' +
			'.aieo-pm-close{cursor:pointer;border:0;background:none;font-size:22px;line-height:1;color:#6b7280;}' +
			'.aieo-pm-search{padding:10px 18px;border-bottom:1px solid #f0f0f1;}' +
			'.aieo-pm-search input{width:100%;}' +
			'.aieo-pm-results{overflow:auto;padding:4px 8px;flex:1;min-height:180px;}' +
			'.aieo-pm-row{border-bottom:1px solid #f3f4f5;}' +
			'.aieo-pm-line{display:flex;align-items:center;gap:8px;padding:7px 4px;}' +
			'.aieo-pm-line label{display:flex;align-items:center;gap:8px;margin:0;flex:1;cursor:pointer;}' +
			'.aieo-pm-row.is-grey>.aieo-pm-line label>span:first-of-type{color:#787c82;}' +
			'.aieo-pm-caret{cursor:pointer;width:18px;text-align:center;color:#2271b1;user-select:none;font-size:11px;}' +
			'.aieo-pm-caret.is-spacer{visibility:hidden;cursor:default;}' +
			'.aieo-pm-badge{font-size:10px;text-transform:uppercase;letter-spacing:.03em;border-radius:8px;padding:1px 6px;background:#eef1f4;color:#50575e;white-space:nowrap;}' +
			'.aieo-pm-badge.var{background:#dbeafe;color:#1e40af;}' +
			'.aieo-pm-badge.draft{background:#fef3c7;color:#92400e;}' +
			'.aieo-pm-vars{padding:0 8px 8px 36px;}' +
			'.aieo-pm-vrow{display:flex;align-items:center;gap:8px;padding:5px 4px;}' +
			'.aieo-pm-vrow label{display:flex;align-items:center;gap:8px;margin:0;cursor:pointer;}' +
			'.aieo-pm-foot{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:12px 18px;border-top:1px solid #e5e7eb;background:#f9fafb;}' +
			'.aieo-pm-count{font-size:12px;color:#50575e;}' +
			'.aieo-pm-muted{color:#787c82;font-size:12px;padding:16px 10px;}';
		var st = document.createElement('style');
		st.id = 'aieo-prodpick-css';
		st.textContent = css;
		document.head.appendChild(st);
	})();

	/* -------- store + chips ----------------------------------------------- */
	function storeEl(wrap) { return wrap.querySelector('select.aieo-prodpick-store'); }
	function chipsEl(wrap) { return wrap.querySelector('.aieo-prodpick-chips'); }

	function storeItems(wrap) {
		var sel = storeEl(wrap), out = [];
		if (!sel) { return out; }
		Array.prototype.forEach.call(sel.options, function (o) {
			var id = parseInt(o.value, 10);
			if (!id) { return; }
			out.push({
				id: id,
				text: o.getAttribute('data-text') || o.textContent || ('#' + id),
				type: o.getAttribute('data-type') || 'simple',
				status: o.getAttribute('data-status') || 'publish',
				parent_id: parseInt(o.getAttribute('data-parent') || '0', 10) || 0
			});
		});
		return out;
	}
	function storeSet(wrap, items) {
		var sel = storeEl(wrap);
		if (!sel) { return; }
		sel.innerHTML = '';
		(items || []).forEach(function (it) {
			var id = parseInt(it.id, 10);
			if (!id) { return; }
			var o = document.createElement('option');
			o.value = String(id);
			o.selected = true;
			o.textContent = it.text || ('#' + id);
			o.setAttribute('data-text', it.text || ('#' + id));
			o.setAttribute('data-type', it.type || 'simple');
			o.setAttribute('data-status', it.status || 'publish');
			if (it.parent_id) { o.setAttribute('data-parent', String(it.parent_id)); }
			sel.appendChild(o);
		});
		renderChips(wrap);
	}
	function renderChips(wrap) {
		var box = chipsEl(wrap);
		if (!box) { return; }
		var items = storeItems(wrap);
		box.innerHTML = '';
		if (!items.length) {
			box.innerHTML = '<span class="aieo-prodpick-empty">' + pEsc(box.getAttribute('data-empty') || '') + '</span>';
			return;
		}
		items.sort(function (a, b) { return a.id - b.id; });
		items.forEach(function (it) {
			var grey = isGrey(it.status);
			var suffix = (it.status === 'missing') ? (' (' + T.deleted + ')')
				: (it.status === 'draft') ? (' · ' + T.draft) : '';
			var chip = document.createElement('span');
			chip.className = 'aieo-chip' + (it.type === 'variation' ? ' is-var' : '') + (grey ? ' is-grey' : '');
			chip.innerHTML = '<span class="aieo-chip-t" title="' + pEsc(it.text + suffix) + '">' + pEsc(it.text + suffix) + '</span>' +
				'<span class="aieo-chip-x" data-id="' + it.id + '" title="' + pEsc(T.remove) + '">×</span>';
			box.appendChild(chip);
		});
	}

	/* -------- modal (shared singleton) ------------------------------------ */
	var pmEl = null;
	var pmState = { wrap: null, sel: {} };

	function pmBuild() {
		if (pmEl) { return pmEl; }
		var ov = document.createElement('div');
		ov.className = 'aieo-pm-overlay';
		ov.style.display = 'none';
		ov.innerHTML =
			'<div class="aieo-pm-card" role="dialog" aria-modal="true">' +
			'<div class="aieo-pm-head"><h3></h3><button type="button" class="aieo-pm-close" aria-label="Close">×</button></div>' +
			'<div class="aieo-pm-search"><input type="search" class="aieo-pm-q"></div>' +
			'<div class="aieo-pm-results"></div>' +
			'<div class="aieo-pm-foot"><span class="aieo-pm-count"></span><span><button type="button" class="button aieo-pm-cancel"></button> <button type="button" class="button button-primary aieo-pm-done"></button></span></div>' +
			'</div>';
		document.body.appendChild(ov);
		pmEl = ov;
		ov.querySelector('.aieo-pm-close').addEventListener('click', pmClose);
		ov.querySelector('.aieo-pm-cancel').addEventListener('click', pmClose);
		ov.addEventListener('click', function (e) { if (e.target === ov) { pmClose(); } });
		ov.querySelector('.aieo-pm-done').addEventListener('click', pmCommit);
		var q = ov.querySelector('.aieo-pm-q');
		var timer;
		q.addEventListener('input', function () { clearTimeout(timer); timer = setTimeout(function () { pmSearch(q.value); }, 250); });
		var res = ov.querySelector('.aieo-pm-results');
		res.addEventListener('click', pmOnClick);
		res.addEventListener('change', pmOnChange);
		return ov;
	}
	function pmOpen(wrap) {
		pmBuild();
		pmState.wrap = wrap;
		pmState.sel = {};
		storeItems(wrap).forEach(function (it) { pmState.sel[it.id] = it; });
		var isExc = wrap.getAttribute('data-mode') === 'exclude' || wrap.getAttribute('data-field') === 'exclude_ids';
		pmEl.querySelector('.aieo-pm-head h3').textContent = isExc ? T.titleExc : T.titleInc;
		pmEl.querySelector('.aieo-pm-cancel').textContent = T.cancel;
		pmEl.querySelector('.aieo-pm-done').textContent = T.done;
		pmEl.querySelector('.aieo-pm-q').setAttribute('placeholder', T.ph);
		pmEl.querySelector('.aieo-pm-q').value = '';
		pmCount();
		pmEl.style.display = 'flex';
		document.addEventListener('keydown', pmKey);
		pmSearch('');
		setTimeout(function () { pmEl.querySelector('.aieo-pm-q').focus(); }, 30);
	}
	function pmClose() { if (pmEl) { pmEl.style.display = 'none'; document.removeEventListener('keydown', pmKey); } }
	function pmKey(e) { if (e.key === 'Escape') { pmClose(); } }
	function pmCommit() {
		if (pmState.wrap) {
			var items = Object.keys(pmState.sel).map(function (k) { return pmState.sel[k]; });
			storeSet(pmState.wrap, items);
		}
		pmClose();
	}
	function pmCount() {
		var n = Object.keys(pmState.sel).length;
		pmEl.querySelector('.aieo-pm-count').textContent = n + ' ' + (n === 1 ? T.selOne : T.selMany);
	}
	function pmSearch(q) {
		var box = pmEl.querySelector('.aieo-pm-results');
		box.innerHTML = '<div class="aieo-pm-muted">' + T.searching + '</div>';
		var url = ajaxUrl('action=' + searchAction(pmState.wrap) + '&q=' + encodeURIComponent(q || ''));
		fetch(url, { credentials: 'same-origin' }).then(function (r) { return r.json(); }).then(function (j) {
			var rows = (j && j.results) ? j.results : [];
			box.innerHTML = '';
			if (!rows.length) { box.innerHTML = '<div class="aieo-pm-muted">' + T.none + '</div>'; return; }
			rows.forEach(function (r) { box.appendChild(pmRow(r)); });
		}).catch(function () { box.innerHTML = '<div class="aieo-pm-muted">' + T.failed + '</div>'; });
	}
	function pmRow(r) {
		var grey = isGrey(r.status);
		var row = document.createElement('div');
		row.className = 'aieo-pm-row' + (grey ? ' is-grey' : '');
		row.setAttribute('data-id', r.id);
		row.setAttribute('data-type', r.type);
		row.setAttribute('data-status', r.status);
		row.setAttribute('data-text', r.text);
		row.setAttribute('data-name', r.name || r.text);
		var caret = (r.type === 'variable' && r.n_variations > 0)
			? '<span class="aieo-pm-caret" data-act="expand">&#9654;</span>'
			: '<span class="aieo-pm-caret is-spacer">&middot;</span>';
		var badge = '';
		if (r.type === 'variable') { badge += '<span class="aieo-pm-badge var">' + parseInt(r.n_variations, 10) + ' ' + T.variations + '</span>'; }
		if (r.status === 'draft') { badge += '<span class="aieo-pm-badge draft">' + T.draft + '</span>'; }
		row.innerHTML =
			'<div class="aieo-pm-line">' + caret +
			'<label><input type="checkbox" class="aieo-pm-cb"><span>' + pEsc(r.text) + '</span>' + badge + '</label>' +
			'</div><div class="aieo-pm-vars" hidden></div>';
		row.querySelector('.aieo-pm-cb').checked = !!pmState.sel[r.id];
		return row;
	}
	function pmOnClick(e) {
		var caret = e.target.closest('.aieo-pm-caret[data-act="expand"]');
		if (!caret) { return; }
		var row = caret.closest('.aieo-pm-row');
		var box = row.querySelector('.aieo-pm-vars');
		if (!box.hasAttribute('hidden')) { box.setAttribute('hidden', ''); caret.innerHTML = '&#9654;'; return; }
		caret.innerHTML = '&#9660;';
		box.removeAttribute('hidden');
		if (box.getAttribute('data-loaded')) { return; }
		box.innerHTML = '<div class="aieo-pm-muted">' + T.loadingV + '</div>';
		var pid = row.getAttribute('data-id');
		var pName = row.getAttribute('data-name') || (row.getAttribute('data-text') || '').replace(/\s*\[[^\]]*\]\s*$/, '');
		var pStatus = row.getAttribute('data-status');
		var url = ajaxUrl('action=' + variationsAction(pmState.wrap) + '&parent_id=' + encodeURIComponent(pid));
		fetch(url, { credentials: 'same-origin' }).then(function (r) { return r.json(); }).then(function (j) {
			var vs = (j && j.results) ? j.results : [];
			box.setAttribute('data-loaded', '1');
			box.innerHTML = '';
			if (!vs.length) { box.innerHTML = '<div class="aieo-pm-muted">' + T.noV + '</div>'; return; }
			vs.forEach(function (v) {
				var vrow = document.createElement('div');
				vrow.className = 'aieo-pm-vrow';
				vrow.setAttribute('data-id', v.id);
				vrow.setAttribute('data-text', pName + ' — ' + v.text);
				vrow.setAttribute('data-parent', pid);
				vrow.setAttribute('data-status', pStatus);
				vrow.innerHTML = '<label><input type="checkbox" class="aieo-pm-vcb"><span>' + pEsc(v.text) + '</span></label>';
				vrow.querySelector('.aieo-pm-vcb').checked = !!pmState.sel[v.id];
				box.appendChild(vrow);
			});
		}).catch(function () { box.innerHTML = '<div class="aieo-pm-muted">' + T.failV + '</div>'; });
	}
	function pmOnChange(e) {
		var cb = e.target;
		if (cb.classList.contains('aieo-pm-cb')) {
			var row = cb.closest('.aieo-pm-row');
			var id = parseInt(row.getAttribute('data-id'), 10);
			if (cb.checked) { pmState.sel[id] = { id: id, text: row.getAttribute('data-text'), type: row.getAttribute('data-type'), status: row.getAttribute('data-status'), parent_id: 0 }; }
			else { delete pmState.sel[id]; }
			pmCount();
		} else if (cb.classList.contains('aieo-pm-vcb')) {
			var vrow = cb.closest('.aieo-pm-vrow');
			var vid = parseInt(vrow.getAttribute('data-id'), 10);
			if (cb.checked) { pmState.sel[vid] = { id: vid, text: vrow.getAttribute('data-text'), type: 'variation', status: vrow.getAttribute('data-status'), parent_id: parseInt(vrow.getAttribute('data-parent'), 10) || 0 }; }
			else { delete pmState.sel[vid]; }
			pmCount();
		}
	}

	/* -------- mount + public API ------------------------------------------ */
	function mountOne(wrap) {
		if (!wrap) { return; }
		// Always (re)render chips so server-pre-rendered <option>s show on load
		// and cloned rows refresh; guard only the one-time marker.
		renderChips(wrap);
		wrap.setAttribute('data-pp-mounted', '1');
	}
	function mount(root) {
		root = root || document;
		if (root.classList && root.classList.contains('aieo-prodpick')) { mountOne(root); }
		var wraps = root.querySelectorAll ? root.querySelectorAll('.aieo-prodpick') : [];
		Array.prototype.forEach.call(wraps, mountOne);
	}
	function hydrate(scope, fieldKey, pairs) {
		var wrap = null;
		if (scope && scope.classList && scope.classList.contains('aieo-prodpick')) {
			wrap = scope;
		} else if (scope && scope.querySelector) {
			wrap = fieldKey ? scope.querySelector('.aieo-prodpick[data-field="' + fieldKey + '"]') : scope.querySelector('.aieo-prodpick');
		}
		if (!wrap) { return; }
		storeSet(wrap, (pairs || []).map(function (p) {
			return { id: parseInt(p.id, 10), text: p.text, type: p.type || 'simple', status: p.status || 'publish', parent_id: parseInt(p.parent_id || 0, 10) || 0 };
		}).filter(function (p) { return p.id; }));
	}

	// Delegated open + chip-remove — works for any wrapper, including cloned
	// rows that were never explicitly mounted.
	document.addEventListener('click', function (e) {
		var open = e.target.closest && e.target.closest('.aieo-prodpick-open');
		if (open) { var w = open.closest('.aieo-prodpick'); if (w) { pmOpen(w); } return; }
		var x = e.target.closest && e.target.closest('.aieo-prodpick-chips .aieo-chip-x');
		if (x) {
			var wrap = x.closest('.aieo-prodpick');
			var id = parseInt(x.getAttribute('data-id'), 10);
			if (wrap) { storeSet(wrap, storeItems(wrap).filter(function (it) { return it.id !== id; })); }
		}
	});

	window.aieoProdPicker = { mount: mount, hydrate: hydrate };

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