(() => {
    'use strict';

    window.FotogenicAI = window.FotogenicAI || {};
    const Studio = window.FotogenicAI.Studio = window.FotogenicAI.Studio || {};
	const Shared = window.FotogenicAI.Shared = window.FotogenicAI.Shared || {};
    const { __, _n, sprintf } = Studio.i18n;

	const pageSize = (route) => {
		return ['product', 'media'].includes(route?.sourceType) ? 24 : 12;
	};
	const supportsVariationSelection = (route) => (
		(
			['product_images', 'campaign_set', 'increase_resolution'].includes(route?.workflow)
		)
		&& route?.sourceType === 'product'
	);
	const SEARCH_DELAY = 250;
	const PRODUCT_SEARCH_MIN_LENGTH = 2;
	const PRODUCT_SEARCH_RESULT_LIMIT = 8;
	const UUID_V4_PATTERN = /^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/i;
	const CAMPAIGN_IDENTITY_ERROR = __( 'This browser cannot create a secure Campaign identity. Use a current browser or enable Web Crypto, then reload Studio. No selection was changed.', 'fotogenic-ai' );
	const CAMPAIGN_SOURCE_ERROR = __( 'Studio could not prepare this Campaign source. Reload Studio to refresh its exact image data. No selection was changed.', 'fotogenic-ai' );
	const MEDIA_FILTER_DEFAULTS = Object.freeze({
		type: 'all',
		date: 'all',
		orientation: 'all',
		size: 'all',
	});
    const { element, requestState } = Studio.viewModel;
	const icons = Shared.ui?.icon;
	if (!icons?.create) throw new Error('Fotogenic AI: icon.js must load before source-picker.js');
	const createIcon = icons.create;
	const createSelectShell = (control, className = 'fotogenic-ai-select-control-shell') => {
		const shell = element('span', className);
		const caret = createIcon('caret-down', { weight: 'bold', size: 14 });
		caret.classList.add('fotogenic-ai-select-control-caret');
		shell.append(control, caret);
		return shell;
	};
	let checkboxFilterSequence = 0;
	const createCheckboxFilterPopover = ({
		label,
		allLabel,
		multipleLabel,
		options = [],
		selectedValues = [],
		allSelected: initialAllSelected = false,
		onSelectionChange,
		onBrowse,
	} = {}) => {
		const filterId = `fotogenic-ai-product-filter-${++checkboxFilterSequence}`;
		const root = element('div', 'fotogenic-ai-product-filter-popover');
		const trigger = element('button', 'fotogenic-ai-product-filter-popover__trigger');
		const triggerLabel = element('span');
		const panel = element('div', 'fotogenic-ai-product-filter-popover__panel');
		const group = element('div', 'fotogenic-ai-product-filter-popover__options');
		let availableOptions = [];
		let selected = new Set((Array.isArray(selectedValues) ? selectedValues : []).map(String).filter(Boolean));
		let allSelected = Boolean(initialAllSelected);
		let open = false;

		trigger.type = 'button';
		trigger.setAttribute('aria-haspopup', 'dialog');
		trigger.setAttribute('aria-expanded', 'false');
		trigger.setAttribute('aria-controls', filterId);
		trigger.append(triggerLabel, createIcon('caret-down', { weight: 'bold', size: 14 }));
		panel.id = filterId;
		panel.hidden = true;
		panel.setAttribute('role', 'dialog');
		panel.setAttribute('aria-label', label);
		group.setAttribute('role', 'group');
		group.setAttribute('aria-label', label);
		panel.appendChild(group);
		root.append(trigger, panel);

		const visibleLabel = () => {
			if (!selected.size) return allLabel;
			const chosen = availableOptions.filter((option) => selected.has(option.value));
			if (chosen.length === 1) return chosen[0].label;
			return typeof multipleLabel === 'function' ? multipleLabel(chosen.length) : `${chosen.length} ${label}`;
		};
		const close = ({ restoreFocus = false } = {}) => {
			if (!open) return;
			open = false;
			panel.hidden = true;
			trigger.setAttribute('aria-expanded', 'false');
			root.classList.remove('is-open');
			if (restoreFocus) trigger.focus({ preventScroll: true });
		};
		const emitSelection = (detail) => {
			triggerLabel.textContent = visibleLabel();
			onSelectionChange?.([...selected], detail);
		};
		const render = () => {
			group.replaceChildren();
			const renderOption = ({ value, label: optionLabel, all = false }) => {
				const option = element('div', 'fotogenic-ai-product-filter-popover__option');
				const selectionControl = element('label', 'fotogenic-ai-product-filter-popover__selection');
				const checkbox = element('input');
				checkbox.type = 'checkbox';
				checkbox.value = value;
				checkbox.checked = all ? allSelected : selected.has(value);
				checkbox.setAttribute('aria-label', sprintf(
					all
						? __( 'Select %s', 'fotogenic-ai' )
						: __( 'Select all products in %s', 'fotogenic-ai' ),
					optionLabel
				));
				checkbox.addEventListener('change', () => {
					if (all) {
						selected.clear();
						allSelected = checkbox.checked;
					} else {
						allSelected = false;
						if (checkbox.checked) selected.add(value);
						else selected.delete(value);
					}
					const detail = { value, checked: checkbox.checked, all };
					render();
					emitSelection(detail);
				});
				selectionControl.appendChild(checkbox);
				const browse = element('button', 'fotogenic-ai-product-filter-popover__browse', optionLabel);
				browse.type = 'button';
				browse.setAttribute('aria-label', sprintf(__( 'Show %s', 'fotogenic-ai' ), optionLabel));
				browse.addEventListener('click', () => {
					onBrowse?.(value, { all, label: optionLabel });
					close({ restoreFocus: true });
				});
				option.append(selectionControl, browse);
				group.appendChild(option);
			};
			renderOption({ value: '', label: allLabel, all: true });
			availableOptions.forEach(renderOption);
			triggerLabel.textContent = visibleLabel();
		};
		const dismiss = (event) => {
			if (open && !root.contains(event.target)) close();
		};
		const dismissWithEscape = (event) => {
			if (open && event.key === 'Escape') {
				event.preventDefault();
				close({ restoreFocus: true });
			}
		};
		trigger.addEventListener('click', () => {
			open = !open;
			panel.hidden = !open;
			trigger.setAttribute('aria-expanded', open ? 'true' : 'false');
			root.classList.toggle('is-open', open);
			if (open) panel.querySelector('input')?.focus?.();
		});
		document.addEventListener('pointerdown', dismiss);
		document.addEventListener('keydown', dismissWithEscape);
		availableOptions = options.map((option) => ({
			value: String(option?.value ?? ''),
			label: String(option?.label ?? option?.value ?? ''),
		})).filter((option) => option.value && option.label);
		render();

		return {
			root,
			close,
			setDisabled(disabled) { trigger.disabled = Boolean(disabled); },
			setOptions(nextOptions = []) {
				availableOptions = nextOptions.map((option) => ({
					value: String(option?.value ?? ''),
					label: String(option?.label ?? option?.value ?? ''),
				})).filter((option) => option.value && option.label);
				selected = new Set([...selected].filter((value) => availableOptions.some((option) => option.value === value)));
				render();
			},
			setSelected(nextValues = [], { allSelected: nextAllSelected = false } = {}) {
				selected = new Set((Array.isArray(nextValues) ? nextValues : []).map(String).filter(Boolean));
				allSelected = Boolean(nextAllSelected);
				render();
			},
			destroy() {
				document.removeEventListener('pointerdown', dismiss);
				document.removeEventListener('keydown', dismissWithEscape);
			},
		};
	};

    const setFocusKey = (node, key) => {
        if (node && key) {
            node.setAttribute('data-fa-focus-key', String(key));
        }
        return node;
    };

    const activeFocusKey = (root) => {
        const active = document.activeElement;
        return active && root?.contains?.(active) ? String(active.dataset?.faFocusKey || '') : '';
    };

    const restoreFocusKey = (root, key) => {
        if (!root || !key) return false;
        const target = [...root.querySelectorAll('[data-fa-focus-key]')]
            .find((node) => node.dataset?.faFocusKey === key && !node.disabled && !node.hidden);
        if (!target?.focus) return false;
        target.focus({ preventScroll: true });
        return true;
    };

	const handleScrollableResultsKeyDown = (event) => {
		const region = event.currentTarget;
		const pageStep = Math.max(40, Math.floor(region.clientHeight * 0.85));
		const scrollTargets = {
			ArrowDown: region.scrollTop + 40,
			ArrowUp: region.scrollTop - 40,
			PageDown: region.scrollTop + pageStep,
			PageUp: region.scrollTop - pageStep,
			Home: 0,
			End: region.scrollHeight,
		};
		if (!Object.prototype.hasOwnProperty.call(scrollTargets, event.key)) return;
		event.preventDefault();
		region.scrollTo({ top: scrollTargets[event.key] });
	};

    const safeImageUrl = (value) => {
        const raw = String(value || '').trim();
        if (!raw) {
            return '';
        }
        try {
            const url = new URL(raw, window.location?.href || 'http://localhost/');
            return ['http:', 'https:'].includes(url.protocol) ? url.href : '';
        } catch (_) {
            return '';
        }
    };

	const formatBytes = (value) => {
		const bytes = Math.max(0, Math.floor(Number(value)) || 0);
		if (!bytes) return '';
		if (bytes < 1024 * 1024) return sprintf(__( '%d KB', 'fotogenic-ai' ), Math.max(1, Math.round(bytes / 1024)));
		return sprintf(__( '%s MB', 'fotogenic-ai' ), (bytes / (1024 * 1024)).toFixed(1));
	};

	const mimeLabel = (mime) => ({
		'image/jpeg': 'JPG',
		'image/png': 'PNG',
		'image/webp': 'WEBP',
	}[String(mime || '').toLowerCase()] || String(mime || '').replace(/^image\//, '').toUpperCase());

    const normalizeAvailability = (rawAvailability) => {
        if (!rawAvailability || typeof rawAvailability !== 'object') {
            return null;
        }
        const featuredCount = Math.max(0, Math.floor(Number(rawAvailability.featuredCount)) || 0);
        const galleryCount = Math.max(0, Math.floor(Number(rawAvailability.galleryCount)) || 0);
        const totalCount = Math.max(featuredCount + galleryCount, Math.floor(Number(rawAvailability.totalCount)) || 0);
        return { featuredCount, galleryCount, totalCount };
    };

    const normalizeTargetHint = (rawItem, sourceType, id) => {
		const rawTarget = rawItem?.target;
		if (!rawTarget || typeof rawTarget !== 'object' || Array.isArray(rawTarget)) {
			return null;
		}
		if (String(rawTarget.sourceType || '').trim().toLowerCase() !== sourceType) {
			return null;
		}
		const targetType = String(rawTarget.targetType || '').trim().toLowerCase();
		const targetId = Number(rawTarget.targetId);
		const parentProductId = Number(rawTarget.parentProductId);
		const variationId = Number(rawTarget.variationId);
		if (![targetId, parentProductId, variationId].every(Number.isInteger)) {
			return null;
		}
        const validProduct = sourceType === 'product' && (
            (targetType === 'product' && targetId === id && parentProductId === 0 && variationId === 0)
            || (targetType === 'variation' && targetId === id && parentProductId > 0 && variationId === id)
        );
        const validWordPressTarget = ['media', 'post', 'page'].includes(sourceType)
            && targetType === sourceType
            && targetId === id
            && parentProductId === 0
            && variationId === 0;
        return validProduct || validWordPressTarget
            ? { targetType, targetId, parentProductId, variationId }
            : null;
    };

    const normalizeItem = (rawItem, sourceType) => {
        const id = Math.floor(Number(rawItem?.id));
        if (id <= 0) {
            return null;
        }
		const label = String(rawItem?.label || sprintf( __( 'Item %d', 'fotogenic-ai' ), id )).trim() || sprintf( __( 'Item %d', 'fotogenic-ai' ), id );
		const imageUrl = safeImageUrl(rawItem?.imageUrl);
        const target = normalizeTargetHint(rawItem, sourceType, id);
		const eligible = rawItem?.eligible !== false && Boolean(target);
        const eligibilityReason = String(rawItem?.eligibilityReason || '').trim().slice(0, 240);
		const attributes = sourceType === 'product' && Array.isArray(rawItem?.attributes)
			? rawItem.attributes.map((attribute) => ({
				name: String(attribute?.name || '').trim(),
				value: String(attribute?.value || '').trim(),
			})).filter((attribute) => attribute.name && attribute.value)
			: [];
		const attributeDetail = attributes.map((attribute) => attribute.value).join(' · ');
		const detail = attributeDetail
			? attributeDetail
			: (sourceType === 'product' && rawItem?.sku
			? sprintf( __( 'SKU %s', 'fotogenic-ai' ), String(rawItem.sku) )
			: (rawItem?.width && rawItem?.height ? sprintf( __( '%1$d × %2$d', 'fotogenic-ai' ), Number(rawItem.width), Number(rawItem.height) ) : ''));
		const sourceAttachmentId = Math.floor(Number(rawItem?.sourceAttachmentId));
        return {
            id,
            sourceType,
            label,
            imageUrl,
            detail,
            eligible,
            eligibilityReason,
            target,
            sourceAttachmentId: sourceAttachmentId > 0 ? sourceAttachmentId : 0,
            sourceAvailability: sourceType === 'product' ? normalizeAvailability(rawItem?.sourceAvailability) : null,
			hasVariations: sourceType === 'product' && rawItem?.hasVariations === true,
			stockStatus: sourceType === 'product' ? String(rawItem?.stockStatus || '') : '',
			stockQuantity: sourceType === 'product'
				&& rawItem?.stockQuantity !== null
				&& rawItem?.stockQuantity !== ''
				&& Number.isFinite(Number(rawItem?.stockQuantity))
				? Math.max(0, Math.floor(Number(rawItem.stockQuantity)))
				: null,
			sku: sourceType === 'product' ? String(rawItem?.sku || '').trim() : '',
			categories: sourceType === 'product'
				? [...new Set([
					...(Array.isArray(rawItem?.categories) ? rawItem.categories : []),
					...(Array.isArray(rawItem?.categoryAncestors) ? rawItem.categoryAncestors : []),
				]
					.map(Number).filter((value) => Number.isInteger(value) && value > 0))]
				: [],
			categoryNames: sourceType === 'product' && Array.isArray(rawItem?.categoryNames)
				? rawItem.categoryNames.map((value) => String(value || '').trim()).filter(Boolean)
				: [],
			variationCount: sourceType === 'product'
				? Math.max(0, Math.floor(Number(rawItem?.variationCount)) || 0)
				: 0,
			attributes,
			mime: String(rawItem?.mime || '').trim().toLowerCase(),
			bytes: Math.max(0, Math.floor(Number(rawItem?.bytes)) || 0),
			width: Math.max(0, Math.floor(Number(rawItem?.width)) || 0),
			height: Math.max(0, Math.floor(Number(rawItem?.height)) || 0),
			dateAdded: String(rawItem?.dateAdded || '').trim(),
			dateLabel: String(rawItem?.dateLabel || '').trim(),
			orientation: String(rawItem?.orientation || '').trim().toLowerCase(),
			status: String(rawItem?.status || '').trim().toLowerCase(),
			statusLabel: String(rawItem?.statusLabel || rawItem?.status || '').trim(),
			author: String(rawItem?.author || '').trim(),
			authorId: Math.max(0, Math.floor(Number(rawItem?.authorId)) || 0),
        };
    };

    const validateMediaAttachmentSelection = async ({ transport, attachmentIds = [], maximum = 1, signal } = {}) => {
        const limit = Math.max(1, Math.floor(Number(maximum)) || 1);
        const ids = [...new Set((Array.isArray(attachmentIds) ? attachmentIds : [])
            .map((value) => Math.floor(Number(value)))
            .filter((id) => id > 0))];
        if (!ids.length || ids.length > limit) {
            return {
                ok: false,
                message: sprintf(__( 'Select no more than %d images.', 'fotogenic-ai' ), limit),
                items: [],
            };
        }
		if (typeof transport?.getSourceSummary !== 'function') {
			return {
				ok: false,
				message: __( 'The selected images could not be verified. Try again.', 'fotogenic-ai' ),
				items: [],
			};
		}

		const settled = await Promise.allSettled(
			ids.map((attachmentId) => transport.getSourceSummary?.('media', attachmentId, { signal }))
		);
		const responses = settled.map((result) => (result.status === 'fulfilled' ? result.value : null));
		const items = responses.map((response) => (response?.ok ? normalizeItem(response.data, 'media') : null));
		const invalidIndex = items.findIndex((item) => !item?.eligible);
        if (invalidIndex >= 0) {
            return {
                ok: false,
				message: items[invalidIndex]?.eligibilityReason
                    || responses[invalidIndex]?.message
                    || __( 'Choose JPEG, PNG, or WebP images no larger than 25 MiB.', 'fotogenic-ai' ),
                items: [],
            };
        }

		return { ok: true, message: '', items };
    };

    const normalizeProductImages = (context) => {
        const candidates = [
            { ...(context?.images?.featured || {}), role: 'featured', label: __( 'Featured image', 'fotogenic-ai' ) },
            ...(Array.isArray(context?.images?.gallery) ? context.images.gallery : []).map((image, index) => ({
                ...image,
                role: 'gallery',
                label: sprintf( __( 'Gallery image %d', 'fotogenic-ai' ), index + 1 ),
            })),
        ];
        const images = [];
        const seen = new Set();
        candidates.forEach((candidate) => {
            const id = Math.floor(Number(candidate?.attachmentId));
            const imageUrl = safeImageUrl(candidate?.thumbUrl || candidate?.fullUrl);
			if (id > 0 && !seen.has(id)) {
                seen.add(id);
				images.push({
					id,
					imageUrl,
					role: candidate.role,
					label: candidate.label,
					eligible: candidate?.eligible !== false,
					eligibilityReason: String(candidate?.eligibilityReason || '').trim().slice(0, 240),
				});
            }
        });
        return images;
    };

    const sourceEligibleForMode = (item, route, sourceMode) => {
        if (!item.eligible || route.sourceType !== 'product' || route.scope !== 'bulk' || !item.sourceAvailability) {
            return item.eligible;
        }
        if (route.workflow === 'campaign_set') {
            return item.sourceAvailability.totalCount > 0;
        }
        if (sourceMode === 'featured') {
            return item.sourceAvailability.featuredCount > 0;
        }
        if (sourceMode === 'gallery_only') {
            return item.sourceAvailability.galleryCount > 0;
        }
        return item.sourceAvailability.totalCount > 0;
    };

    const normalizeBulkSelection = (selection = {}, maximum = 1) => {
		const limit = Math.max(1, Math.floor(Number(maximum)) || 1);
        const ids = (values) => [...new Set((Array.isArray(values) ? values : [])
            .map(Number)
            .filter((id) => Number.isInteger(id) && id > 0))].slice(0, limit);
        const selectedIds = ids(selection.selectedIds);
        return {
            strategy: selection.strategy === 'query' ? 'query' : 'explicit',
            selectedIds,
            excludedIds: ids(selection.excludedIds).filter((id) => !selectedIds.includes(id)),
            query: selection.query && typeof selection.query === 'object' && !Array.isArray(selection.query)
                ? { ...selection.query }
                : {},
        };
    };

    const selectBulkPage = (selection, pageIds, maximum = 1) => {
        const current = normalizeBulkSelection(selection, maximum);
        const eligible = [...new Set((pageIds || []).map(Number).filter((id) => Number.isInteger(id) && id > 0))];
        if (current.strategy === 'query') {
            return {
                ok: true,
                selection: { ...current, excludedIds: current.excludedIds.filter((id) => !eligible.includes(id)) },
            };
        }
        const selectedIds = [...new Set([...current.selectedIds, ...eligible])];
        return selectedIds.length > maximum
            ? { ok: false, selection: current }
            : { ok: true, selection: { strategy: 'explicit', selectedIds, excludedIds: [], query: {} } };
    };

	const replaceParentWithVariations = ({
		selection = {},
		parentId = 0,
		variationIds = [],
		siblingVariationIds = [],
		maximum = 1,
		restoreParent = false,
	} = {}) => {
		const current = normalizeBulkSelection(selection, maximum);
		const normalizedParentId = Math.floor(Number(parentId));
		const siblings = new Set((Array.isArray(siblingVariationIds) ? siblingVariationIds : [])
			.map(Number).filter((id) => Number.isInteger(id) && id > 0));
		const variations = [...new Set((Array.isArray(variationIds) ? variationIds : [])
			.map(Number).filter((id) => Number.isInteger(id) && id > 0))];
		if (normalizedParentId <= 0) return { ok: false, selection: current, droppedQuerySelection: false };
		const retained = current.selectedIds.filter((id) => id !== normalizedParentId && !siblings.has(id));
		const selectedIds = [...new Set([
			...retained,
			...(variations.length ? variations : (restoreParent ? [normalizedParentId] : [])),
		])];
		if (selectedIds.length > maximum) {
			return { ok: false, selection: current, droppedQuerySelection: false };
		}
		return {
			ok: true,
			selection: { strategy: 'explicit', selectedIds, excludedIds: [], query: {} },
			droppedQuerySelection: current.strategy === 'query',
		};
	};

    const createSourceSearchController = ({ transport, onResult, onPending } = {}) => {
        let token = 0;
        let controller = null;
        let timer = null;
        let destroyed = false;

        const cancel = () => {
            token += 1;
            controller?.abort?.();
            controller = null;
            if (timer) {
                window.clearTimeout(timer);
                timer = null;
            }
        };

        const load = async ({ sourceType, query = '', page = 1, perPage = 8, filters = {}, bulk = false } = {}) => {
            if (destroyed) {
                return { applied: false, destroyed: true };
            }
            const requestToken = ++token;
            controller?.abort?.();
            controller = typeof AbortController === 'function' ? new AbortController() : null;
            onPending?.(true);
            const result = await transport.getSourcePage(sourceType, {
                query,
                page,
                perPage,
                filters,
                bulk,
                signal: controller?.signal,
            });
            const current = !destroyed && requestToken === token;
            if (current) {
                controller = null;
                onPending?.(false);
                onResult?.(result);
            }
            return { applied: current, result };
        };

        const schedule = (params) => {
            if (timer) {
                window.clearTimeout(timer);
            }
            timer = window.setTimeout(() => {
                timer = null;
                load(params);
            }, SEARCH_DELAY);
        };

        return {
            load,
            schedule,
            cancel,
            destroy() {
                destroyed = true;
                cancel();
            },
        };
    };

	const mergeSourcePageItems = (currentItems, incomingItems) => {
		const merged = [];
		const positions = new Map();
		[...(Array.isArray(currentItems) ? currentItems : []), ...(Array.isArray(incomingItems) ? incomingItems : [])]
			.forEach((item) => {
				const id = Math.floor(Number(item?.id));
				if (id <= 0) return;
				if (positions.has(id)) {
					merged[positions.get(id)] = item;
					return;
				}
				positions.set(id, merged.length);
				merged.push(item);
			});
		return merged;
	};

    const createSourcePicker = ({
        mount,
		sourceTypesMount = null,
        transport,
        getRoute,
        getSelectedIds,
        getSelection,
        getSourcePolicy,
		getSourceDefinition,
		getSourceAttachmentLimit,
        getCampaignGroupDefaults = () => ({ recipe: {}, resultPolicy: {} }),
        selectedItems,
		onSelectionChange,
        onBulkMeta,
        onSourcePolicyChange,
        onSourceServiceError,
    } = {}) => {
        let route = getRoute();
		let destroyed = false;
        let query = '';
        let filters = { categories: [], stock: [] };
		let mediaFilters = { ...MEDIA_FILTER_DEFAULTS };
		let mediaFilterDraft = { ...MEDIA_FILTER_DEFAULTS };
		let mediaFilterOpen = false;
		let mediaFilterReturnFocus = null;
		let mediaFilterCloseTimer = 0;
		const uploadedSessionIds = new Set();
		let uploadRecovery = '';
		let mediaUploadSession = null;
		let mediaSummaryToken = 0;
		let mediaSummaryController = null;
		let sourceLoadError = null;
		let campaignSelectionError = '';
		let campaignSelectionErrorKind = '';
        let page = 1;
        let pageData = { items: [], page: 1, totalPages: 1, totalItems: 0 };
		let productSelectionCount = null;
		let productSelectionCountSignature = '';
		let productSelectionCountPending = false;
		let productSelectionCountToken = 0;
		let productSelectionCountController = null;
		let sourceLoading = true;
		let sourceLoadMorePending = false;
		let sourceLoadMoreError = null;
		let sourceLoadMoreController = null;
		let sourceLoadMoreObserver = null;
		let sourceScrollRoot = null;
		let sourceScrollHandler = null;
		const compactDiscoveryMedia = typeof window.matchMedia === 'function'
			? window.matchMedia('(max-width: 820px)')
			: null;
		let compactDiscovery = Boolean(compactDiscoveryMedia?.matches);
        const productContexts = new Map();
        let productContextController = null;
        let productContextToken = 0;
		let categoryController = null;
		let categoryToken = 0;
		let categoriesLoaded = false;
		let categoriesLoading = false;
		let productSearchOpen = false;
		let productSearchCloseTimer = 0;
		let suppressProductSearchFocus = false;
		let productSearchPending = false;
		let productSearchResultQuery = '';
		let productSearchQuery = '';
		let productSearchPage = null;
		let productSearchError = null;
		let cataloguePage = null;
		let catalogueScrollTop = 0;
		let quickCategories = [];
		const variationItems = new Map();
		let variationParent = null;
		let variationParentWasSelected = false;
		let variationChosenIds = new Set();
		let variationStock = '';
		let variationAttributes = {};
		let variationPage = 1;
		let variationPageData = { items: [], attributeOptions: [], page: 1, totalPages: 1, totalItems: 0 };
		let variationLoading = false;
		let variationLoadError = '';
		let variationSelectionReady = false;
		let variationController = null;
		let variationToken = 0;
		let variationOverlay = null;
		let variationLayer = null;
		let campaignOverlay = null;
		let campaignLayer = null;
		let campaignController = null;
		let campaignToken = 0;
		let campaignReturnFocus = null;
		let campaignOverlaySync = null;
		let campaignOverlaySyncSuspended = false;
		let campaignSelectionUpdating = false;

		const root = element('div', 'fotogenic-ai-source-picker');
		const selectHeading = element('header', 'fotogenic-ai-select-heading');
		const stepHeading = element('h2', 'fotogenic-ai-select-heading__title', __( 'Step 1 of 4 · Select', 'fotogenic-ai' ));
		stepHeading.tabIndex = -1;
		const selectionCount = element('span', 'fotogenic-ai-select-heading__count');
		selectHeading.append(stepHeading, selectionCount);
		const commandBar = element('div', 'fotogenic-ai-select-command-bar');
		const sourceTypeSlot = element('div', 'fotogenic-ai-select-command-bar__source');
		const searchControl = element('div', 'fotogenic-ai-product-search-control');
		const searchLabel = element('label', 'fotogenic-ai-select-search');
		const searchText = element('span', 'fotogenic-ai-studio-sr-only', __( 'Search sources', 'fotogenic-ai' ));
		const searchInput = element('input', 'fotogenic-ai-studio-control');
        searchInput.type = 'search';
        searchInput.autocomplete = 'off';
        searchInput.maxLength = 100;
		searchInput.placeholder = __( 'Search products…', 'fotogenic-ai' );
		searchInput.setAttribute('aria-label', __( 'Search products', 'fotogenic-ai' ));
		searchInput.setAttribute('aria-expanded', 'false');
		searchInput.setAttribute('aria-controls', 'fotogenic-ai-product-search-suggestions');
		searchLabel.append(searchText, createIcon('magnifying-glass', { weight: 'bold', size: 18 }), searchInput);
		const productSearchPopover = element('div', 'fotogenic-ai-product-search-popover');
		productSearchPopover.id = 'fotogenic-ai-product-search-suggestions';
		productSearchPopover.setAttribute('role', 'dialog');
		productSearchPopover.setAttribute('aria-label', __( 'Product search suggestions', 'fotogenic-ai' ));
		productSearchPopover.hidden = true;
		searchControl.append(searchLabel, productSearchPopover);

		const productFilters = element('div', 'fotogenic-ai-select-product-filters');
		const categoryFilter = createCheckboxFilterPopover({
			label: __( 'Product categories', 'fotogenic-ai' ),
			allLabel: __( 'All categories', 'fotogenic-ai' ),
			multipleLabel: (count) => sprintf(_n( '%d category', '%d categories', count, 'fotogenic-ai' ), count),
			onSelectionChange: (values, detail) => selectProductFilter('categories', values, detail),
			onBrowse: (value) => browseProductFilter('categories', value),
		});
		categoryFilter.setDisabled(true);
		const stockFilter = createCheckboxFilterPopover({
			label: __( 'Stock status', 'fotogenic-ai' ),
			allLabel: __( 'Any stock', 'fotogenic-ai' ),
			multipleLabel: (count) => sprintf(_n( '%d stock status', '%d stock statuses', count, 'fotogenic-ai' ), count),
			options: [
				{ value: 'instock', label: __( 'In stock', 'fotogenic-ai' ) },
				{ value: 'outofstock', label: __( 'Out of stock', 'fotogenic-ai' ) },
				{ value: 'onbackorder', label: __( 'On backorder', 'fotogenic-ai' ) },
			],
			onSelectionChange: (values, detail) => selectProductFilter('stock', values, detail),
			onBrowse: (value) => browseProductFilter('stock', value),
		});
		productFilters.append(categoryFilter.root, stockFilter.root);
		const mediaFilterControl = element('div', 'fotogenic-ai-media-filter-control');
		const mediaFilterTrigger = element('button', 'fotogenic-ai-media-filter-trigger');
		mediaFilterTrigger.type = 'button';
		mediaFilterTrigger.setAttribute('aria-haspopup', 'dialog');
		mediaFilterTrigger.setAttribute('aria-expanded', 'false');
		mediaFilterTrigger.append(
			createIcon('funnel', { weight: 'regular', size: 17 }),
			element('span', '', __( 'Filters', 'fotogenic-ai' )),
			createIcon('caret-down', { weight: 'bold', size: 14 })
		);
		const mediaFilterPopover = element('div', 'fotogenic-ai-media-filter-popover');
		mediaFilterPopover.hidden = true;
		mediaFilterPopover.setAttribute('role', 'dialog');
		mediaFilterPopover.setAttribute('aria-label', __( 'Filter media', 'fotogenic-ai' ));
		mediaFilterControl.append(mediaFilterTrigger, mediaFilterPopover);
		commandBar.append(sourceTypeSlot, searchControl, productFilters, mediaFilterControl);

		const toolbar = element('div', 'fotogenic-ai-select-toolbar');
        const selectedRegion = element('section', 'fotogenic-ai-source-picker__selected');
        selectedRegion.setAttribute('aria-label', __( 'Selected sources', 'fotogenic-ai' ));
        const policyRegion = element('section', 'fotogenic-ai-source-picker__policy');
        policyRegion.setAttribute('aria-label', __( 'Source image policy', 'fotogenic-ai' ));
		const status = element('p', 'fotogenic-ai-select-status fotogenic-ai-studio-sr-only');
        status.setAttribute('role', 'status');
        status.setAttribute('aria-live', 'polite');
        const results = element('div', 'fotogenic-ai-source-picker__results');
        results.setAttribute('aria-label', __( 'Source results', 'fotogenic-ai' ));
		const pagination = element('footer', 'fotogenic-ai-select-pagination');
		pagination.setAttribute('aria-label', __( 'Source navigation', 'fotogenic-ai' ));
		const paginationControls = element('div', 'fotogenic-ai-select-pagination__controls');
		const previous = element('button', '', '');
		const next = element('button', '', '');
		previous.type = 'button';
		next.type = 'button';
		previous.setAttribute('aria-label', __( 'Previous source page', 'fotogenic-ai' ));
		next.setAttribute('aria-label', __( 'Next source page', 'fotogenic-ai' ));
		previous.appendChild(createIcon('arrow-left', { weight: 'regular', size: 14 }));
		next.appendChild(createIcon('arrow-right', { weight: 'regular', size: 14 }));
		const pageLabel = element('strong');
		paginationControls.append(previous, pageLabel, next);
		pagination.appendChild(paginationControls);

		const selectView = mount.closest?.('[data-fa-view="select"]');
		const originalStageFooter = selectView?.querySelector?.(':scope > .fotogenic-ai-studio-stage-footer') || null;
		const selectionSummary = selectView?.querySelector?.('[data-fa-selection-summary]') || null;
		const configureAction = selectView?.querySelector?.('[data-fa-action="configure"]') || null;
		const mediaGalleryColumn = element('div', 'fotogenic-ai-media-gallery-column');
		root.append(selectHeading, commandBar, toolbar, status, results, selectedRegion, policyRegion, pagination);
		mount.replaceChildren(root);

		const syncContinuePlacement = () => {
			if (!originalStageFooter) return;
			if (selectionSummary) selectionSummary.classList.remove('fotogenic-ai-studio-sr-only');
			if (configureAction) {
				configureAction.classList.remove('fotogenic-ai-select-pagination__continue');
				configureAction.classList.remove('fotogenic-ai-media-continue');
				configureAction.textContent = __( 'Continue to Configure', 'fotogenic-ai' );
			}
			originalStageFooter.append(selectionSummary, configureAction);
		};
		const syncPresentation = () => {
			const productSelect = route.sourceType === 'product';
			const productDiscovery = productSelect;
			const mediaSelect = route.sourceType === 'media';
			const contentSelect = route.scope === 'bulk' && ['post', 'page'].includes(route.sourceType);
			root.classList.toggle('is-product-select', productSelect);
			root.classList.toggle('is-media-select', mediaSelect);
			root.classList.toggle('is-content-select', contentSelect);
			root.classList.toggle('is-campaign-source-select', route.workflow === 'campaign_set');
			commandBar.classList.toggle('has-product-filters', productDiscovery);
			commandBar.classList.toggle('fotogenic-ai-media-command-row', mediaSelect);
			selectHeading.hidden = false;
			selectionCount.hidden = mediaSelect;
			mediaFilterControl.hidden = !mediaSelect;
			policyRegion.hidden = mediaSelect;
			productFilters.hidden = !productDiscovery;
			searchControl.classList.toggle('is-product-search', productDiscovery);
			searchControl.classList.toggle('fotogenic-ai-media-search', mediaSelect);
			searchInput.placeholder = productDiscovery ? __( 'Search products…', 'fotogenic-ai' )
				: (mediaSelect ? __( 'Search media…', 'fotogenic-ai' ) : __( 'Search by title or ID', 'fotogenic-ai' ));
			searchInput.setAttribute('aria-label', productDiscovery ? __( 'Search products', 'fotogenic-ai' )
				: (mediaSelect ? __( 'Search media', 'fotogenic-ai' ) : __( 'Search sources', 'fotogenic-ai' )));
			if (mediaSelect) {
				mediaGalleryColumn.replaceChildren(selectHeading, commandBar, toolbar, status, results, pagination);
				root.replaceChildren(mediaGalleryColumn, selectedRegion, policyRegion);
			} else {
				root.replaceChildren(selectHeading, commandBar, toolbar, status, results, selectedRegion, policyRegion, pagination);
			}
			if (sourceTypesMount && sourceTypesMount.parentElement !== sourceTypeSlot) {
				sourceTypeSlot.replaceChildren(sourceTypesMount);
			}
			syncContinuePlacement();
		};
		const isProductDiscovery = () => route.sourceType === 'product';
		const isStoreQueueSelection = () => route.workflow === 'product_images'
			&& route.sourceType === 'product'
			&& route.scope === 'bulk';
		const isInfiniteDiscovery = () => ['product', 'media'].includes(route.sourceType) && !compactDiscovery;
		const discoveryPageSize = () => compactDiscovery ? 12 : pageSize(route);
		const disconnectInfiniteScroll = () => {
			sourceLoadMoreObserver?.disconnect?.();
			sourceLoadMoreObserver = null;
			if (sourceScrollRoot && sourceScrollHandler) {
				sourceScrollRoot.removeEventListener('scroll', sourceScrollHandler);
			}
			sourceScrollRoot = null;
			sourceScrollHandler = null;
		};
		const resetInfiniteState = () => {
			sourceLoadMoreController?.cancel?.();
			sourceLoadMorePending = false;
			sourceLoadMoreError = null;
			disconnectInfiniteScroll();
		};
		const handleDiscoveryModeChange = (event) => {
			const nextCompact = Boolean(event?.matches);
			if (nextCompact === compactDiscovery) return;
			compactDiscovery = nextCompact;
			resetInfiniteState();
			if (!['product', 'media'].includes(route.sourceType)) return;
			page = 1;
			cataloguePage = null;
			sourceLoadError = null;
			productSuggestionsController.cancel();
			productSearchPending = false;
			productSearchPage = null;
			productSearchResultQuery = '';
			if (productSearchOpen) loadProductSuggestions();
			void load();
		};
		const syncPaginationVisibility = ({ pending = false, failed = false } = {}) => {
			const singlePage = pageData.totalPages <= 1;
			const infiniteProduct = isInfiniteDiscovery();
			const compactProductFailure = failed && isProductDiscovery() && !infiniteProduct;
			paginationControls.hidden = infiniteProduct || singlePage || compactProductFailure;
			pagination.classList.toggle('has-single-page', infiniteProduct || singlePage || compactProductFailure);
			pagination.hidden = pending || singlePage || infiniteProduct || (failed && !compactProductFailure);
		};

		const getSourceMode = () => String(getSourcePolicy?.()?.sourceMode || 'featured');
		const currentSelection = () => {
			const selection = getSelection?.();
			return selection && typeof selection === 'object' ? selection : {
				strategy: 'explicit',
				selectedIds: getSelectedIds(),
				excludedIds: [],
				query: {},
			};
		};
		const sourceLimit = () => Math.max(1, Math.floor(Number(getSourceAttachmentLimit?.())) || 1);
		const sourceAttachmentIds = () => {
			const ids = getSourcePolicy?.()?.attachmentIds;
			return Array.isArray(ids) ? ids : [];
		};
		const getMaximum = () => {
			const configured = getSourceDefinition?.()?.selectionCardinality?.[route.scope]?.maximum;
			return Math.max(1, Math.floor(Number(configured)) || 1);
		};
		const currentQuery = () => ({
			search: query.trim().replace(/\s+/g, ' ').slice(0, 100),
			...(route.sourceType === 'product' ? {
				categories: [...filters.categories],
				stock: [...filters.stock],
			} : {}),
			...(route.sourceType === 'media' ? { ...mediaFilters } : {}),
		});
		const productSelectionFilters = () => {
			const selection = currentSelection();
			if (selection.strategy !== 'query' || route.sourceType !== 'product') {
				return { categories: [], stock: [] };
			}
			return {
				categories: Array.isArray(selection.query?.categories)
					? selection.query.categories.map(Number).filter((value) => value > 0).slice(0, 50)
					: [],
				stock: Array.isArray(selection.query?.stock)
					? selection.query.stock.map(String).filter((value) => ['instock', 'outofstock', 'onbackorder'].includes(value))
					: [],
			};
		};
		const selectionQueryForProductFilters = (updates = {}) => {
			const currentFilters = productSelectionFilters();
			return {
				search: '',
				categories: updates.categories ?? currentFilters.categories,
				stock: updates.stock ?? currentFilters.stock,
			};
		};
		const syncProductSelectionFilterControls = () => {
			const selection = currentSelection();
			const selectedFilters = productSelectionFilters();
			const querySelection = selection.strategy === 'query';
			categoryFilter.setSelected(selectedFilters.categories, {
				allSelected: querySelection && selectedFilters.categories.length === 0,
			});
			stockFilter.setSelected(selectedFilters.stock, {
				allSelected: querySelection && selectedFilters.stock.length === 0,
			});
		};
		const showProductSelectionFilters = () => {
			const selectedFilters = productSelectionFilters();
			query = '';
			productSearchQuery = '';
			searchInput.value = '';
			filters.categories = [...selectedFilters.categories];
			filters.stock = [...selectedFilters.stock];
			page = 1;
			closeProductSearch();
			applyBulkFilterChange();
		};
		const selectProductFilter = (name, values, detail = {}) => {
			if (!isStoreQueueSelection()) return false;
			const normalized = name === 'categories'
				? values.map(Number).filter((value) => value > 0).slice(0, 50)
				: values.filter((value) => ['instock', 'outofstock', 'onbackorder'].includes(value));
			if (detail.all) {
				const committed = commitSelection(detail.checked
					? { strategy: 'query', selectedIds: [], excludedIds: [], query: selectionQueryForProductFilters({ [name]: [] }) }
					: { strategy: 'explicit', selectedIds: [], excludedIds: [], query: {} });
				if (!committed) return false;
				syncProductSelectionFilterControls();
				showProductSelectionFilters();
				return true;
			}
			const querySelection = selectionQueryForProductFilters({ [name]: normalized });
			let committed;
			if (!detail.all && !querySelection.categories.length && !querySelection.stock.length) {
				committed = commitSelection({ strategy: 'explicit', selectedIds: [], excludedIds: [], query: {} });
			} else {
				committed = commitSelection({ strategy: 'query', selectedIds: [], excludedIds: [], query: querySelection });
			}
			if (!committed) return false;
			syncProductSelectionFilterControls();
			showProductSelectionFilters();
			return true;
		};
		const browseProductFilter = (name, value) => {
			if (name === 'categories') {
				const categoryId = Number(value);
				filters.categories = categoryId > 0 ? [categoryId] : [];
			} else {
				filters.stock = ['instock', 'outofstock', 'onbackorder'].includes(String(value)) ? [String(value)] : [];
			}
			page = 1;
			closeProductSearch();
			applyBulkFilterChange();
		};
		const mediaFilterOptions = {
			type: [
				['all', __( 'All types', 'fotogenic-ai' )],
				['jpg', 'JPG'],
				['png', 'PNG'],
				['webp', 'WEBP'],
			],
			date: [
				['all', __( 'Any time', 'fotogenic-ai' )],
				['today', __( 'Today', 'fotogenic-ai' )],
				['week', __( 'This week', 'fotogenic-ai' )],
				['month', __( 'This month', 'fotogenic-ai' )],
				['older', __( 'Older', 'fotogenic-ai' )],
			],
			orientation: [
				['all', __( 'Any orientation', 'fotogenic-ai' )],
				['square', __( 'Square', 'fotogenic-ai' )],
				['landscape', __( 'Landscape', 'fotogenic-ai' )],
				['portrait', __( 'Portrait', 'fotogenic-ai' )],
			],
			size: [
				['all', __( 'Any size', 'fotogenic-ai' )],
				['under_300kb', __( 'Under 300 KB', 'fotogenic-ai' )],
				['300kb_and_over', __( '300 KB and over', 'fotogenic-ai' )],
			],
		};
		const activeMediaFilterCount = () => Object.keys(MEDIA_FILTER_DEFAULTS)
			.filter((key) => mediaFilters[key] !== MEDIA_FILTER_DEFAULTS[key]).length;
		const popoverCloseDelay = () => window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches ? 0 : 140;
		const finishMediaFilterClose = () => {
			mediaFilterCloseTimer = 0;
			mediaFilterPopover.classList.remove('is-closing');
			mediaFilterPopover.hidden = true;
		};
		const closeMediaFilters = ({ restoreFocus = false, immediate = false } = {}) => {
			if (!mediaFilterOpen && !mediaFilterPopover.classList.contains('is-open')) return;
			mediaFilterOpen = false;
			window.clearTimeout(mediaFilterCloseTimer);
			mediaFilterPopover.classList.remove('is-open');
			mediaFilterPopover.classList.add('is-closing');
			mediaFilterTrigger.classList.remove('is-open');
			mediaFilterTrigger.setAttribute('aria-expanded', 'false');
			const delay = immediate ? 0 : popoverCloseDelay();
			if (delay) mediaFilterCloseTimer = window.setTimeout(finishMediaFilterClose, delay);
			else finishMediaFilterClose();
			if (restoreFocus) window.setTimeout(() => mediaFilterReturnFocus?.focus?.(), 0);
		};
		const renderMediaFilters = () => {
			mediaFilterPopover.replaceChildren();
			mediaFilterTrigger.replaceChildren(
				createIcon('funnel', { weight: 'regular', size: 17 }),
				element('span', '', __( 'Filters', 'fotogenic-ai' )),
				...(activeMediaFilterCount() ? [element('strong', '', String(activeMediaFilterCount()))] : []),
				createIcon('caret-down', { weight: 'bold', size: 14 })
			);
			const heading = element('div', 'fotogenic-ai-media-filter-heading');
			const copy = element('div');
			copy.append(
				element('strong', '', __( 'Filter media', 'fotogenic-ai' )),
				element('small', '', __( 'Narrow the visible library.', 'fotogenic-ai' ))
			);
				const reset = element('button', 'fotogenic-ai-source-text-button', __( 'Reset', 'fotogenic-ai' ));
			reset.type = 'button';
			reset.addEventListener('click', () => {
				mediaFilterDraft = { ...MEDIA_FILTER_DEFAULTS };
				mediaFilters = { ...MEDIA_FILTER_DEFAULTS };
				page = 1;
				renderMediaFilters();
				applyBulkFilterChange();
			});
			heading.append(copy, reset);
			const grid = element('div', 'fotogenic-ai-media-filter-grid');
			[
				['type', __( 'File type', 'fotogenic-ai' )],
				['date', __( 'Date added', 'fotogenic-ai' )],
				['orientation', __( 'Orientation', 'fotogenic-ai' )],
				['size', __( 'File size', 'fotogenic-ai' )],
			].forEach(([key, label]) => {
				const field = element('label');
				const control = element('select', 'fotogenic-ai-studio-control');
				mediaFilterOptions[key].forEach(([value, optionLabel]) => {
					const option = element('option', '', optionLabel);
					option.value = value;
					control.appendChild(option);
				});
				control.value = mediaFilterDraft[key];
				control.addEventListener('change', () => {
					mediaFilterDraft = { ...mediaFilterDraft, [key]: control.value };
				});
				field.append(element('span', '', label), createSelectShell(control));
				grid.appendChild(field);
			});
			const actions = element('div', 'fotogenic-ai-media-filter-actions');
			actions.appendChild(element('span', '', sprintf(
				_n( '%d matching image', '%d matching images', pageData.totalItems, 'fotogenic-ai' ),
				pageData.totalItems
			)));
			const apply = element('button', 'primary small', __( 'Apply filters', 'fotogenic-ai' ));
			apply.type = 'button';
			apply.addEventListener('click', () => {
				mediaFilters = { ...mediaFilterDraft };
				page = 1;
				closeMediaFilters({ restoreFocus: true });
				renderMediaFilters();
				applyBulkFilterChange();
			});
			actions.appendChild(apply);
			mediaFilterPopover.append(heading, grid, actions);
			mediaFilterPopover.hidden = !mediaFilterOpen && !mediaFilterPopover.classList.contains('is-closing');
		};
		const dismissMediaFilters = (event) => {
			if (!mediaFilterOpen || mediaFilterControl.contains(event.target)) return;
			closeMediaFilters();
		};
		const closeMediaFiltersWithEscape = (event) => {
			if (event.key !== 'Escape' || !mediaFilterOpen) return;
			event.preventDefault();
			closeMediaFilters({ restoreFocus: true });
		};
		const selectedVariationsForParent = (parentId) => getSelectedIds()
			.map((id) => selectedItems.get(Number(id)))
			.filter((item) => item?.target?.targetType === 'variation'
				&& Number(item.target.parentProductId) === Number(parentId));
		const variationHost = mount.closest?.('.fotogenic-ai-studio-workbench--select');
		const variationUi = {};
		if (variationHost && Shared.ui?.containedOverlay?.create) {
			variationLayer = element('div', 'fotogenic-ai-variation-layer variation-drawer-layer');
			const panel = element('section', 'fotogenic-ai-variation-drawer variation-drawer');
			panel.setAttribute('aria-labelledby', 'fotogenic-ai-variation-drawer-title');
			const header = element('header', 'fotogenic-ai-variation-drawer__header variation-drawer-header');
			const parentImage = element('img', 'fotogenic-ai-variation-drawer__parent-image');
			parentImage.alt = '';
			parentImage.hidden = true;
			const headingWrap = element('div', 'fotogenic-ai-variation-drawer__product');
			const heading = element('h2', '', __( 'Choose variations', 'fotogenic-ai' ));
			heading.id = 'fotogenic-ai-variation-drawer-title';
			heading.tabIndex = -1;
			heading.setAttribute('data-fa-overlay-heading', '');
			const description = element('p', '', __( 'Variable Product', 'fotogenic-ai' ));
			headingWrap.append(heading, description);
			const close = element('button', 'fotogenic-ai-variation-drawer__close');
			close.type = 'button';
			close.setAttribute('aria-label', __( 'Close variation picker', 'fotogenic-ai' ));
			const closeIcon = createIcon('x', { weight: 'bold', size: 18 });
			close.appendChild(closeIcon);
			header.append(parentImage, headingWrap, close);

			const filtersRegion = element('div', 'fotogenic-ai-variation-drawer__filters variation-filter-row');
			const attributeFilters = element('div', 'fotogenic-ai-variation-drawer__attribute-filters');
			const variationStockLabel = element('label', 'fotogenic-ai-variation-drawer__filter');
			variationStockLabel.appendChild(element('span', 'fotogenic-ai-studio-sr-only', __( 'Variation stock', 'fotogenic-ai' )));
			const variationStockControl = element('select', 'fotogenic-ai-studio-control');
			[
				['', __( 'Any stock', 'fotogenic-ai' )],
				['instock', __( 'In stock', 'fotogenic-ai' )],
				['onbackorder', __( 'On backorder', 'fotogenic-ai' )],
				['outofstock', __( 'Out of stock', 'fotogenic-ai' )],
			].forEach(([value, label]) => {
				const option = element('option', '', label);
				option.value = value;
				variationStockControl.appendChild(option);
			});
			variationStockLabel.appendChild(createSelectShell(variationStockControl));
			const selectAll = element('input', 'fotogenic-ai-variation-drawer__select-all');
			selectAll.type = 'checkbox';
			selectAll.setAttribute('aria-label', __( 'Select or deselect eligible variations on this page', 'fotogenic-ai' ));
			filtersRegion.append(attributeFilters, variationStockLabel);

			const variationStatus = element('p', 'fotogenic-ai-studio-sr-only');
			variationStatus.setAttribute('role', 'status');
			const listHeading = element('div', 'fotogenic-ai-variation-drawer__list-heading');
			listHeading.classList.add('variation-list-heading');
			listHeading.append(
				selectAll,
				element('span', '', __( 'Variation', 'fotogenic-ai' )),
				element('span', '', __( 'SKU', 'fotogenic-ai' )),
				element('span', '', __( 'Stock', 'fotogenic-ai' )),
				element('span', '', __( 'Eligibility', 'fotogenic-ai' ))
			);
			const variationList = element('div', 'fotogenic-ai-variation-drawer__list variation-list');
			variationList.setAttribute('aria-label', __( 'Product variations', 'fotogenic-ai' ));
			variationList.setAttribute('role', 'list');
			const variationPagination = element('div', 'fotogenic-ai-variation-drawer__pagination fotogenic-ai-overlay-pagination');
			const variationPrevious = element('button');
			const variationPageLabel = element('strong');
			const variationNext = element('button');
			variationPrevious.type = 'button';
			variationNext.type = 'button';
			variationPrevious.setAttribute('aria-label', __( 'Previous variation page', 'fotogenic-ai' ));
			variationNext.setAttribute('aria-label', __( 'Next variation page', 'fotogenic-ai' ));
			variationPrevious.appendChild(createIcon('arrow-left', { weight: 'regular', size: 14 }));
			variationNext.appendChild(createIcon('arrow-right', { weight: 'regular', size: 14 }));
			variationPagination.hidden = true;
			variationPagination.append(variationPrevious, variationPageLabel, variationNext);
			const footer = element('footer', 'fotogenic-ai-variation-drawer__footer variation-drawer-footer');
			const cancel = element('button', 'secondary small', __( 'Cancel', 'fotogenic-ai' ));
			const apply = element('button', 'primary small', __( 'Apply variations', 'fotogenic-ai' ));
			cancel.type = 'button';
			apply.type = 'button';
			footer.append(cancel, variationPagination, apply);
			panel.append(header, filtersRegion, variationStatus, variationList, footer);
			variationLayer.appendChild(panel);
			variationHost.appendChild(variationLayer);
			variationOverlay = Shared.ui.containedOverlay.create({
				layer: variationLayer,
				panel,
				onClose: () => closeVariationDrawer(),
			});
			Object.assign(variationUi, {
				heading,
				description,
				parentImage,
				close,
				attributeFilters,
				stock: variationStockControl,
				selectAll,
				status: variationStatus,
				listHeading,
				list: variationList,
				pagination: variationPagination,
				previous: variationPrevious,
				pageLabel: variationPageLabel,
				next: variationNext,
				cancel,
				apply,
			});
		}

		const renderVariationFilters = () => {
			if (!variationUi.attributeFilters) return;
			const options = Array.isArray(variationPageData.attributeOptions) ? variationPageData.attributeOptions : [];
			const signature = JSON.stringify(options);
			if (signature === variationUi.attributeSignature) return;
			variationUi.attributeSignature = signature;
			variationUi.attributeFilters.replaceChildren();
			options.forEach((attribute) => {
				const label = element('label', 'fotogenic-ai-variation-drawer__filter');
				label.appendChild(element('span', 'fotogenic-ai-studio-sr-only', attribute.label));
				const control = element('select', 'fotogenic-ai-studio-control');
				const any = element('option', '', sprintf(__( 'All %s', 'fotogenic-ai' ), attribute.label.toLowerCase()));
				any.value = '';
				control.appendChild(any);
				attribute.options.forEach((value) => {
					const option = element('option', '', value);
					option.value = value;
					control.appendChild(option);
				});
				control.value = variationAttributes[attribute.key] || '';
				control.addEventListener('change', () => {
					if (control.value) variationAttributes[attribute.key] = control.value;
					else delete variationAttributes[attribute.key];
					variationPage = 1;
					void loadVariations();
				});
				label.appendChild(createSelectShell(control));
				variationUi.attributeFilters.appendChild(label);
			});
		};

		const renderVariationDrawer = () => {
			if (!variationUi.list || !variationParent) return;
			variationUi.heading.textContent = variationParent.label;
			variationUi.description.textContent = sprintf(__( 'ID %d · Variable product', 'fotogenic-ai' ), variationParent.id);
			variationUi.parentImage.src = variationParent.imageUrl || '';
			variationUi.parentImage.hidden = !variationParent.imageUrl;
			renderVariationFilters();
			const eligibleIds = variationPageData.items
				.filter((item) => sourceEligibleForMode(item, route, getSourceMode()))
				.map((item) => item.id);
			variationUi.list.replaceChildren(variationUi.listHeading);
			variationUi.list.setAttribute('aria-busy', variationLoading ? 'true' : 'false');
			if (variationLoading || variationLoadError) {
				variationUi.list.appendChild(requestState({
					message: variationLoading ? __( 'Loading variations…', 'fotogenic-ai' ) : variationLoadError,
					loading: variationLoading,
					onRetry: variationLoading ? null : () => void loadVariations(),
				}));
			} else if (!variationPageData.items.length) {
				const empty = element('div', 'fotogenic-ai-variation-drawer__empty');
				empty.append(
					element('strong', '', __( 'No matching variations', 'fotogenic-ai' )),
					element(
						'p',
						'',
						variationStock || Object.keys(variationAttributes).length
							? __( 'Try broader variation filters or a different SKU.', 'fotogenic-ai' )
							: __( 'This Product has no available variations.', 'fotogenic-ai' )
					)
				);
				variationUi.list.appendChild(empty);
			} else {
				variationPageData.items.forEach((item) => {
					const checked = variationChosenIds.has(item.id);
					const eligible = sourceEligibleForMode(item, route, getSourceMode());
					const eligibilityReason = eligible
						? __( 'Variation image', 'fotogenic-ai' )
						: (item.eligibilityReason || __( 'Unavailable', 'fotogenic-ai' ));
					const reasonId = `fotogenic-ai-variation-${item.id}-eligibility`;
					const row = element('label', 'fotogenic-ai-variation-drawer__item variation-row');
					row.setAttribute('role', 'listitem');
					row.classList.toggle('is-selected', checked);
					row.classList.toggle('is-disabled', !eligible);
					const checkbox = element('input');
					checkbox.type = 'checkbox';
					checkbox.checked = checked;
					checkbox.disabled = !eligible && !checked;
					checkbox.setAttribute('aria-label', sprintf(__( 'Select %s', 'fotogenic-ai' ), item.label));
					if (!eligible) checkbox.setAttribute('aria-describedby', reasonId);
					checkbox.addEventListener('change', () => {
						if (checkbox.checked) variationChosenIds.add(item.id);
						else variationChosenIds.delete(item.id);
						renderVariationDrawer();
					});
					row.appendChild(checkbox);
					const image = element('span', 'fotogenic-ai-variation-drawer__thumb');
					if (item.imageUrl) {
						const imageElement = element('img', 'fotogenic-ai-source-picker__thumb');
						imageElement.src = item.imageUrl;
						imageElement.alt = '';
						imageElement.loading = 'lazy';
						imageElement.decoding = 'async';
						image.appendChild(imageElement);
					} else {
						image.appendChild(createIcon('image-square', { weight: 'regular', size: 24 }));
					}
					row.appendChild(image);
					row.appendChild(element('strong', '', item.attributes.length ? item.attributes.map((attribute) => attribute.value).join(' / ') : item.label));
					row.appendChild(element('small', '', item.sku || sprintf(__( 'ID %d', 'fotogenic-ai' ), item.id)));
					const stock = item.stockQuantity !== null
						? String(item.stockQuantity)
						: (item.stockStatus === 'outofstock' ? '0' : (item.stockStatus === 'onbackorder' ? __( 'Backorder', 'fotogenic-ai' ) : __( 'In stock', 'fotogenic-ai' )));
					row.appendChild(element('span', item.stockStatus === 'outofstock' ? 'is-out-of-stock' : '', stock));
					const eligibility = element(
						'span',
						`fotogenic-ai-variation-drawer__eligibility ${eligible ? 'is-eligible' : 'is-ineligible'}`,
						eligibilityReason
					);
					eligibility.id = reasonId;
					row.appendChild(eligibility);
					variationUi.list.appendChild(row);
				});
			}
			variationUi.pageLabel.textContent = sprintf(__( '%1$d / %2$d', 'fotogenic-ai' ), variationPageData.page, variationPageData.totalPages);
			variationUi.pageLabel.setAttribute('aria-label', sprintf(__( 'Page %1$d of %2$d', 'fotogenic-ai' ), variationPageData.page, variationPageData.totalPages));
			const unavailable = variationLoading || Boolean(variationLoadError);
			variationUi.previous.disabled = unavailable || variationPageData.page <= 1;
			variationUi.next.disabled = unavailable || variationPageData.page >= variationPageData.totalPages;
			variationUi.pagination.hidden = unavailable || variationPageData.totalPages <= 1;
			variationUi.selectAll.disabled = unavailable || eligibleIds.length === 0;
			variationUi.apply.disabled = unavailable;
			variationUi.selectAll.checked = eligibleIds.length > 0 && eligibleIds.every((id) => variationChosenIds.has(id));
			variationUi.selectAll.indeterminate = !variationUi.selectAll.checked && eligibleIds.some((id) => variationChosenIds.has(id));
			variationUi.selectAll.hidden = route.scope === 'single';
			variationUi.apply.textContent = sprintf(
				_n( 'Apply %d variation', 'Apply %d variations', variationChosenIds.size, 'fotogenic-ai' ),
				variationChosenIds.size
			);
		};

		const loadVariations = async () => {
			if (!variationParent || typeof transport.getProductVariations !== 'function') {
				variationLoading = false;
				variationLoadError = __( 'Variation discovery is unavailable.', 'fotogenic-ai' );
				renderVariationDrawer();
				return;
			}
			const parentId = variationParent.id;
			const token = ++variationToken;
			variationController?.abort?.();
			variationController = typeof AbortController === 'function' ? new AbortController() : null;
			const controller = variationController;
			const isCurrent = () => token === variationToken && variationParent?.id === parentId && variationOverlay?.isOpen() && !destroyed;
			const fail = (message) => {
				variationController = null;
				variationLoading = false;
				variationLoadError = message;
				renderVariationDrawer();
			};
			variationLoading = true;
			variationLoadError = '';
			variationUi.status.textContent = '';
			renderVariationDrawer();
			if (!variationSelectionReady) {
				const unresolvedIds = getSelectedIds().filter((id) => !selectedItems.has(Number(id)));
				if (unresolvedIds.length) {
					const responses = await Promise.all(unresolvedIds.map((id) => transport.getSourceSummary('product', id, { signal: controller?.signal })));
					if (!isCurrent()) return;
					const resolvedItems = responses.map((response) => response?.ok ? normalizeItem(response.data, 'product') : null);
					if (resolvedItems.some((item) => !item)) {
						fail(__( 'Selected variations could not be checked. Try again before applying changes.', 'fotogenic-ai' ));
						return;
					}
					resolvedItems.forEach((item) => selectedItems.set(item.id, item));
				}
				const siblings = selectedVariationsForParent(parentId);
				siblings.forEach((item) => variationItems.set(item.id, item));
				variationChosenIds = new Set(siblings.map((item) => item.id));
				variationSelectionReady = true;
			}
			const response = await transport.getProductVariations(parentId, {
				page: variationPage,
				perPage: 12,
				stock: variationStock,
				attributes: variationAttributes,
				signal: controller?.signal,
			});
			if (!isCurrent()) return;
			variationController = null;
			variationLoading = false;
			if (!response.ok) {
				fail(response.message || __( 'Variations could not be loaded.', 'fotogenic-ai' ));
				return;
			}
			const items = response.data.items
				.map((raw) => normalizeItem(raw, 'product'))
				.filter((item) => item?.target?.targetType === 'variation'
					&& Number(item.target.parentProductId) === Number(parentId));
			items.forEach((item) => variationItems.set(item.id, item));
			variationPageData = {
				...response.data,
				attributeOptions: response.data.attributeOptions,
				items,
			};
			variationUi.status.textContent = sprintf(
				_n( '%d variation available.', '%d variations available.', variationPageData.totalItems, 'fotogenic-ai' ),
				variationPageData.totalItems
			);
			renderVariationDrawer();
		};

		const closeVariationDrawer = (options = {}) => {
			variationToken += 1;
			variationController?.abort?.();
			variationController = null;
			variationOverlay?.close?.(options);
			root.querySelectorAll('.active-variation-row').forEach((row) => row.classList.remove('active-variation-row'));
		};

		const applyVariationSelection = () => {
			if (!variationParent || variationLoading || variationLoadError || !variationSelectionReady) return;
			const siblings = selectedVariationsForParent(variationParent.id);
			const chosenItems = [...variationChosenIds]
				.map((id) => variationItems.get(Number(id)) || selectedItems.get(Number(id)))
				.filter((item) => item?.target?.targetType === 'variation'
					&& Number(item.target.parentProductId) === Number(variationParent.id));
			const replacement = replaceParentWithVariations({
				selection: currentSelection(),
				parentId: variationParent.id,
				variationIds: chosenItems.map((item) => item.id),
				siblingVariationIds: siblings.map((item) => item.id),
				maximum: getMaximum(),
				restoreParent: variationParentWasSelected || siblings.length > 0,
			});
			if (!replacement.ok) {
				variationUi.status.textContent = sprintf(__( 'Select no more than %d exact targets.', 'fotogenic-ai' ), getMaximum());
				return;
			}
			const affectedIds = new Set([
				variationParent.id,
				...siblings.map((item) => item.id),
				...chosenItems.map((item) => item.id),
			]);
			const previousItems = new Map([...affectedIds].map((id) => [
				id,
				selectedItems.has(id) ? selectedItems.get(id) : null,
			]));
			const restorePreviousItems = () => previousItems.forEach((item, id) => {
				if (item) selectedItems.set(id, item);
				else selectedItems.delete(id);
			});
			siblings.forEach((item) => selectedItems.delete(item.id));
			selectedItems.delete(variationParent.id);
			if (chosenItems.length) chosenItems.forEach((item) => selectedItems.set(item.id, item));
			else if (replacement.selection.selectedIds.includes(variationParent.id)) selectedItems.set(variationParent.id, variationParent);
			let committed = false;
			try {
				committed = commitSelection(replacement.selection);
			} catch (error) {
				restorePreviousItems();
				throw error;
			}
			if (!committed) {
				restorePreviousItems();
				return;
			}
			const parentFocusKey = `variations:${variationParent.id}`;
			closeVariationDrawer({ restoreFocus: false });
			if (replacement.droppedQuerySelection) {
				status.textContent = __( 'All-matching selection was replaced with explicit exact variation targets.', 'fotogenic-ai' );
			}
			window.requestAnimationFrame(() => {
				if (restoreFocusKey(mount, parentFocusKey)) return;
				window.requestAnimationFrame(() => restoreFocusKey(mount, parentFocusKey));
			});
		};

		const openVariationDrawer = (item, trigger) => {
			if (
				!variationOverlay
				|| !supportsVariationSelection(route)
				|| item?.target?.targetType !== 'product'
				|| item?.hasVariations !== true
			) return;
			variationParent = item;
			variationParentWasSelected = getSelectedIds().includes(item.id);
			variationChosenIds = new Set();
			variationStock = '';
			variationAttributes = {};
			variationPage = 1;
			variationPageData = { items: [], attributeOptions: [], page: 1, totalPages: 1, totalItems: 0 };
			variationLoading = true;
			variationLoadError = '';
			variationSelectionReady = false;
			variationUi.attributeSignature = '';
			variationUi.attributeFilters.replaceChildren();
			variationUi.stock.value = '';
			variationUi.status.textContent = '';
			renderVariationDrawer();
			trigger?.closest?.('tr')?.classList.add('active-variation-row');
			variationOverlay.open({ returnFocus: trigger, initialFocus: variationUi.heading });
			void loadVariations();
		};

		if (variationOverlay) {
			variationUi.close.addEventListener('click', closeVariationDrawer);
			variationUi.cancel.addEventListener('click', closeVariationDrawer);
			variationUi.apply.addEventListener('click', applyVariationSelection);
			variationUi.selectAll.addEventListener('change', () => {
				const eligibleIds = variationPageData.items
					.filter((item) => sourceEligibleForMode(item, route, getSourceMode()))
					.map((item) => item.id);
				const allSelected = eligibleIds.some((id) => variationChosenIds.has(id));
				eligibleIds.forEach((id) => {
					if (allSelected) variationChosenIds.delete(id);
					else variationChosenIds.add(id);
				});
				renderVariationDrawer();
			});
			variationUi.stock.addEventListener('change', () => {
				variationStock = variationUi.stock.value;
				variationPage = 1;
				void loadVariations();
			});
			variationUi.previous.addEventListener('click', () => {
				variationPage = Math.max(1, variationPageData.page - 1);
				void loadVariations();
			});
			variationUi.next.addEventListener('click', () => {
				variationPage = Math.min(100, variationPageData.page + 1);
				void loadVariations();
			});
		}
		const productSelectionQuerySignature = (selection = currentSelection()) => JSON.stringify({
			search: String(selection.query?.search || '').trim().replace(/\s+/g, ' ').slice(0, 100),
			categories: [...new Set((selection.query?.categories || []).map(Number).filter((id) => id > 0))].slice(0, 50),
			stock: [...new Set((selection.query?.stock || []).map(String).filter((value) => ['instock', 'outofstock', 'onbackorder'].includes(value)))],
		});
		const productSelectionMatchesCatalogue = (selection = currentSelection()) => (
			selection.strategy === 'query'
			&& productSelectionQuerySignature(selection) === productSelectionQuerySignature({ strategy: 'query', query: currentQuery() })
		);
        const selectionEstimate = () => {
            const selection = currentSelection();
            if (selection.strategy !== 'query') return selection.selectedIds.length;
			if (isStoreQueueSelection()) {
				if (productSelectionMatchesCatalogue(selection)) {
					return Math.max(0, pageData.totalItems - selection.excludedIds.length + selection.selectedIds.length);
				}
				if (productSelectionCountSignature === productSelectionQuerySignature(selection)
					&& Number.isFinite(productSelectionCount)) {
					return Math.max(0, productSelectionCount - selection.excludedIds.length + selection.selectedIds.length);
				}
				return 0;
			}
            return Math.max(0, pageData.totalItems - selection.excludedIds.length + selection.selectedIds.length);
        };
		const syncSelectionCount = () => {
			const selection = currentSelection();
			if (isStoreQueueSelection()) {
				const unresolvedQuery = selection.strategy === 'query'
					&& !productSelectionMatchesCatalogue(selection)
					&& productSelectionCountSignature === productSelectionQuerySignature(selection)
					&& !Number.isFinite(productSelectionCount);
				selectionCount.textContent = unresolvedQuery
					? (productSelectionCountPending
						? __( 'Updating selection…', 'fotogenic-ai' )
						: __( 'Products selected', 'fotogenic-ai' ))
					: sprintf( __( '%d ready', 'fotogenic-ai' ), selectionEstimate() );
				selectionCount.setAttribute('aria-busy', productSelectionCountPending ? 'true' : 'false');
				return;
			}
			selectionCount.removeAttribute('aria-busy');
			selectionCount.textContent = selection.strategy === 'query'
				? sprintf( __( 'All eligible · max %d', 'fotogenic-ai' ), getMaximum() )
				: sprintf(
					__( '%1$d of %2$d', 'fotogenic-ai' ),
					selectionEstimate(),
					getMaximum()
				);
		};
		const refreshProductSelectionCount = async (selection = currentSelection()) => {
			productSelectionCountToken += 1;
			const requestToken = productSelectionCountToken;
			productSelectionCountController?.abort?.();
			productSelectionCountController = null;
			if (!isStoreQueueSelection() || selection.strategy !== 'query') {
				productSelectionCount = null;
				productSelectionCountSignature = '';
				productSelectionCountPending = false;
				syncSelectionCount();
				return;
			}
			const signature = productSelectionQuerySignature(selection);
			if (productSelectionMatchesCatalogue(selection)) {
				productSelectionCount = pageData.totalItems;
				productSelectionCountSignature = signature;
				productSelectionCountPending = false;
				syncSelectionCount();
				publishBulkMeta();
				return;
			}
			productSelectionCount = null;
			productSelectionCountSignature = signature;
			productSelectionCountPending = true;
			syncSelectionCount();
			productSelectionCountController = typeof AbortController === 'function' ? new AbortController() : null;
			let result = null;
			try {
				result = await transport.getSourcePage('product', {
					query: String(selection.query?.search || ''),
					page: 1,
					perPage: 1,
					filters: {
						categories: Array.isArray(selection.query?.categories) ? selection.query.categories : [],
						stock: Array.isArray(selection.query?.stock) ? selection.query.stock : [],
					},
					bulk: true,
					signal: productSelectionCountController?.signal,
				});
			} catch (error) {
				result = null;
			}
			if (destroyed || requestToken !== productSelectionCountToken) return;
			productSelectionCountController = null;
			productSelectionCountPending = false;
			if (result?.ok) {
				productSelectionCount = Math.max(0, Math.floor(Number(result.data?.totalItems)) || 0);
			}
			syncSelectionCount();
			publishBulkMeta();
		};
        const publishBulkMeta = () => {
            if (route.scope !== 'bulk') return;
            onBulkMeta?.({
                matchingCount: pageData.totalItems,
                selectedCount: isCampaignBulk() ? campaignGroups().length : selectionEstimate(),
                maximum: getMaximum(),
                strategy: currentSelection().strategy,
            });
        };
		const isCampaignBulk = () => route.workflow === 'campaign_set' && route.scope === 'bulk';
		const campaignGroupLimitMessage = () => sprintf(
			__( 'This run supports up to %d Campaign Sets. Remove a set or selected target before adding another.', 'fotogenic-ai' ),
			getMaximum()
		);
		const campaignDrawerConflictMessage = () => __( 'Campaign Sets changed while this drawer was open. Close and reopen it to review the latest groups.', 'fotogenic-ai' );
		const campaignGroupRevision = (groups) => Studio.store.stableStringify(
			(Array.isArray(groups) ? groups : []).map((group) => {
				const revisionGroup = Studio.store.clone(group);
				delete revisionGroup.ordinal;
				return revisionGroup;
			})
		);
		const setCampaignSelectionError = (kind, message) => {
			campaignSelectionErrorKind = kind;
			campaignSelectionError = message;
		};
		const clearCampaignSelectionError = () => {
			campaignSelectionErrorKind = '';
			campaignSelectionError = '';
		};
		const campaignGroups = () => {
            const groups = getSourcePolicy?.()?.groups;
            return Array.isArray(groups) ? groups : [];
		};
		const replaceCampaignGroups = (groups) => {
			if (!Array.isArray(groups) || groups.length > getMaximum()) {
				setCampaignSelectionError('capacity', campaignGroupLimitMessage());
				return false;
			}
			const normalized = (Array.isArray(groups) ? groups : []).map((group, index) => ({
                ...group,
                ordinal: index + 1,
                supportingAttachmentIds: Array.isArray(group.supportingAttachmentIds)
                    ? [...group.supportingAttachmentIds]
                    : [],
            }));
			return onSourcePolicyChange?.({ groups: normalized }) !== false;
        };
		const campaignGroupSource = (item) => {
            const primaryAttachmentId = route.sourceType === 'media'
                ? item?.id
                : item?.sourceAttachmentId;
			return item?.target && Number.isInteger(Number(primaryAttachmentId)) && Number(primaryAttachmentId) > 0
				? { target: { ...item.target }, primaryAttachmentId: Number(primaryAttachmentId) }
				: null;
		};
		const newCampaignGroup = (item) => {
			const source = campaignGroupSource(item);
			if (!source) return null;
			const id = String(Shared.identity?.createSecureUuid?.() || '').toLowerCase();
			if (!UUID_V4_PATTERN.test(id)) return null;
			const defaults = getCampaignGroupDefaults?.() || {};
            return {
                id: String(id).toLowerCase(),
                ordinal: 1,
                subjectId: Number(item.id),
				target: source.target,
				primaryAttachmentId: source.primaryAttachmentId,
				supportingAttachmentIds: [],
				recipe: Studio.store.clone(defaults.recipe || {}),
				resultPolicy: Studio.store.clone(defaults.resultPolicy || {}),
			};
        };
		const campaignGroupsForSelection = (requestedSelectedIds) => {
            const selectedIds = requestedSelectedIds === null
                ? getSelectedIds()
                : normalizeBulkSelection({ selectedIds: requestedSelectedIds }, getMaximum()).selectedIds;
            const selected = new Set(selectedIds);
			let groups = campaignGroups().filter((group) => selected.has(Number(group.subjectId)));
			if (groups.length > getMaximum()) {
				setCampaignSelectionError('capacity', campaignGroupLimitMessage());
				return null;
			}
			for (const subjectId of selectedIds) {
				if (groups.some((group) => Number(group.subjectId) === Number(subjectId))) continue;
				if (groups.length >= getMaximum()) {
					setCampaignSelectionError('capacity', campaignGroupLimitMessage());
					return null;
				}
				const group = newCampaignGroup(selectedItems.get(Number(subjectId)));
                if (!group) return null;
                groups.push(group);
            }
            return groups.map((group, index) => ({ ...group, ordinal: index + 1 }));
        };
        const ensureCampaignGroups = (requestedSelectedIds = null) => {
            if (!isCampaignBulk() || (campaignSelectionUpdating && requestedSelectedIds === null)) return true;
			const groups = campaignGroupsForSelection(requestedSelectedIds);
			if (!groups) {
				if (!campaignSelectionError) {
					const selectedIds = requestedSelectedIds === null ? getSelectedIds() : requestedSelectedIds;
					const sourceMissing = (Array.isArray(selectedIds) ? selectedIds : [])
						.some((subjectId) => !campaignGroupSource(selectedItems.get(Number(subjectId))));
					setCampaignSelectionError(
						sourceMissing ? 'source' : 'identity',
						sourceMissing ? CAMPAIGN_SOURCE_ERROR : CAMPAIGN_IDENTITY_ERROR
					);
				}
				return false;
			}
			clearCampaignSelectionError();
			if (JSON.stringify(groups) !== JSON.stringify(campaignGroups()) && !replaceCampaignGroups(groups)) return false;
			return true;
        };
		const updateCampaignGroupAttachments = (groupId, attachmentIds) => {
            const limit = sourceLimit();
            const ordered = [...new Set((Array.isArray(attachmentIds) ? attachmentIds : [])
                .map(Number)
                .filter((id) => Number.isInteger(id) && id > 0))].slice(0, limit);
			if (!ordered.length) return false;
			return replaceCampaignGroups(campaignGroups().map((group) => (
				group.id === groupId
                    ? { ...group, primaryAttachmentId: ordered[0], supportingAttachmentIds: ordered.slice(1) }
                    : group
            )));
        };
        const syncBulkQueryControls = () => {
            const selection = currentSelection();
			if (route.sourceType === 'product') {
				syncProductSelectionFilterControls();
				return;
			}
            if (route.scope !== 'bulk' || selection.strategy !== 'query') return;
            query = String(selection.query?.search || '').slice(0, 100);
			if (route.sourceType === 'media') {
				mediaFilters = Object.fromEntries(Object.keys(MEDIA_FILTER_DEFAULTS).map((key) => [
					key,
					String(selection.query?.[key] || MEDIA_FILTER_DEFAULTS[key]),
				]));
				mediaFilterDraft = { ...mediaFilters };
			}
            searchInput.value = query;
			productSearchQuery = query;
        };

		const mediaUploadRouteKey = (candidate = route) => [candidate.workflow, candidate.sourceType, candidate.scope].join(':');
		const mediaUploadCapacityMessage = (maximum) => sprintf(
			_n(
				'Maximum of %d image selected. Remove an image to upload another.',
				'Maximum of %d images selected. Remove an image to upload another.',
				maximum,
				'fotogenic-ai'
			),
			maximum
		);
		const releaseMediaUploadSession = (session, { closeFrame = false, restoreFocus = false } = {}) => {
			if (!session || session.released) return;
			session.released = true;
			if (mediaUploadSession === session) mediaUploadSession = null;
			session.controller?.abort?.();
			session.controller = null;
			session.frame?.off?.('open', session.onOpen);
			session.frame?.off?.('select', session.onSelect);
			session.frame?.off?.('close', session.onClose);
			if (closeFrame && !session.closed) {
				session.closed = true;
				session.frame?.close?.();
			}
			session.frame?.remove?.();
			session.frame = null;
			if (restoreFocus) {
				window.setTimeout(() => {
					if (destroyed || session.routeKey !== mediaUploadRouteKey()) return;
					const liveTrigger = root.contains(session.trigger) ? session.trigger : null;
					if (liveTrigger && !liveTrigger.disabled) {
						liveTrigger.focus?.({ preventScroll: true });
						return;
					}
					if (restoreFocusKey(root, session.returnFocusKey)) return;
					root.querySelector('.fotogenic-ai-media-selection-heading')?.querySelector('h3')?.focus?.({ preventScroll: true });
				}, 0);
			}
		};
		const cancelMediaUpload = () => releaseMediaUploadSession(mediaUploadSession, { closeFrame: true });
		const openMediaUpload = ({ replaceId = 0, trigger } = {}) => {
			const replacementId = Math.max(0, Math.floor(Number(replaceId)) || 0);
			const selectedIds = getSelectedIds().map(Number).filter((id) => id > 0);
			if (replacementId && !selectedIds.includes(replacementId)) {
				uploadRecovery = __( 'Your selection changed before replacement started. Choose Replace again for the image you want to update.', 'fotogenic-ai' );
				renderSelected();
				return;
			}
			if (!replacementId && route.scope === 'bulk' && selectionEstimate() >= getMaximum()) {
				uploadRecovery = '';
				status.textContent = mediaUploadCapacityMessage(getMaximum());
				renderSelected();
				return;
			}
			if (typeof window.wp?.media !== 'function' || !window.wp.media.model?.Selection || !window.wp.media.controller?.Library) {
				uploadRecovery = __( 'The WordPress Media Library is unavailable. Refresh this page and try again.', 'fotogenic-ai' );
				renderSelected();
				return;
			}
			cancelMediaUpload();
			const uploadSelection = new window.wp.media.model.Selection([], { multiple: false, props: { type: 'image', query: false } });
			const uploadTitle = replacementId ? __( 'Replace selected image', 'fotogenic-ai' ) : __( 'Upload an image', 'fotogenic-ai' );
			const frame = window.wp.media({
				title: uploadTitle,
				button: { text: replacementId ? __( 'Use replacement', 'fotogenic-ai' ) : __( 'Use image', 'fotogenic-ai' ) },
				state: 'upload',
				selection: uploadSelection,
				states: [new window.wp.media.controller.Library({
					id: 'upload',
					title: uploadTitle,
					content: 'upload',
					router: false,
					menu: false,
					contentUserSetting: false,
					syncSelection: false,
					searchable: false,
					filterable: false,
					library: uploadSelection,
					selection: uploadSelection,
					multiple: false,
				})],
				multiple: false,
			});
			const session = {
				controller: null,
				frame,
				replacementId,
				routeKey: mediaUploadRouteKey(),
				trigger,
				returnFocusKey: replacementId ? `media-replace:${replacementId}` : 'media-upload',
				validating: false,
				closed: false,
				onOpen: null,
				onSelect: null,
				onClose: null,
				released: false,
			};
			const current = () => !destroyed && mediaUploadSession === session && session.routeKey === mediaUploadRouteKey();
			session.onOpen = () => {
				if (current()) frame.content?.mode?.('upload');
			};
			session.onSelect = async () => {
				if (!current() || session.validating) return;
				const chosen = frame.state()?.get?.('selection')?.first?.()?.toJSON?.() || {};
				const attachmentId = Math.floor(Number(chosen.id));
				if (attachmentId <= 0) return;
				session.validating = true;
				session.controller = typeof AbortController === 'function' ? new AbortController() : null;
				status.textContent = __( 'Checking uploaded image…', 'fotogenic-ai' );
				const verified = await validateMediaAttachmentSelection({
					transport,
					attachmentIds: [attachmentId],
					maximum: 1,
					signal: session.controller?.signal,
				});
				if (!current()) return;
				const item = verified.ok ? verified.items[0] : null;
					if (!item?.eligible) {
					uploadRecovery = item?.eligibilityReason || verified.message || __( 'Choose a JPEG, PNG, or WebP image no larger than 25 MiB.', 'fotogenic-ai' );
					renderSelected();
					session.validating = false;
					releaseMediaUploadSession(session, { closeFrame: !session.closed, restoreFocus: true });
						return;
					}
					const currentSelectionState = currentSelection();
					const currentSelectedIds = getSelectedIds().map(Number).filter((id) => id > 0);
					if (session.replacementId && !currentSelectedIds.includes(session.replacementId)) {
						uploadRecovery = __( 'Your selection changed while the replacement was checked. Choose Replace again for the image you want to update.', 'fotogenic-ai' );
						renderSelected();
						session.validating = false;
						releaseMediaUploadSession(session, { closeFrame: !session.closed, restoreFocus: true });
						return;
					}
					const replacementIndex = session.replacementId
						? currentSelectedIds.indexOf(session.replacementId)
						: -1;
					const remainingSelectedIds = currentSelectedIds.filter((id) => id !== session.replacementId && id !== item.id);
					const nextSelectedIds = [...remainingSelectedIds];
					if (replacementIndex >= 0) nextSelectedIds.splice(Math.min(replacementIndex, nextSelectedIds.length), 0, item.id);
					else nextSelectedIds.unshift(item.id);
					const nextEstimate = currentSelectionState.strategy === 'query'
						? selectionEstimate() + (currentSelectionState.selectedIds.includes(item.id) ? 0 : 1) - (session.replacementId ? 1 : 0)
						: nextSelectedIds.length;
					if (route.scope === 'bulk' && nextEstimate > getMaximum()) {
						uploadRecovery = '';
						status.textContent = mediaUploadCapacityMessage(getMaximum());
						renderSelected();
						session.validating = false;
						releaseMediaUploadSession(session, { closeFrame: !session.closed, restoreFocus: true });
						return;
					}
					const hadPreviousItem = selectedItems.has(item.id);
					const previousItem = selectedItems.get(item.id);
					selectedItems.set(item.id, item);
					const committed = route.scope === 'bulk'
						? commitSelection({
							strategy: currentSelectionState.strategy,
							selectedIds: nextSelectedIds,
							excludedIds: currentSelectionState.strategy === 'query' ? currentSelectionState.excludedIds : [],
							query: currentSelectionState.strategy === 'query' ? currentSelectionState.query : {},
						})
						: commitSelection({ strategy: 'explicit', selectedIds: [item.id], excludedIds: [], query: {} });
					if (!committed) {
						if (hadPreviousItem) selectedItems.set(item.id, previousItem);
						else selectedItems.delete(item.id);
						uploadRecovery = campaignSelectionError || __( 'Studio could not add the verified image to this selection. Review your current sources and try again.', 'fotogenic-ai' );
						renderSelected();
						session.validating = false;
						releaseMediaUploadSession(session, { closeFrame: !session.closed, restoreFocus: true });
						return;
					}
					uploadedSessionIds.add(item.id);
					uploadRecovery = '';
					session.returnFocusKey = `media-replace:${item.id}`;
					status.textContent = __( 'Uploaded image verified.', 'fotogenic-ai' );
					renderSelected();
				session.validating = false;
				releaseMediaUploadSession(session, { closeFrame: !session.closed, restoreFocus: true });
			};
			session.onClose = () => {
				session.closed = true;
				if (!session.validating) releaseMediaUploadSession(session, { restoreFocus: true });
			};
			frame.on('open', session.onOpen);
			frame.on('select', session.onSelect);
			frame.on('close', session.onClose);
			mediaUploadSession = session;
			frame.open();
		};

		const mediaItemDetail = (item) => item.width > 0 && item.height > 0
			? sprintf(__( '%1$d × %2$d', 'fotogenic-ai' ), item.width, item.height)
			: (item.detail || [mimeLabel(item.mime), formatBytes(item.bytes)].filter(Boolean).join(' · '));

		const renderMediaSelectedRail = () => {
			selectedRegion.hidden = false;
			selectedRegion.className = 'fotogenic-ai-source-picker__selected fotogenic-ai-media-selection-rail';
			const selectedIds = getSelectedIds();
			const maximum = getMaximum();
			const uploadAtCapacity = route.scope === 'bulk' && selectionEstimate() >= maximum;
			const upload = setFocusKey(element('button', 'fotogenic-ai-media-upload-button', __( 'Upload image', 'fotogenic-ai' )), 'media-upload');
			upload.type = 'button';
			upload.disabled = uploadAtCapacity;
			upload.prepend(createIcon('upload-simple', { weight: 'regular', size: 18 }));
			upload.addEventListener('click', () => openMediaUpload({ trigger: upload }));
			selectedRegion.appendChild(upload);
			if (uploadAtCapacity) {
				const uploadLimit = element('small', 'fotogenic-ai-media-upload-limit', mediaUploadCapacityMessage(maximum));
				uploadLimit.id = 'fotogenic-ai-media-upload-limit';
				upload.setAttribute('aria-describedby', uploadLimit.id);
				selectedRegion.appendChild(uploadLimit);
			}
			if (uploadRecovery) {
				const recovery = element('div', 'fotogenic-ai-media-upload-recovery');
				recovery.setAttribute('role', 'alert');
				const recoveryCopy = element('span');
				recoveryCopy.append(
					element('strong', '', __( 'Upload not added', 'fotogenic-ai' )),
					element('small', '', uploadRecovery)
				);
					const choose = element('button', 'fotogenic-ai-media-upload-retry', __( 'Choose another', 'fotogenic-ai' ));
				choose.type = 'button';
				choose.addEventListener('click', () => openMediaUpload({ trigger: choose }));
				const dismiss = element('button');
				dismiss.type = 'button';
				dismiss.setAttribute('aria-label', __( 'Dismiss upload error', 'fotogenic-ai' ));
				dismiss.appendChild(createIcon('x', { weight: 'regular', size: 16 }));
				dismiss.addEventListener('click', () => {
					uploadRecovery = '';
					renderSelected();
					restoreFocusKey(root, 'media-upload');
				});
				recovery.append(createIcon('warning', { weight: 'fill', size: 17 }), recoveryCopy, choose, dismiss);
				selectedRegion.appendChild(recovery);
			}
			const heading = element('div', 'fotogenic-ai-media-selection-heading');
			const title = route.workflow === 'campaign_set' ? __( 'Campaign sets', 'fotogenic-ai' ) : __( 'Selected', 'fotogenic-ai' );
				const selectedHeading = element('h3', '', sprintf(__( '%1$s · %2$d of %3$d', 'fotogenic-ai' ), title, selectedIds.length, maximum));
				selectedHeading.tabIndex = -1;
				heading.appendChild(selectedHeading);
				const clear = element('button', 'fotogenic-ai-source-text-button', __( 'Clear all', 'fotogenic-ai' ));
			clear.type = 'button';
			clear.disabled = selectedIds.length === 0;
			clear.addEventListener('click', () => {
				if (route.scope === 'bulk') {
					commitSelection({ strategy: 'explicit', selectedIds: [], excludedIds: [], query: {} });
				} else {
					const item = selectedItems.get(selectedIds[0]);
					if (item) toggleItem(item);
				}
			});
			heading.appendChild(clear);
			selectedRegion.appendChild(heading);
			if (route.workflow === 'campaign_set' && selectedIds.length) {
				selectedRegion.appendChild(element('p', 'fotogenic-ai-campaign-media-help', __( 'Each selected image starts its own Campaign Set. Add supporting angles only when they belong to that same item.', 'fotogenic-ai' )));
			}
			const selected = selectedIds.map((id) => selectedItems.get(Number(id)) || {
				id: Number(id),
				label: sprintf(__( 'Media %d', 'fotogenic-ai' ), Number(id)),
				imageUrl: '',
				eligible: false,
				eligibilityReason: __( 'This saved source is no longer available. Replace or remove it to continue.', 'fotogenic-ai' ),
			});
			const invalidCount = selected.filter((item) => !item.eligible).length;
			if (invalidCount) {
				const warning = element('div', 'fotogenic-ai-media-selected-warning');
				warning.setAttribute('role', 'alert');
				warning.append(createIcon('warning', { weight: 'fill', size: 17 }), element('span', '', sprintf(
					_n( '%d selected item needs attention. Remove or replace it before continuing.', '%d selected items need attention. Remove or replace them before continuing.', invalidCount, 'fotogenic-ai' ),
					invalidCount
				)));
				selectedRegion.appendChild(warning);
			}
			const list = element('div', 'fotogenic-ai-selected-media-list');
			selected.forEach((item) => {
				const row = element('div', `fotogenic-ai-selected-media-row${item.eligible ? '' : ' is-ineligible'}`);
				if (item.imageUrl) {
					const image = element('img');
					image.src = item.imageUrl;
					image.alt = '';
					image.decoding = 'async';
					row.appendChild(image);
				} else {
					row.appendChild(createIcon('image-square', { weight: 'regular', size: 24 }));
				}
				const copy = element('div');
				const group = campaignGroups().find((candidate) => Number(candidate.subjectId) === item.id);
				copy.append(
					element('strong', '', item.label),
					element('small', '', item.eligible
						? (route.workflow === 'campaign_set'
							? sprintf(_n( '%d source image', '%d source images', 1 + (group?.supportingAttachmentIds?.length || 0), 'fotogenic-ai' ), 1 + (group?.supportingAttachmentIds?.length || 0))
							: mediaItemDetail(item))
						: item.eligibilityReason)
				);
				const actions = element('span', 'fotogenic-ai-selected-media-actions');
				if (item.eligible && route.workflow === 'campaign_set') {
					const angles = setFocusKey(element('button', 'fotogenic-ai-media-role-button', group?.supportingAttachmentIds?.length
						? sprintf(_n( '%d angle', '%d angles', group.supportingAttachmentIds.length, 'fotogenic-ai' ), group.supportingAttachmentIds.length)
						: __( 'Add angles', 'fotogenic-ai' )), `campaign-angles:${item.id}`);
					angles.type = 'button';
					angles.setAttribute('aria-haspopup', 'dialog');
					angles.addEventListener('click', () => openCampaignMediaAngles(item, angles));
					actions.appendChild(angles);
				}
				if (uploadedSessionIds.has(item.id) || !item.eligible) {
					const replace = setFocusKey(element('button', 'fotogenic-ai-media-role-button', __( 'Replace', 'fotogenic-ai' )), `media-replace:${item.id}`);
					replace.type = 'button';
					replace.addEventListener('click', () => openMediaUpload({ replaceId: item.id, trigger: replace }));
					actions.appendChild(replace);
				}
				const remove = element('button');
				remove.type = 'button';
				remove.setAttribute('aria-label', sprintf(__( 'Remove %s', 'fotogenic-ai' ), item.label));
				remove.appendChild(createIcon('x', { weight: 'regular', size: 19 }));
				remove.addEventListener('click', () => {
					if (route.scope === 'bulk') {
						commitSelection({
							strategy: 'explicit',
							selectedIds: selectedIds.filter((id) => Number(id) !== item.id),
							excludedIds: [],
							query: {},
						});
					} else {
						toggleItem(item);
					}
				});
				actions.appendChild(remove);
				row.append(copy, actions);
				list.appendChild(row);
			});
			if (!selected.length) {
				const empty = element('div', 'fotogenic-ai-selected-media-empty');
				empty.append(
					createIcon('image-square', { weight: 'regular', size: 24 }),
					element('strong', '', __( 'No images selected', 'fotogenic-ai' )),
					element('small', '', __( 'Select images from the gallery to add them here.', 'fotogenic-ai' ))
				);
				list.appendChild(empty);
			}
			selectedRegion.appendChild(list);
			publishBulkMeta();
			syncContinuePlacement();
		};
		const hydrateSelectedMedia = async () => {
			if (route.sourceType !== 'media') return;
			const ids = getSelectedIds().map(Number).filter((id) => id > 0);
			if (!ids.length) return;
			const token = ++mediaSummaryToken;
			mediaSummaryController?.abort?.();
			mediaSummaryController = typeof AbortController === 'function' ? new AbortController() : null;
			const responses = await Promise.all(ids.map((id) => transport.getSourceSummary('media', id, { signal: mediaSummaryController?.signal })));
			if (token !== mediaSummaryToken || route.sourceType !== 'media') return;
			mediaSummaryController = null;
			responses.forEach((response, index) => {
				const item = response?.ok ? normalizeItem(response.data, 'media') : null;
				if (item) {
					selectedItems.set(item.id, item);
					return;
				}
				const previousItem = selectedItems.get(ids[index]);
				selectedItems.set(ids[index], {
					...(previousItem || { id: ids[index], label: sprintf(__( 'Media %d', 'fotogenic-ai' ), ids[index]), imageUrl: '' }),
					eligible: false,
					eligibilityReason: response?.message || __( 'This saved source is no longer available. Replace or remove it to continue.', 'fotogenic-ai' ),
				});
			});
			renderSelected();
			renderResults();
		};

		const renderSelected = () => {
			selectedRegion.replaceChildren();
			const selection = currentSelection();
			selectedRegion.className = route.sourceType === 'media'
				? 'fotogenic-ai-source-picker__selected fotogenic-ai-media-selection-rail'
				: 'fotogenic-ai-source-picker__selected';
            if (route.scope === 'bulk' && selection.strategy === 'query') {
                selectedRegion.hidden = true;
                publishBulkMeta();
                return;
            }
			if (route.sourceType === 'media') {
				renderMediaSelectedRail();
				return;
			}
			const selectedIds = getSelectedIds();
			const usesTableSelection = route.sourceType === 'product'
				|| (route.scope === 'bulk' && ['post', 'page'].includes(route.sourceType));
			if (usesTableSelection) {
				selectedRegion.hidden = true;
				publishBulkMeta();
				return;
			}
			if (!selectedIds.length) {
				selectedRegion.classList.remove('is-single-preview');
				selectedRegion.hidden = true;
				return;
            }
            selectedRegion.hidden = false;
            if (route.scope === 'single') {
                const item = selectedItems.get(selectedIds[0]) || {
                    id: selectedIds[0],
                    label: sprintf( __( 'Selected %s', 'fotogenic-ai' ), Studio.i18n.labels[route.sourceType] || route.sourceType ),
                    detail: '',
                    imageUrl: '',
                    eligible: true,
                };
                selectedRegion.classList.add('is-single-preview');
                const preview = element('article', 'fotogenic-ai-source-picker__selected-preview');
                if (item.imageUrl) {
                    const image = element('img', 'fotogenic-ai-source-picker__selected-image');
                    image.src = item.imageUrl;
                    image.alt = '';
                    image.decoding = 'async';
                    preview.appendChild(image);
                }
                const copy = element('div', 'fotogenic-ai-source-picker__selected-copy');
                copy.append(
                    element('span', 'fotogenic-ai-studio-eyebrow', __( 'Selected source', 'fotogenic-ai' )),
                    element('strong', '', item.label)
                );
                if (item.detail) copy.appendChild(element('span', 'fotogenic-ai-studio-empty-copy', item.detail));
                const change = setFocusKey(element('button', 'secondary', __( 'Change source', 'fotogenic-ai' )), `source:${item.id}`);
                change.type = 'button';
                change.setAttribute('aria-label', sprintf( __( 'Change source: %s', 'fotogenic-ai' ), item.label ));
                change.addEventListener('click', () => {
					toggleItem(item);
                    window.setTimeout(() => searchInput.focus(), 0);
                });
                copy.appendChild(change);
                preview.appendChild(copy);
				selectedRegion.appendChild(preview);
                publishBulkMeta();
                return;
            }
            selectedRegion.classList.remove('is-single-preview');
            const heading = element('h4', '', route.scope === 'bulk' ? sprintf( __( 'Selected (%d)', 'fotogenic-ai' ), selectedIds.length ) : __( 'Selected source', 'fotogenic-ai' ));
            const list = element('div', 'fotogenic-ai-source-picker__selected-list');
            selectedIds.forEach((id) => {
                const item = selectedItems.get(id) || { id, label: sprintf( __( 'Item %d', 'fotogenic-ai' ), id ), detail: '', eligible: true };
                const row = element('div', 'fotogenic-ai-source-picker__selected-item');
                const copy = element('span', '', item.label);
                if (!sourceEligibleForMode(item, route, getSourceMode())) {
					copy.appendChild(element('span', 'fotogenic-ai-studio-empty-copy', __( ': unavailable for the selected image source mode', 'fotogenic-ai' )));
                }
                const remove = setFocusKey(element('button', 'fotogenic-ai-source-text-button', __( 'Remove', 'fotogenic-ai' )), `selected:${item.id}`);
                remove.type = 'button';
                remove.setAttribute('aria-label', sprintf( __( 'Remove %s', 'fotogenic-ai' ), item.label ));
				remove.addEventListener('click', () => toggleItem(item));
                row.append(copy, remove);
                list.appendChild(row);
            });
            selectedRegion.append(heading, list);
            publishBulkMeta();
        };

        const applyProductAttachments = (attachmentIds) => {
            const limit = sourceLimit();
            const existingCount = sourceAttachmentIds().length;
            const maximum = Math.max(limit, existingCount);
            const normalized = [];
            const seen = new Set();
            (Array.isArray(attachmentIds) ? attachmentIds : []).some((value) => {
                const id = Math.floor(Number(value));
                if (id > 0 && !seen.has(id)) {
                    seen.add(id);
                    normalized.push(id);
                }
                return normalized.length >= maximum;
            });
            onSourcePolicyChange?.({ attachmentIds: normalized });
        };

        const renderProductImages = (productId, images) => {
            const focusKey = activeFocusKey(policyRegion);
            policyRegion.replaceChildren();
			const eligibleImages = images.filter((image) => image.eligible);
			if (!eligibleImages.length) {
				policyRegion.appendChild(element(
					'p',
					'fotogenic-ai-studio-empty-copy',
					images.find((image) => image.eligibilityReason)?.eligibilityReason
						|| __( 'This Product has no eligible featured or gallery image.', 'fotogenic-ai' )
				));
                return;
            }

            const limit = sourceLimit();
			const singleImage = limit === 1;
			const availableIds = eligibleImages.map((image) => image.id);
            let selected = sourceAttachmentIds()
                .map(Number)
                .filter((id, index, values) => availableIds.includes(id) && values.indexOf(id) === index);
            const applyDefault = !selected.length;
            if (applyDefault) {
				selected = [eligibleImages[0].id];
            }
            const applyAttachments = applyProductAttachments;

			if (singleImage) {
				const chooser = element('div', 'fotogenic-ai-product-image-select');
				const image = eligibleImages.find((candidate) => candidate.id === selected[0]);
				if (image.imageUrl) {
					const preview = element('img', 'fotogenic-ai-source-picker__thumb');
					preview.src = image.imageUrl;
					preview.alt = '';
					chooser.appendChild(preview);
				}
				const label = element('label');
				const select = setFocusKey(element('select', 'fotogenic-ai-studio-control'), `product-source:${productId}`);
				select.setAttribute('aria-label', __( 'Source image', 'fotogenic-ai' ));
				images.forEach((candidate) => {
					const option = element('option', '', candidate.eligible
						? candidate.label
						: `${candidate.label}: ${candidate.eligibilityReason || __( 'Unavailable', 'fotogenic-ai' )}`);
					option.value = String(candidate.id);
					option.disabled = !candidate.eligible;
					select.appendChild(option);
				});
				select.value = String(image.id);
				select.addEventListener('change', () => {
					const id = Number(select.value);
					if (availableIds.includes(id)) applyAttachments([id]);
				});
				label.append(element('span', '', __( 'Source image', 'fotogenic-ai' )), createSelectShell(select));
				chooser.appendChild(label);
				policyRegion.appendChild(chooser);
				if (applyDefault) applyAttachments(selected);
				restoreFocusKey(policyRegion, focusKey);
				return;
			}

            const headingRow = element('div', 'fotogenic-ai-studio-pane__heading-row');
            const copy = element('div');
            copy.append(
				element('h4', '', __( 'Product images', 'fotogenic-ai' )),
                element(
					'p',
					'fotogenic-ai-studio-empty-copy',
					__( 'Choose the primary image first, then add only the angles that preserve useful product detail.', 'fotogenic-ai' )
				)
            );
			headingRow.append(copy, element(
				'span',
				'fotogenic-ai-studio-count',
				`${selected.length} / ${limit}`
			));
            if (selected.length > limit) {
                const excess = selected.length - limit;
                copy.appendChild(element('p', 'fotogenic-ai-studio-empty-copy', sprintf(
                    _n( 'Remove %d source image to fit the current source and reference limit.', 'Remove %d source images to fit the current source and reference limit.', excess, 'fotogenic-ai' ),
                    excess
                )));
            }
            const list = element('div', 'fotogenic-ai-source-picker__results');
            images.forEach((image) => {
                const isPrimary = selected[0] === image.id;
                const isSelected = selected.includes(image.id);
				const row = element('article', 'fotogenic-ai-source-picker__item');
				if (image.imageUrl) {
					const preview = element('img', 'fotogenic-ai-source-picker__thumb');
					preview.src = image.imageUrl;
					preview.alt = '';
					preview.loading = 'lazy';
					preview.decoding = 'async';
					row.appendChild(preview);
				}
                const imageCopy = element('div', 'fotogenic-ai-source-picker__item-copy');
                imageCopy.appendChild(element('strong', '', image.label));
				if (!image.eligible) imageCopy.appendChild(element('span', 'fotogenic-ai-studio-empty-copy', image.eligibilityReason || __( 'This image is not eligible.', 'fotogenic-ai' )));
                const actions = element('div', 'fotogenic-ai-studio-actions');
                const primary = setFocusKey(
                    element('button', 'secondary small', isPrimary ? __( 'Primary', 'fotogenic-ai' ) : __( 'Make primary', 'fotogenic-ai' )),
                    `product-primary:${image.id}`
                );
                primary.type = 'button';
				primary.disabled = !image.eligible;
                primary.setAttribute('aria-pressed', isPrimary ? 'true' : 'false');
                primary.setAttribute('aria-label', sprintf( __( '%1$s: %2$s', 'fotogenic-ai' ), isPrimary ? __( 'Primary image', 'fotogenic-ai' ) : __( 'Make primary', 'fotogenic-ai' ), image.label ));
                primary.addEventListener('click', () => {
                    applyAttachments([image.id, ...selected.filter((id) => id !== image.id)]);
                });
                actions.appendChild(primary);
                if (!isPrimary) {
                    const angle = setFocusKey(
                        element('button', 'secondary small', isSelected ? __( 'Remove angle', 'fotogenic-ai' ) : __( 'Add angle', 'fotogenic-ai' )),
                        `product-angle:${image.id}`
                    );
                    angle.type = 'button';
                    angle.setAttribute('aria-pressed', isSelected ? 'true' : 'false');
					angle.disabled = !image.eligible || (!isSelected && selected.length >= limit);
                    if (image.eligible && angle.disabled) {
                        const reasonId = `fotogenic-source-limit-${productId}-${image.id}`;
                        angle.setAttribute('aria-describedby', reasonId);
                        const reason = element('span', 'fotogenic-ai-studio-empty-copy', sprintf( __( 'The %d-image workflow limit is reached.', 'fotogenic-ai' ), limit ));
                        reason.id = reasonId;
                        imageCopy.appendChild(reason);
                    }
                    angle.addEventListener('click', () => {
                        applyAttachments(isSelected
                            ? selected.filter((id) => id !== image.id)
                            : [...selected, image.id]);
                    });
                    actions.appendChild(angle);
                }
				row.append(imageCopy, actions);
                list.appendChild(row);
            });
            policyRegion.append(headingRow, list);
            if (applyDefault) applyAttachments(selected);
            restoreFocusKey(policyRegion, focusKey);
        };

        const loadProductContext = async (productId) => {
            policyRegion.setAttribute('aria-busy', 'false');
            if (productContexts.has(productId)) {
                renderProductImages(productId, productContexts.get(productId));
                return;
            }
            const token = ++productContextToken;
            productContextController?.abort?.();
            productContextController = typeof AbortController === 'function' ? new AbortController() : null;
            policyRegion.setAttribute('aria-busy', 'true');
            policyRegion.replaceChildren(requestState({ message: __( 'Loading Product images…', 'fotogenic-ai' ), loading: true }));
            const response = await transport.getProductContext(productId, { signal: productContextController?.signal });
            if (token !== productContextToken || !getSelectedIds().includes(productId)) {
                return;
            }
            productContextController = null;
            policyRegion.setAttribute('aria-busy', 'false');
            if (!response.ok) {
                policyRegion.replaceChildren(requestState({
                    message: response.message || __( 'Product images could not be loaded.', 'fotogenic-ai' ),
                    onRetry: () => loadProductContext(productId),
                }));
                return;
            }
            const images = normalizeProductImages(response.data);
            productContexts.set(productId, images);
            renderProductImages(productId, images);
        };

        const renderSourcePolicy = () => {
            policyRegion.setAttribute('aria-busy', 'false');
            productContextToken += 1;
            productContextController?.abort?.();
            productContextController = null;
            if (isCampaignBulk()) {
				policyRegion.replaceChildren();
                return;
            }
            if (route.sourceType !== 'product') {
                policyRegion.replaceChildren();
                return;
            }
			if (route.scope === 'bulk') {
				policyRegion.replaceChildren();
				return;
			}
            const productId = getSelectedIds()[0];
            if (!productId) {
                policyRegion.replaceChildren();
                return;
            }
            loadProductContext(productId);
        };

		const closeCampaignOverlay = (options = {}) => {
			campaignToken += 1;
			campaignController?.abort?.();
			campaignController = null;
			campaignOverlay?.close?.(options);
			campaignOverlay?.destroy?.();
			campaignLayer?.remove?.();
			campaignOverlay = null;
			campaignLayer = null;
			campaignOverlaySync = null;
			campaignOverlaySyncSuspended = false;
		};

		const mountCampaignOverlay = ({ panel, layerClass, trigger, initialFocus }) => {
			if (!variationHost || !Shared.ui?.containedOverlay?.create) return false;
			closeCampaignOverlay({ restoreFocus: false });
			campaignReturnFocus = trigger || null;
			campaignLayer = element('div', `fotogenic-ai-campaign-layer ${layerClass}`);
			campaignLayer.appendChild(panel);
			variationHost.appendChild(campaignLayer);
			campaignOverlay = Shared.ui.containedOverlay.create({
				layer: campaignLayer,
				panel,
				onClose: () => closeCampaignOverlay(),
			});
			campaignOverlay.open({ returnFocus: campaignReturnFocus, initialFocus });
			return true;
		};

		const openCampaignProductSets = (parentItem, trigger) => {
			if (route.workflow !== 'campaign_set' || route.sourceType !== 'product') return;
			const variationTargets = selectedVariationsForParent(parentItem.id);
			const targets = variationTargets.length
				? variationTargets
				: (getSelectedIds().includes(parentItem.id) ? [parentItem] : []);
			if (!targets.length) return;
			const panel = element('section', 'fotogenic-ai-campaign-product-sets-drawer');
			panel.setAttribute('aria-labelledby', 'fotogenic-ai-campaign-product-sets-title');
			const heading = element('h2', '', __( 'Campaign Sets', 'fotogenic-ai' ));
			heading.id = 'fotogenic-ai-campaign-product-sets-title';
			heading.tabIndex = -1;
			heading.setAttribute('data-fa-overlay-heading', '');
			const header = element('header', 'fotogenic-ai-campaign-product-sets-heading');
			const headingCopy = element('div');
			headingCopy.append(heading, element('p', '', parentItem.label));
			const close = element('button');
			close.type = 'button';
			close.setAttribute('aria-label', __( 'Close Campaign Sets', 'fotogenic-ai' ));
			close.appendChild(createIcon('x', { weight: 'regular', size: 18 }));
			close.addEventListener('click', () => closeCampaignOverlay());
			header.append(headingCopy, close);
			const intro = element('div', 'fotogenic-ai-campaign-product-sets-intro');
			const capacityStatus = element('strong', 'fotogenic-ai-campaign-product-capacity');
			const capacityError = element('p', 'fotogenic-ai-campaign-product-capacity-error');
			capacityError.setAttribute('role', 'alert');
			capacityError.hidden = true;
			intro.append(
				element('strong', '', __( 'Build independent image groups', 'fotogenic-ai' )),
				element('p', '', __( 'Each set becomes its own Campaign Set request for the exact Product or variation shown below.', 'fotogenic-ai' )),
				capacityStatus,
				capacityError
			);
			const targetsHost = element('div', 'fotogenic-ai-campaign-product-targets');
			const footer = element('footer', 'fotogenic-ai-campaign-product-sets-footer');
			const cancel = element('button', 'secondary', __( 'Cancel', 'fotogenic-ai' ));
			const apply = element('button', 'primary', __( 'Apply Campaign Sets', 'fotogenic-ai' ));
			cancel.type = 'button';
			apply.type = 'button';
			cancel.addEventListener('click', () => closeCampaignOverlay());
			footer.append(cancel, apply);
			panel.append(header, intro, targetsHost, footer);
			if (!mountCampaignOverlay({ panel, layerClass: 'fotogenic-ai-campaign-product-sets-layer', trigger, initialFocus: heading })) return;

			const loadTargets = async () => {
				const token = ++campaignToken;
				campaignController?.abort?.();
				campaignController = typeof AbortController === 'function' ? new AbortController() : null;
				const controller = campaignController;
				const isCurrent = () => token === campaignToken && campaignOverlay?.isOpen?.();
				apply.disabled = true;
				targetsHost.setAttribute('aria-busy', 'true');
				targetsHost.replaceChildren(requestState({ message: __( 'Loading Product images…', 'fotogenic-ai' ), loading: true }));
				const responses = await Promise.all(targets.map(async (targetItem) => {
					const cached = productContexts.get(targetItem.id);
					if (cached) return { targetItem, images: cached.filter((image) => image.eligible) };
					const response = await transport.getProductContext(targetItem.id, { signal: controller?.signal });
					if (!isCurrent()) return null;
					if (!response?.ok) return { error: response?.message || __( 'Product images could not be loaded.', 'fotogenic-ai' ) };
					const images = normalizeProductImages(response.data);
					productContexts.set(targetItem.id, images);
					return { targetItem, images: images.filter((image) => image.eligible) };
				}));
				if (!isCurrent()) return;
				campaignController = null;
				targetsHost.setAttribute('aria-busy', 'false');
				const failure = responses.find((response) => response?.error);
				if (failure) {
					targetsHost.replaceChildren(requestState({ message: failure.error, onRetry: loadTargets }));
					return;
				}
				renderLoadedTargets(responses);
			};

			const renderLoadedTargets = (responses) => {
				const targetIds = new Set(targets.map((item) => Number(item.id)));
				const liveTargetGroups = () => campaignGroups().filter((group) => targetIds.has(Number(group.subjectId)));
				const initialTargetRevision = campaignGroupRevision(liveTargetGroups());
				const targetGroupsChanged = () => campaignGroupRevision(liveTargetGroups()) !== initialTargetRevision;
				let draftGroups = Studio.store.clone(liveTargetGroups());
				let capacityErrorMessage = '';
				const otherGroups = () => campaignGroups().filter((group) => !targetIds.has(Number(group.subjectId)));
				const projectedGroupCount = () => otherGroups().length + draftGroups.length;
				targets.forEach((targetItem) => {
					if (draftGroups.some((group) => Number(group.subjectId) === targetItem.id)) return;
					if (projectedGroupCount() >= getMaximum()) return;
					const group = newCampaignGroup(targetItem);
					if (group) draftGroups.push(group);
				});

				const renderDrawer = () => {
					const projectedCount = projectedGroupCount();
					const targetConflict = targetGroupsChanged();
					const visibleError = targetConflict
						? campaignDrawerConflictMessage()
						: (projectedCount > getMaximum() ? campaignGroupLimitMessage() : capacityErrorMessage);
					capacityStatus.textContent = sprintf(
						__( '%1$d of %2$d Campaign Sets', 'fotogenic-ai' ),
						projectedCount,
						getMaximum()
					);
					capacityError.textContent = visibleError;
					capacityError.hidden = !visibleError;
					targetsHost.replaceChildren();
					responses.forEach(({ targetItem, images }) => {
						const section = element('section', 'fotogenic-ai-campaign-product-target');
						const sectionHeader = element('header');
						const identity = element('div', 'fotogenic-ai-campaign-product-target-identity');
						if (targetItem.imageUrl) {
							const image = element('img');
							image.src = targetItem.imageUrl;
							image.alt = '';
							identity.appendChild(image);
						}
						const identityCopy = element('span');
						identityCopy.append(
							element('strong', '', targetItem.label),
							element('small', '', targetItem.sku || sprintf(__( 'ID %d', 'fotogenic-ai' ), targetItem.id))
						);
						identity.appendChild(identityCopy);
						const targetGroups = draftGroups.filter((group) => Number(group.subjectId) === targetItem.id);
						sectionHeader.append(identity, element('span', '', sprintf(_n( '%d set', '%d sets', targetGroups.length, 'fotogenic-ai' ), targetGroups.length)));
						section.appendChild(sectionHeader);
						if (!images.length) {
							section.appendChild(element('p', 'fotogenic-ai-studio-empty-copy', __( 'This target has no eligible Product images.', 'fotogenic-ai' )));
							targetsHost.appendChild(section);
							return;
						}
						const list = element('div', 'fotogenic-ai-campaign-product-group-list');
						targetGroups.forEach((group, groupIndex) => {
							const selectedAttachments = [Number(group.primaryAttachmentId), ...(group.supportingAttachmentIds || []).map(Number)];
							const card = element('article', 'fotogenic-ai-campaign-product-group-card');
							const cardHeading = element('div', 'fotogenic-ai-campaign-product-group-card-heading');
							const cardCopy = element('div');
							cardCopy.append(
								element('strong', '', sprintf(__( 'Set %d', 'fotogenic-ai' ), groupIndex + 1)),
								element('small', '', sprintf(_n( '%d source image', '%d source images', selectedAttachments.length, 'fotogenic-ai' ), selectedAttachments.length))
							);
							const remove = element('button');
							remove.type = 'button';
							remove.disabled = targetGroups.length <= 1;
							remove.setAttribute('aria-label', sprintf(__( 'Remove Set %1$d from %2$s', 'fotogenic-ai' ), groupIndex + 1, targetItem.label));
							remove.appendChild(createIcon('x', { weight: 'regular', size: 19 }));
							remove.addEventListener('click', () => {
								capacityErrorMessage = '';
								draftGroups = draftGroups.filter((candidate) => candidate.id !== group.id);
								renderDrawer();
							});
							cardHeading.append(cardCopy, remove);
							const primary = element('label', 'fotogenic-ai-campaign-product-primary-select');
							primary.appendChild(element('span', '', __( 'Primary image', 'fotogenic-ai' )));
							const primaryControl = element('span', 'fotogenic-ai-campaign-product-primary-control');
							const activeImage = images.find((image) => image.id === Number(group.primaryAttachmentId)) || images[0];
							if (activeImage?.imageUrl) {
								const preview = element('img');
								preview.src = activeImage.imageUrl;
								preview.alt = '';
								primaryControl.appendChild(preview);
							}
							const select = element('select');
							images.forEach((image) => {
								const option = element('option', '', image.label);
								option.value = String(image.id);
								select.appendChild(option);
							});
							select.value = String(activeImage.id);
							select.addEventListener('change', () => {
								group.primaryAttachmentId = Number(select.value);
								group.supportingAttachmentIds = (group.supportingAttachmentIds || []).filter((id) => Number(id) !== Number(select.value));
								renderDrawer();
							});
							primaryControl.append(select, createIcon('caret-down', { weight: 'bold', size: 14 }));
							primary.appendChild(primaryControl);
							const supporting = element('fieldset', 'fotogenic-ai-campaign-product-supporting-images');
							const legend = element('legend');
							legend.append(
								document.createTextNode(__( 'Supporting images ', 'fotogenic-ai' )),
								element('span', '', sprintf(__( 'Optional · up to %d', 'fotogenic-ai' ), Math.max(0, sourceLimit() - 1)))
							);
							supporting.appendChild(legend);
							const supportingGrid = element('div');
							images.filter((image) => image.id !== Number(group.primaryAttachmentId)).forEach((image) => {
								const checked = (group.supportingAttachmentIds || []).map(Number).includes(image.id);
								const option = element('label');
								const checkbox = element('input');
								checkbox.type = 'checkbox';
								checkbox.checked = checked;
								checkbox.disabled = !checked && selectedAttachments.length >= sourceLimit();
								checkbox.addEventListener('change', () => {
									group.supportingAttachmentIds = checkbox.checked
										? [...(group.supportingAttachmentIds || []), image.id]
										: (group.supportingAttachmentIds || []).filter((id) => Number(id) !== image.id);
									renderDrawer();
								});
								if (image.imageUrl) {
									const preview = element('img');
									preview.src = image.imageUrl;
									preview.alt = '';
									option.append(checkbox, preview, element('span', '', image.label));
								} else {
									option.append(checkbox, element('span', '', image.label));
								}
								supportingGrid.appendChild(option);
							});
							supporting.appendChild(supportingGrid);
							card.append(cardHeading, primary, supporting);
							list.appendChild(card);
						});
						section.appendChild(list);
						const add = element('button', 'fotogenic-ai-campaign-product-add-set', __( 'Add another Campaign Set', 'fotogenic-ai' ));
						add.type = 'button';
						add.disabled = targetConflict || projectedCount >= getMaximum();
						add.prepend(createIcon('images', { weight: 'regular', size: 16 }));
						add.addEventListener('click', () => {
							if (targetGroupsChanged()) {
								capacityErrorMessage = campaignDrawerConflictMessage();
								renderDrawer();
								return;
							}
							if (projectedGroupCount() >= getMaximum()) {
								capacityErrorMessage = campaignGroupLimitMessage();
								renderDrawer();
								return;
							}
							const next = newCampaignGroup(targetItem);
							if (next) {
								capacityErrorMessage = '';
								next.primaryAttachmentId = images[0].id;
								draftGroups.push(next);
								renderDrawer();
							}
						});
						section.appendChild(add);
						targetsHost.appendChild(section);
					});
					apply.disabled = targetConflict
						|| projectedCount > getMaximum()
						|| responses.some(({ images }) => !images.length)
						|| targets.some((targetItem) => !draftGroups.some((group) => Number(group.subjectId) === targetItem.id));
				};
				apply.addEventListener('click', () => {
					if (apply.disabled) return;
					if (targetGroupsChanged()) {
						capacityErrorMessage = campaignDrawerConflictMessage();
						renderDrawer();
						return;
					}
					const combinedGroups = [...otherGroups(), ...draftGroups];
					if (combinedGroups.length > getMaximum()) {
						capacityErrorMessage = campaignGroupLimitMessage();
						renderDrawer();
						return;
					}
					let replaced = false;
					campaignOverlaySyncSuspended = true;
					try {
						replaced = replaceCampaignGroups(combinedGroups);
					} finally {
						campaignOverlaySyncSuspended = false;
					}
					if (!replaced) {
						capacityErrorMessage = campaignSelectionError || campaignGroupLimitMessage();
						renderDrawer();
						return;
					}
					closeCampaignOverlay({ restoreFocus: false });
					renderResults();
					restoreFocusKey(root, `campaign-sets:${parentItem.id}`);
				});
				campaignOverlaySync = () => {
					if (!campaignOverlaySyncSuspended && campaignOverlay?.isOpen?.()) renderDrawer();
				};
				renderDrawer();
			};
			void loadTargets();
		};

		const openCampaignMediaAngles = (primaryItem, trigger) => {
			if (route.workflow !== 'campaign_set' || route.sourceType !== 'media') return;
			const group = campaignGroups().find((candidate) => Number(candidate.subjectId) === primaryItem.id);
			if (!group) return;
			let draftIds = [...(group.supportingAttachmentIds || [])].map(Number).filter((id) => id > 0);
			let anglesLoading = true;
			let anglesError = '';
			const panel = element('section', 'fotogenic-ai-campaign-angle-drawer');
			panel.setAttribute('aria-labelledby', 'fotogenic-ai-campaign-angle-title');
			const header = element('header', 'fotogenic-ai-campaign-angle-header');
			if (primaryItem.imageUrl) {
				const image = element('img');
				image.src = primaryItem.imageUrl;
				image.alt = '';
				header.appendChild(image);
			}
			const titleCopy = element('div');
			const heading = element('h2', '', __( 'Sources for this Campaign Set', 'fotogenic-ai' ));
			heading.id = 'fotogenic-ai-campaign-angle-title';
			heading.tabIndex = -1;
			heading.setAttribute('data-fa-overlay-heading', '');
			titleCopy.append(heading, element('p', '', sprintf(__( '%s remains the primary source.', 'fotogenic-ai' ), primaryItem.label)));
			const count = element('strong');
			const close = element('button');
			close.type = 'button';
			close.setAttribute('aria-label', __( 'Close supporting angle selector', 'fotogenic-ai' ));
			close.appendChild(createIcon('x', { weight: 'regular', size: 18 }));
			close.addEventListener('click', () => closeCampaignOverlay());
			header.append(titleCopy, count, close);
			const searchRegion = element('div', 'fotogenic-ai-campaign-angle-search');
			const searchLabel = element('label', 'fotogenic-ai-select-search');
			const angleSearch = element('input', 'fotogenic-ai-studio-control');
			angleSearch.type = 'search';
			angleSearch.maxLength = 100;
			angleSearch.placeholder = __( 'Search supporting angles…', 'fotogenic-ai' );
			angleSearch.setAttribute('aria-label', __( 'Search supporting angles', 'fotogenic-ai' ));
			searchLabel.append(createIcon('magnifying-glass', { weight: 'bold', size: 18 }), angleSearch);
			const limitStatus = element('p');
			limitStatus.setAttribute('role', 'status');
			searchRegion.append(searchLabel, limitStatus);
			const conflictStatus = element('p', 'fotogenic-ai-campaign-angle-conflict');
			conflictStatus.setAttribute('role', 'alert');
			conflictStatus.hidden = true;
			const list = element('div', 'fotogenic-ai-campaign-angle-list');
			list.setAttribute('role', 'list');
			const pagination = element('div', 'fotogenic-ai-campaign-angle-pagination fotogenic-ai-overlay-pagination');
			const previousButton = element('button');
			const pageCopy = element('strong');
			const nextButton = element('button');
			previousButton.type = 'button';
			nextButton.type = 'button';
			previousButton.setAttribute('aria-label', __( 'Previous supporting image page', 'fotogenic-ai' ));
			nextButton.setAttribute('aria-label', __( 'Next supporting image page', 'fotogenic-ai' ));
			previousButton.appendChild(createIcon('arrow-left', { weight: 'regular', size: 14 }));
			nextButton.appendChild(createIcon('arrow-right', { weight: 'regular', size: 14 }));
			pagination.hidden = true;
			pagination.append(previousButton, pageCopy, nextButton);
			const footer = element('footer', 'fotogenic-ai-campaign-angle-footer');
			const cancel = element('button', 'secondary', __( 'Cancel', 'fotogenic-ai' ));
			const apply = element('button', 'primary');
			cancel.type = 'button';
			apply.type = 'button';
			cancel.addEventListener('click', () => closeCampaignOverlay());
			footer.append(cancel, apply);
			const initialGroupRevision = campaignGroupRevision([group]);
			const groupChanged = () => {
				const liveGroup = campaignGroups().find((candidate) => candidate.id === group.id);
				return !liveGroup || campaignGroupRevision([liveGroup]) !== initialGroupRevision;
			};
			const renderSelectionSummary = () => {
				const selectedCount = 1 + draftIds.length;
				const conflict = groupChanged();
				count.textContent = sprintf(__( '%1$d of %2$d images', 'fotogenic-ai' ), selectedCount, sourceLimit());
				apply.textContent = sprintf(_n( 'Apply %d source image', 'Apply %d source images', selectedCount, 'fotogenic-ai' ), selectedCount);
				apply.disabled = conflict || anglesLoading || Boolean(anglesError);
				conflictStatus.textContent = conflict ? campaignDrawerConflictMessage() : '';
				conflictStatus.hidden = !conflict;
			};
			panel.append(header, searchRegion, conflictStatus, list, pagination, footer);
			if (!mountCampaignOverlay({ panel, layerClass: 'fotogenic-ai-campaign-angle-layer', trigger, initialFocus: heading })) return;

			let anglePage = 1;
			let angleData = { items: [], page: 1, totalPages: 1, totalItems: 0 };
			const primaryIds = new Set(getSelectedIds().map(Number));
			const maximumAngles = Math.max(0, sourceLimit() - 1);
			const renderAngles = () => {
				renderSelectionSummary();
				limitStatus.textContent = draftIds.length >= maximumAngles
					? __( 'Limit reached. Remove an angle to select another.', 'fotogenic-ai' )
					: sprintf(__( 'Select up to %d images that show the same item from useful supporting angles.', 'fotogenic-ai' ), maximumAngles);
				list.replaceChildren();
				const visibleItems = angleData.items.filter((item) => item.id !== primaryItem.id && !primaryIds.has(item.id));
				if (!visibleItems.length) {
					const empty = element('div', 'fotogenic-ai-campaign-angle-empty');
					empty.append(element('strong', '', __( 'No matching images', 'fotogenic-ai' )), element('p', '', __( 'Try a broader search.', 'fotogenic-ai' )));
					list.appendChild(empty);
				} else {
					visibleItems.forEach((item) => {
						const checked = draftIds.includes(item.id);
						const atLimit = !checked && draftIds.length >= maximumAngles;
						const row = element('label', `fotogenic-ai-campaign-angle-row${checked ? ' is-selected' : ''}${item.eligible && !atLimit ? '' : ' is-disabled'}`);
						row.setAttribute('role', 'listitem');
						const checkbox = element('input');
						checkbox.type = 'checkbox';
						checkbox.checked = checked;
						checkbox.disabled = !item.eligible || atLimit;
						checkbox.addEventListener('change', () => {
							draftIds = checkbox.checked ? [...draftIds, item.id] : draftIds.filter((id) => id !== item.id);
							renderAngles();
						});
						if (item.imageUrl) {
							const image = element('img');
							image.src = item.imageUrl;
							image.alt = '';
							row.append(checkbox, image);
						} else {
							row.appendChild(checkbox);
						}
						const copy = element('span');
						copy.append(element('strong', '', item.label), element('small', '', item.eligible ? mediaItemDetail(item) : item.eligibilityReason));
						row.appendChild(copy);
						list.appendChild(row);
					});
				}
				pageCopy.textContent = sprintf(__( '%1$d / %2$d', 'fotogenic-ai' ), angleData.page, angleData.totalPages);
				pageCopy.setAttribute('aria-label', sprintf(__( 'Page %1$d of %2$d', 'fotogenic-ai' ), angleData.page, angleData.totalPages));
				previousButton.disabled = angleData.page <= 1;
				nextButton.disabled = angleData.page >= angleData.totalPages;
				pagination.hidden = angleData.totalPages <= 1;
			};
			renderSelectionSummary();
			const showAngleRequestState = () => {
				list.setAttribute('aria-busy', anglesLoading ? 'true' : 'false');
				pagination.hidden = true;
				limitStatus.textContent = '';
				list.replaceChildren(requestState({
					message: anglesLoading ? __( 'Loading supporting images…', 'fotogenic-ai' ) : anglesError,
					loading: anglesLoading,
					onRetry: anglesLoading ? null : loadAngles,
				}));
				renderSelectionSummary();
			};
			const loadAngles = async () => {
				if (!campaignLayer?.contains(panel) || !campaignOverlay?.isOpen?.()) return;
				const token = ++campaignToken;
				campaignController?.abort?.();
				campaignController = typeof AbortController === 'function' ? new AbortController() : null;
				const angleController = campaignController;
				anglesLoading = true;
				anglesError = '';
				showAngleRequestState();
				const response = await transport.getSourcePage('media', {
					query: angleSearch.value,
					page: anglePage,
					perPage: 8,
					filters: { ...MEDIA_FILTER_DEFAULTS },
					bulk: true,
					signal: angleController?.signal,
				});
				if (token !== campaignToken || !campaignOverlay?.isOpen?.()) return;
				if (!response?.ok) {
					campaignController = null;
					anglesLoading = false;
					anglesError = response?.message || __( 'Supporting images could not be loaded.', 'fotogenic-ai' );
					showAngleRequestState();
					return;
				}
				const pageIds = new Set(response.data.items.map((item) => Number(item?.id)));
				const missingSelectedIds = draftIds.filter((id) => !pageIds.has(id));
				const selectedResponses = await Promise.all(missingSelectedIds.map((id) => transport.getSourceSummary('media', id, { signal: angleController?.signal })));
				if (token !== campaignToken || !campaignOverlay?.isOpen?.()) return;
				campaignController = null;
				const selectedItemsForPage = selectedResponses
					.map((selectedResponse) => selectedResponse?.ok ? normalizeItem(selectedResponse.data, 'media') : null)
					.filter(Boolean);
				anglesLoading = false;
				if (selectedItemsForPage.length !== missingSelectedIds.length) {
					anglesError = __( 'Selected images could not be checked. Try again before applying changes.', 'fotogenic-ai' );
					showAngleRequestState();
					return;
				}
				list.setAttribute('aria-busy', 'false');
				angleData = {
					...response.data,
					items: [
						...selectedItemsForPage,
						...response.data.items.map((item) => normalizeItem(item, 'media')).filter(Boolean),
					],
				};
				renderAngles();
			};
			let searchTimer = 0;
			angleSearch.addEventListener('input', () => {
				window.clearTimeout(searchTimer);
				campaignToken += 1;
				campaignController?.abort?.();
				anglesLoading = true;
				anglesError = '';
				showAngleRequestState();
				searchTimer = window.setTimeout(() => {
					anglePage = 1;
					void loadAngles();
				}, SEARCH_DELAY);
			});
			previousButton.addEventListener('click', () => {
				anglePage = Math.max(1, angleData.page - 1);
				void loadAngles();
			});
			nextButton.addEventListener('click', () => {
				anglePage = Math.min(100, angleData.page + 1);
				void loadAngles();
			});
			apply.addEventListener('click', () => {
				renderSelectionSummary();
				if (apply.disabled) return;
				let updated = false;
				campaignOverlaySyncSuspended = true;
				try {
					updated = updateCampaignGroupAttachments(group.id, [primaryItem.id, ...draftIds]);
				} finally {
					campaignOverlaySyncSuspended = false;
				}
				if (!updated) {
					conflictStatus.textContent = campaignSelectionError || campaignDrawerConflictMessage();
					conflictStatus.hidden = false;
					return;
				}
				closeCampaignOverlay({ restoreFocus: false });
				renderSelected();
				restoreFocusKey(root, `campaign-angles:${primaryItem.id}`);
			});
			campaignOverlaySync = () => {
				if (!campaignOverlaySyncSuspended && campaignOverlay?.isOpen?.()) renderSelectionSummary();
			};
			void loadAngles();
		};

		const notifySelectionChange = (selection) => (
			typeof onSelectionChange === 'function' && onSelectionChange(selection) !== false
		);

		const commitSelection = (selection) => {
			const requestedQuery = selection.strategy === 'query'
				&& selection.query
				&& typeof selection.query === 'object'
				&& !Array.isArray(selection.query)
				? selection.query
				: currentQuery();
            const normalized = {
                strategy: selection.strategy === 'query' ? 'query' : 'explicit',
                selectedIds: [...new Set((selection.selectedIds || []).map(Number).filter((id) => id > 0))],
                excludedIds: [...new Set((selection.excludedIds || []).map(Number).filter((id) => id > 0))],
				query: selection.strategy === 'query' ? {
					search: String(requestedQuery.search || '').trim().replace(/\s+/g, ' ').slice(0, 100),
					...(route.sourceType === 'product' ? {
						categories: [...new Set((requestedQuery.categories || []).map(Number).filter((id) => id > 0))].slice(0, 50),
						stock: [...new Set((requestedQuery.stock || []).map(String).filter((value) => ['instock', 'outofstock', 'onbackorder'].includes(value)))],
					} : {}),
					...(route.sourceType === 'media' ? {
						type: String(requestedQuery.type || 'all'),
						date: String(requestedQuery.date || 'all'),
						orientation: String(requestedQuery.orientation || 'all'),
						size: String(requestedQuery.size || 'all'),
					} : {}),
				} : {},
            };
			if (route.scope !== 'bulk') {
				if (normalized.strategy !== 'explicit' || normalized.selectedIds.length > getMaximum()) return false;
				return notifySelectionChange(normalized);
			}
			if (!isCampaignBulk()) {
				const committed = notifySelectionChange(normalized);
				if (committed && isStoreQueueSelection()) void refreshProductSelectionCount(normalized);
				return committed;
			}
			clearCampaignSelectionError();
			const groups = campaignGroupsForSelection(normalized.selectedIds);
			if (!groups) {
				if (!campaignSelectionError) {
					const sourceMissing = normalized.selectedIds
						.some((subjectId) => !campaignGroupSource(selectedItems.get(Number(subjectId))));
					setCampaignSelectionError(
						sourceMissing ? 'source' : 'identity',
						sourceMissing ? CAMPAIGN_SOURCE_ERROR : CAMPAIGN_IDENTITY_ERROR
					);
				}
				renderResults({ skipCampaignGroupSync: true });
				return false;
			}
			clearCampaignSelectionError();
			campaignSelectionUpdating = true;
			try {
				if (!replaceCampaignGroups(groups)) return false;
				return notifySelectionChange(normalized);
			} finally {
				campaignSelectionUpdating = false;
			}
		};

		const itemMatchesSelectionFilters = (itemId) => {
			if (!isStoreQueueSelection()) return true;
			const item = selectedItems.get(itemId);
			const { categories, stock } = productSelectionFilters();
			return (!categories.length || categories.some((id) => item?.categories?.includes(id)))
				&& (!stock.length || stock.includes(item?.stockStatus));
		};
		const itemSelected = (itemId, eligible = true) => {
			const selection = currentSelection();
			if (selection.strategy !== 'query') return selection.selectedIds.includes(itemId);
			return eligible && (selection.selectedIds.includes(itemId)
				|| (itemMatchesSelectionFilters(itemId) && !selection.excludedIds.includes(itemId)));
		};
		const reportSelectionLimit = () => {
			const message = sprintf(__( 'This run already has %d sources. Clear a selection to add another.', 'fotogenic-ai' ), getMaximum());
			status.textContent = message;
			Studio.notify?.warning?.(message, { title: __( 'Selection limit reached', 'fotogenic-ai' ) });
		};

		const toggleItem = (item) => {
			if (!item?.eligible) return false;
			const selection = currentSelection();
			const maximum = getMaximum();
			if (selection.strategy === 'query') {
				if (route.scope !== 'bulk') return false;
				const matchesQuery = itemMatchesSelectionFilters(item.id);
				const wasSelected = itemSelected(item.id);
				const selectedIds = selection.selectedIds.filter((id) => id !== item.id);
				let excludedIds = selection.excludedIds.filter((id) => id !== item.id);
				if (!wasSelected && !matchesQuery) selectedIds.push(item.id);
				if (wasSelected && matchesQuery) {
					excludedIds.push(item.id);
					if (!isStoreQueueSelection()) excludedIds = excludedIds.slice(0, maximum);
				}
				return commitSelection({ ...selection, selectedIds, excludedIds });
			}
			const selected = selection.selectedIds.includes(item.id)
				? selection.selectedIds.filter((id) => id !== item.id)
				: (route.scope === 'single' ? [item.id] : [...selection.selectedIds, item.id]);
			if (selected.length > maximum) {
				reportSelectionLimit();
				return false;
			}
			return commitSelection({ strategy: 'explicit', selectedIds: selected, excludedIds: [], query: {} });
		};

		const eligiblePageIds = () => pageData.items
				.filter((item) => sourceEligibleForMode(item, route, getSourceMode()))
				.map((item) => item.id);
		const pageSelectionComplete = () => {
			const eligibleIds = eligiblePageIds();
			return eligibleIds.length > 0 && eligibleIds.every((id) => itemSelected(id));
		};
		const pageSelectionStarted = () => eligiblePageIds().some((id) => itemSelected(id));
		const availablePageIds = () => eligiblePageIds().filter((id) => !itemSelected(id))
			.slice(0, Math.max(0, getMaximum() - selectionEstimate()));
		const selectCurrentPage = () => {
			const eligibleIds = availablePageIds();
			if (!eligibleIds.length) {
				reportSelectionLimit();
				return;
			}
			const result = selectBulkPage(currentSelection(), eligibleIds, getMaximum());
            if (!result.ok) {
                status.textContent = sprintf( __( 'This page would exceed the %d-source maximum.', 'fotogenic-ai' ), getMaximum() );
                return;
            }
			commitSelection(result.selection);
		};
		const clearCurrentPage = () => {
			const eligibleIds = new Set(eligiblePageIds());
			const selection = currentSelection();
			if (selection.strategy === 'query') {
				commitSelection({
					...selection,
					selectedIds: selection.selectedIds.filter((id) => !eligibleIds.has(id)),
					excludedIds: isStoreQueueSelection()
						? [...new Set([...selection.excludedIds, ...eligibleIds])]
						: [...new Set([...selection.excludedIds, ...eligibleIds])].slice(0, getMaximum()),
				});
				return;
			}
			commitSelection({
				strategy: 'explicit',
				selectedIds: selection.selectedIds.filter((id) => !eligibleIds.has(id)),
				excludedIds: [],
				query: {},
			});
		};
		const toggleCurrentPage = () => {
			if (pageSelectionStarted()) clearCurrentPage();
			else selectCurrentPage();
			results.querySelectorAll('thead input[type="checkbox"]').forEach((checkbox) => {
				checkbox.checked = pageSelectionComplete();
				checkbox.indeterminate = pageSelectionStarted() && !checkbox.checked;
			});
		};
		const selectAllMatching = () => {
			if (!isStoreQueueSelection() || pageData.totalItems < 1) return false;
			return commitSelection({ strategy: 'query', selectedIds: [], excludedIds: [], query: currentQuery() });
		};
		const toggleProductQuerySelection = (event) => {
			if (!event.target.checked) {
				commitSelection({ strategy: 'explicit', selectedIds: [], excludedIds: [], query: {} });
			} else {
				selectAllMatching();
			}
			renderResults();
		};
		const loadCategories = async () => {
			if (categoriesLoaded) {
				categoryFilter.setDisabled(false);
				syncProductSelectionFilterControls();
				return;
			}
			if (categoriesLoading) return;
            categoryController?.abort?.();
            const token = ++categoryToken;
            categoryController = typeof AbortController === 'function' ? new AbortController() : null;
			categoriesLoading = true;
			categoryFilter.setDisabled(true);
            const response = await transport.getProductCategories?.({ signal: categoryController?.signal });
			if (destroyed || token !== categoryToken) return;
            categoryController = null;
			categoriesLoading = false;
            if (response?.ok) {
				quickCategories = response.data.filter((category) => Number(category.count) > 0)
					.sort((a, b) => Number(b.count) - Number(a.count)).slice(0, 3);
				categoryFilter.setOptions(response.data.map((category) => ({
					value: String(category.id),
					label: `${category.name} (${category.count})`,
				})));
				categoriesLoaded = true;
				syncProductSelectionFilterControls();
            }
			categoryFilter.setDisabled(!categoriesLoaded);
			if (productSearchOpen) renderProductSearchPopover();
		};

		const finishProductSearchClose = () => {
			productSearchCloseTimer = 0;
			productSearchPopover.classList.remove('is-closing');
			productSearchPopover.hidden = true;
		};
		const closeProductSearch = ({ restoreFocus = false, immediate = false } = {}) => {
			if (!productSearchOpen && !productSearchPopover.classList.contains('is-open')) return;
			productSearchOpen = false;
			window.clearTimeout(productSearchCloseTimer);
			productSearchPopover.classList.remove('is-open');
			productSearchPopover.classList.add('is-closing');
			searchInput.setAttribute('aria-expanded', 'false');
			searchControl.classList.remove('is-open');
			const delay = immediate ? 0 : popoverCloseDelay();
			if (delay) productSearchCloseTimer = window.setTimeout(finishProductSearchClose, delay);
			else finishProductSearchClose();
			if (restoreFocus) {
				suppressProductSearchFocus = true;
				searchInput.focus({ preventScroll: true });
				window.queueMicrotask(() => {
					suppressProductSearchFocus = false;
				});
			}
		};
		const openProductSearch = () => {
			if (!isProductDiscovery()) return;
			const bounds = searchControl.getBoundingClientRect?.();
			if (bounds && window.innerHeight) {
				const bottom = Math.min(window.innerHeight, selectView?.getBoundingClientRect?.().bottom || window.innerHeight);
				productSearchPopover.style.setProperty('--fa-search-available-height', `${Math.max(160, bottom - bounds.bottom - 12)}px`);
			}
			window.clearTimeout(productSearchCloseTimer);
			productSearchCloseTimer = 0;
			productSearchOpen = true;
			productSearchPopover.hidden = false;
			productSearchPopover.classList.remove('is-closing');
			productSearchPopover.classList.add('is-open');
			searchInput.setAttribute('aria-expanded', 'true');
			searchControl.classList.add('is-open');
			renderProductSearchPopover();
		};
		const runProductQuickSearch = ({ category = '', stock = '' } = {}) => {
			query = '';
			productSearchQuery = '';
			searchInput.value = '';
			filters.categories = category ? [Number(category)] : [];
			filters.stock = stock ? [stock] : [];
			page = 1;
			closeProductSearch();
			applyBulkFilterChange();
		};
		const renderProductSearchPopover = () => {
			if (!productSearchOpen || !isProductDiscovery()) {
				if (!productSearchPopover.classList.contains('is-closing')) productSearchPopover.hidden = true;
				return;
			}
			productSearchPopover.hidden = false;
			productSearchPopover.classList.add('is-open');
			const normalizedQuery = productSearchQuery.trim();
			productSearchPopover.setAttribute('aria-busy', productSearchPending ? 'true' : 'false');
			if (productSearchPending && productSearchPopover.querySelector('.fotogenic-ai-product-search-loading')) return;
			const previousScroll = productSearchPopover.querySelector('.fotogenic-ai-product-search-results')?.scrollTop || 0;
			productSearchPopover.replaceChildren();
			const section = element('div', 'fotogenic-ai-product-search-section');
			if (productSearchPending) {
				section.appendChild(element(
					'strong',
					'fotogenic-ai-product-search-section__title',
					normalizedQuery ? __( 'Searching all products', 'fotogenic-ai' ) : __( 'Loading products', 'fotogenic-ai' )
				));
				const loading = element('div', 'fotogenic-ai-product-search-loading');
				loading.setAttribute('role', 'status');
				loading.setAttribute('aria-live', 'polite');
				const spinner = createIcon('arrows-clockwise', { size: 20 });
				spinner.classList.add('fotogenic-ai-icon--spin');
				loading.append(
					spinner,
					element('span', '', normalizedQuery
						? __( 'Searching product names, exact SKUs, and IDs…', 'fotogenic-ai' )
						: __( 'Loading the Product catalog…', 'fotogenic-ai' ))
				);
				section.appendChild(loading);
				productSearchPopover.appendChild(section);
				return;
			}
			if (productSearchError) {
				section.appendChild(element('strong', 'fotogenic-ai-product-search-section__title', __( 'Product search unavailable', 'fotogenic-ai' )));
				const error = element('div', 'fotogenic-ai-product-search-empty');
				error.setAttribute('role', 'alert');
				error.append(
					element('strong', '', productSearchError.message || __( 'Products could not be loaded.', 'fotogenic-ai' )),
					element('small', '', __( 'Check your connection, then try the search again.', 'fotogenic-ai' ))
				);
				const retry = element('button', 'secondary small', __( 'Try again', 'fotogenic-ai' ));
				retry.type = 'button';
				retry.addEventListener('click', () => {
					loadProductSuggestions();
				});
				error.appendChild(retry);
				section.appendChild(error);
				productSearchPopover.appendChild(section);
				return;
			}
			section.appendChild(element(
				'strong',
				'fotogenic-ai-product-search-section__title',
				normalizedQuery.length >= PRODUCT_SEARCH_MIN_LENGTH
					? sprintf(
						_n( '%d catalog match', '%d catalog matches', productSearchPage?.totalItems || 0, 'fotogenic-ai' ),
						productSearchPage?.totalItems || 0
					)
					: __( 'Find products', 'fotogenic-ai' )
			));
			const visibleItems = normalizedQuery.length >= PRODUCT_SEARCH_MIN_LENGTH && productSearchResultQuery === normalizedQuery
				? (productSearchPage?.items || []).slice(0, PRODUCT_SEARCH_RESULT_LIMIT) : [];
			if (visibleItems.length) {
				const list = element('div', 'fotogenic-ai-product-search-results');
				visibleItems.forEach((item, index) => {
					const eligible = sourceEligibleForMode(item, route, getSourceMode());
					const row = element('label', 'fotogenic-ai-product-search-result');
					const checkbox = element('input');
					checkbox.type = 'checkbox';
					setFocusKey(checkbox, `search-source:${item.id}`);
					checkbox.checked = itemSelected(item.id, eligible);
					checkbox.disabled = !eligible;
					checkbox.setAttribute('aria-label', sprintf(__( 'Select %s', 'fotogenic-ai' ), item.label));
					checkbox.addEventListener('change', () => {
						if (!toggleItem(item)) checkbox.checked = itemSelected(item.id, eligible);
					});
					checkbox.addEventListener('keydown', (event) => {
						if (event.key === 'Escape') {
							event.preventDefault();
							closeProductSearch({ restoreFocus: true });
							return;
						}
						if (!['ArrowDown', 'ArrowUp'].includes(event.key)) return;
						event.preventDefault();
						const controls = [...productSearchPopover.querySelectorAll('.fotogenic-ai-product-search-result input:not(:disabled)')];
						const current = controls.indexOf(checkbox);
						const offset = event.key === 'ArrowDown' ? 1 : -1;
						controls[(current + offset + controls.length) % controls.length]?.focus();
					});
					row.appendChild(checkbox);
					if (item.imageUrl) {
						const image = element('img');
						image.src = item.imageUrl;
						image.alt = '';
						row.appendChild(image);
					} else {
						const placeholder = element('span', 'fotogenic-ai-product-search-result__placeholder');
						placeholder.appendChild(createIcon('image-square', { weight: 'regular', size: 17 }));
						row.appendChild(placeholder);
					}
					const copy = element('span');
					copy.append(
						element('strong', '', item.label),
						element('small', '', [
							sprintf(__( 'ID %d', 'fotogenic-ai' ), item.id),
							item.categoryNames[0] || item.sku,
							item.stockStatus ? (item.stockStatus === 'instock' ? __( 'In stock', 'fotogenic-ai' ) : item.stockStatus) : '',
						].filter(Boolean).join(' · '))
					);
					row.appendChild(copy);
					list.appendChild(row);
				});
				section.appendChild(list);
				const showAll = element('button', 'fotogenic-ai-product-search-show-all', sprintf(__( 'Show all %d results', 'fotogenic-ai' ), productSearchPage.totalItems));
				showAll.type = 'button';
				showAll.addEventListener('click', () => {
					if (!query && !sourceLoading) {
						cataloguePage = pageData;
						catalogueScrollTop = results.querySelector('.fotogenic-ai-select-table-wrap')?.scrollTop || 0;
					}
					searchController.cancel();
					resetInfiniteState();
					query = normalizedQuery;
					pageData = productSearchPage;
					page = pageData.page;
					sourceLoading = false;
					sourceLoadError = null;
					reconcileBulkSelectionAfterDiscoveryChange();
					closeProductSearch({ immediate: true });
					renderResults();
					results.querySelector('.fotogenic-ai-select-table-wrap')?.focus({ preventScroll: true });
				});
				section.appendChild(showAll);
			} else {
				const empty = element('div', 'fotogenic-ai-product-search-empty');
				empty.append(
					element('strong', '', normalizedQuery.length >= PRODUCT_SEARCH_MIN_LENGTH
						? __( 'No matching products', 'fotogenic-ai' ) : __( 'Search by product name, SKU or ID', 'fotogenic-ai' )),
					element('small', '', __( 'Type at least 2 characters, or choose a category below.', 'fotogenic-ai' ))
				);
				section.appendChild(empty);
			}
			productSearchPopover.appendChild(section);
			const resultList = section.querySelector('.fotogenic-ai-product-search-results');
			if (resultList) resultList.scrollTop = previousScroll;
			if (normalizedQuery.length < PRODUCT_SEARCH_MIN_LENGTH) {
				const quickSection = element('div', 'fotogenic-ai-product-search-section fotogenic-ai-product-search-section--quick');
				quickSection.appendChild(element('strong', 'fotogenic-ai-product-search-section__title', __( 'Quick searches', 'fotogenic-ai' )));
				const quickSearches = element('div', 'fotogenic-ai-product-quick-searches');
				const quickOptions = [
					{ label: __( 'In stock', 'fotogenic-ai' ), stock: 'instock' },
					...quickCategories.map((category) => ({
						label: category.name,
						category: String(category.id),
					})),
				];
				quickOptions.forEach((quick) => {
					const button = element('button', '', quick.label);
					button.type = 'button';
					button.addEventListener('click', () => runProductQuickSearch(quick));
					quickSearches.appendChild(button);
				});
				quickSection.appendChild(quickSearches);
				productSearchPopover.appendChild(quickSection);
			}
		};
		const dismissProductSearch = (event) => {
			if (productSearchOpen && !searchControl.contains(event.target)) closeProductSearch();
		};
		document.addEventListener('pointerdown', dismissProductSearch);

		const renderMediaGrid = () => {
			if (!pageData.items.length) {
				const empty = element('div', 'fotogenic-ai-media-no-results');
				empty.append(
					createIcon('image-square', { weight: 'regular', size: 28 }),
					element('strong', '', __( 'No matching images', 'fotogenic-ai' )),
					element('p', '', __( 'Try a broader search or reset the active filters.', 'fotogenic-ai' ))
				);
				const reset = element('button', 'secondary small', __( 'Clear search and filters', 'fotogenic-ai' ));
				reset.type = 'button';
				reset.addEventListener('click', () => {
					query = '';
					searchInput.value = '';
					mediaFilters = { ...MEDIA_FILTER_DEFAULTS };
					mediaFilterDraft = { ...MEDIA_FILTER_DEFAULTS };
					page = 1;
					renderMediaFilters();
					applyBulkFilterChange();
				});
				empty.appendChild(reset);
				results.appendChild(empty);
				return;
			}
			const grid = element('div', 'fotogenic-ai-media-grid');
			grid.setAttribute('role', 'list');
			grid.setAttribute('aria-label', __( 'Available media', 'fotogenic-ai' ));
			pageData.items.forEach((item) => {
				const eligible = sourceEligibleForMode(item, route, getSourceMode());
				const checked = route.scope === 'bulk'
					? itemSelected(item.id, eligible)
					: getSelectedIds().includes(item.id);
				const capacityBlocked = route.scope === 'bulk' && !checked && selectionEstimate() >= getMaximum();
				const capacityReason = capacityBlocked
					? sprintf(__( '%d-source maximum reached. Deselect one source to choose this image.', 'fotogenic-ai' ), getMaximum())
					: '';
				const tile = element('article', `fotogenic-ai-media-tile${checked ? ' is-selected' : ''}${eligible ? '' : ' is-ineligible'}${capacityBlocked ? ' is-capacity-blocked' : ''}`);
				tile.setAttribute('role', 'listitem');
				const button = setFocusKey(element('button', 'fotogenic-ai-media-thumbnail'), `source:${item.id}`);
				button.type = 'button';
				button.disabled = !eligible || capacityBlocked;
				button.setAttribute('aria-pressed', checked ? 'true' : 'false');
				button.setAttribute('aria-label', capacityBlocked
					? sprintf(__( '%1$s unavailable: %2$s', 'fotogenic-ai' ), item.label, capacityReason)
					: (eligible
					? sprintf(__( '%1$s %2$s', 'fotogenic-ai' ), checked ? __( 'Deselect', 'fotogenic-ai' ) : __( 'Select', 'fotogenic-ai' ), item.label)
					: sprintf(__( '%1$s unavailable: %2$s', 'fotogenic-ai' ), item.label, item.eligibilityReason)));
				if (item.imageUrl) {
					const image = element('img');
					image.src = item.imageUrl;
					image.alt = '';
					image.loading = 'lazy';
					image.decoding = 'async';
					button.appendChild(image);
				}
				const check = element('span', 'fotogenic-ai-media-check', checked ? '✓' : '');
				check.setAttribute('aria-hidden', 'true');
				button.appendChild(check);
				button.addEventListener('click', () => toggleItem(item));
				const detail = element('small', '', capacityReason || (eligible ? mediaItemDetail(item) : item.eligibilityReason));
				if (capacityBlocked) {
					detail.id = `fotogenic-ai-media-capacity-${item.id}`;
					button.setAttribute('aria-describedby', detail.id);
				}
				tile.append(
					button,
					element('strong', '', item.label),
					detail
				);
				grid.appendChild(tile);
			});
			results.appendChild(grid);
		};

		const contentStatusClass = (statusValue) => {
			if (statusValue === 'publish') return ' is-published';
			if (statusValue === 'draft' || statusValue === 'pending') return ' is-draft';
			if (statusValue === 'future') return ' is-scheduled';
			if (statusValue === 'private') return ' is-private';
			return '';
		};
		const renderContentTable = () => {
			if (!pageData.items.length) {
				results.appendChild(element('p', 'fotogenic-ai-studio-empty-copy', query ? __( 'No matching sources.', 'fotogenic-ai' ) : __( 'No editable sources are available.', 'fotogenic-ai' )));
				return;
			}
			const label = route.sourceType === 'post' ? __( 'Post', 'fotogenic-ai' ) : __( 'Page', 'fotogenic-ai' );
			const wrap = element('div', 'fotogenic-ai-select-table-wrap fotogenic-ai-content-source-table-wrap');
			wrap.setAttribute('role', 'region');
			wrap.setAttribute('aria-label', sprintf(__( '%s source results', 'fotogenic-ai' ), label));
			wrap.tabIndex = 0;
			wrap.addEventListener('keydown', handleScrollableResultsKeyDown);
			const table = element('table', 'fotogenic-ai-bulk-source-table fotogenic-ai-content-source-table');
			const head = element('thead');
			const headRow = element('tr');
			const checkHeading = element('th', 'fotogenic-ai-bulk-source-table__check');
			const pageCheckbox = element('input');
			pageCheckbox.type = 'checkbox';
			pageCheckbox.checked = pageSelectionComplete();
			pageCheckbox.indeterminate = pageSelectionStarted() && !pageCheckbox.checked;
			pageCheckbox.disabled = eligiblePageIds().length === 0;
			pageCheckbox.setAttribute('aria-label', sprintf(__( 'Select eligible %ss on this page', 'fotogenic-ai' ), label));
			pageCheckbox.addEventListener('change', toggleCurrentPage);
			checkHeading.appendChild(pageCheckbox);
			headRow.append(
				checkHeading,
				element('th', '', label),
				element('th', '', __( 'Status', 'fotogenic-ai' )),
				element('th', '', __( 'Author', 'fotogenic-ai' )),
				element('th', '', __( 'Source image', 'fotogenic-ai' ))
			);
			head.appendChild(headRow);
			const body = element('tbody');
			pageData.items.forEach((item) => {
				const eligible = sourceEligibleForMode(item, route, getSourceMode());
				const checked = itemSelected(item.id, eligible);
				const row = element('tr');
				row.classList.toggle('selected-row', checked);
				row.classList.toggle('ineligible-row', !eligible);
				row.addEventListener('click', (event) => {
					if (!eligible || event.target.closest('button, input, select, textarea, a')) return;
					toggleItem(item);
				});
				const checkCell = element('td', 'fotogenic-ai-bulk-source-table__check');
				const checkbox = setFocusKey(element('input'), `source:${item.id}`);
				checkbox.type = 'checkbox';
				checkbox.checked = checked;
				checkbox.disabled = !eligible;
				checkbox.setAttribute('aria-label', sprintf(__( '%1$s %2$s', 'fotogenic-ai' ), checked ? __( 'Remove', 'fotogenic-ai' ) : __( 'Select', 'fotogenic-ai' ), item.label));
				checkbox.addEventListener('change', () => {
					if (!toggleItem(item)) checkbox.checked = itemSelected(item.id, eligible);
				});
				checkCell.appendChild(checkbox);
				const identityCell = element('td', 'fotogenic-ai-content-identity');
				const identity = element('div', 'fotogenic-ai-select-product-cell');
				if (item.imageUrl) {
					const image = element('img', 'fotogenic-ai-source-picker__thumb');
					image.src = item.imageUrl;
					image.alt = '';
					identity.appendChild(image);
				} else {
					const placeholder = element('span', 'fotogenic-ai-select-product-cell__placeholder');
					placeholder.appendChild(createIcon('image-square', { weight: 'regular', size: 17 }));
					identity.appendChild(placeholder);
				}
				const copy = element('div', 'fotogenic-ai-source-picker__item-copy');
				copy.append(element('strong', '', item.label), element('small', '', sprintf(__( 'ID %d', 'fotogenic-ai' ), item.id)));
				identity.appendChild(copy);
				identityCell.appendChild(identity);
				const statusCell = element('td', 'fotogenic-ai-content-status-cell');
				statusCell.appendChild(element('span', `fotogenic-ai-content-status${contentStatusClass(item.status)}`, item.statusLabel || item.status));
				const authorCell = element('td', 'fotogenic-ai-content-author', item.author || __( 'Not available', 'fotogenic-ai' ));
				const sourceCell = element('td', 'fotogenic-ai-content-source');
				const source = element('span', eligible ? 'fotogenic-ai-select-source-badge' : 'fotogenic-ai-select-issue');
				source.append(
					createIcon(eligible ? 'image-square' : 'warning', { weight: eligible ? 'regular' : 'fill', size: 15 }),
					element('span', '', eligible ? __( 'Featured image', 'fotogenic-ai' ) : item.eligibilityReason)
				);
				sourceCell.appendChild(source);
				row.append(checkCell, identityCell, statusCell, authorCell, sourceCell);
				body.appendChild(row);
			});
			table.append(head, body);
			wrap.appendChild(table);
			results.appendChild(wrap);
		};
		const renderSourceLoadError = () => {
			const state = element('section', 'fotogenic-ai-source-load-error');
			state.setAttribute('role', 'alert');
			state.append(
				createIcon('warning', { weight: 'fill', size: 24 }),
				element('h3', '', __( 'Sources could not be loaded', 'fotogenic-ai' )),
				element('p', '', sourceLoadError?.message || __( 'Check your connection and permissions, then try again.', 'fotogenic-ai' ))
			);
			const actions = element('div', 'fotogenic-ai-source-load-error__actions');
			const retry = element('button', 'primary small', __( 'Try again', 'fotogenic-ai' ));
			retry.type = 'button';
			retry.addEventListener('click', load);
			const focusSearch = element('button', 'secondary small', __( 'Edit search', 'fotogenic-ai' ));
			focusSearch.type = 'button';
			focusSearch.addEventListener('click', () => searchInput.focus());
			actions.append(retry, focusSearch);
			state.appendChild(actions);
			results.appendChild(state);
		};
		const renderSourceLoading = () => {
			const state = element('section', 'fotogenic-ai-source-loading');
			state.setAttribute('role', 'status');
			state.setAttribute('aria-live', 'polite');
			const spinner = createIcon('arrows-clockwise', { weight: 'bold', size: 20 });
			spinner.classList.add('fotogenic-ai-icon--spin');
			spinner.setAttribute('aria-hidden', 'true');
			state.append(spinner, element('span', '', __( 'Loading sources…', 'fotogenic-ai' )));
			results.appendChild(state);
		};
		const renderCampaignSelectionError = () => {
			const state = element('section', 'fotogenic-ai-source-load-error fotogenic-ai-campaign-selection-error');
			state.setAttribute('role', 'alert');
			const heading = campaignSelectionErrorKind === 'source'
				? __( 'Campaign source unavailable', 'fotogenic-ai' )
				: (campaignSelectionErrorKind === 'capacity'
					? __( 'Campaign Set limit reached', 'fotogenic-ai' )
					: __( 'Secure selection is unavailable', 'fotogenic-ai' ));
			state.append(
				createIcon('warning', { weight: 'fill', size: 24 }),
				element('h3', '', heading),
				element('p', '', campaignSelectionError)
			);
			if (campaignSelectionErrorKind === 'capacity') {
				const dismiss = element('button', 'secondary small', __( 'Review current selection', 'fotogenic-ai' ));
				dismiss.type = 'button';
				dismiss.addEventListener('click', () => {
					clearCampaignSelectionError();
					renderResults({ skipCampaignGroupSync: true });
				});
				state.appendChild(dismiss);
			} else {
				const reload = element('button', 'primary small', __( 'Reload Studio', 'fotogenic-ai' ));
				reload.type = 'button';
				reload.addEventListener('click', () => window.location.reload());
				state.appendChild(reload);
			}
			results.appendChild(state);
		};
		const renderInfiniteState = (sentinel) => {
			if (!sentinel) return;
			sentinel.replaceChildren();
			const hasNextPage = pageData.page < pageData.totalPages;
			sentinel.hidden = !hasNextPage && !sourceLoadMoreError;
			sentinel.classList.toggle(
				'is-active',
				sourceLoadMorePending || Boolean(sourceLoadMoreError)
			);
			if (sentinel.hidden) return;
			if (sourceLoadMorePending) {
				const spinner = createIcon('arrows-clockwise', { size: 20 });
				spinner.classList.add('fotogenic-ai-icon--spin');
				sentinel.append(spinner, element('span', '', __( 'Loading more sources…', 'fotogenic-ai' )));
				return;
			}
			if (sourceLoadMoreError) {
				sentinel.appendChild(element('span', '', sourceLoadMoreError.message || __( 'More products could not be loaded.', 'fotogenic-ai' )));
				const retry = element('button', 'secondary small', __( 'Try again', 'fotogenic-ai' ));
				retry.type = 'button';
				retry.addEventListener('click', () => loadMoreSources(true));
				sentinel.appendChild(retry);
			}
		};
		const setupInfiniteScroll = (wrap, sentinel) => {
			disconnectInfiniteScroll();
			if (!wrap || !sentinel || sentinel.hidden || sourceLoadMoreError) return;
			if (typeof window.IntersectionObserver === 'function') {
				sourceLoadMoreObserver = new window.IntersectionObserver((entries) => {
					if (entries.some((entry) => entry.isIntersecting)) loadMoreSources();
				}, {
					root: wrap,
					rootMargin: '0px 0px 160px 0px',
					threshold: 0.01,
				});
				sourceLoadMoreObserver.observe(sentinel);
				return;
			}
			sourceScrollRoot = wrap.scrollHeight > wrap.clientHeight ? wrap : window;
			sourceScrollHandler = () => {
				const nearEnd = sourceScrollRoot === window
					? sentinel.getBoundingClientRect().top <= window.innerHeight + 160
					: wrap.scrollHeight - wrap.scrollTop - wrap.clientHeight <= 160;
				if (nearEnd) loadMoreSources();
			};
			sourceScrollRoot.addEventListener('scroll', sourceScrollHandler, { passive: true });
			sourceScrollHandler();
		};

		const renderResults = ({ preserveProductRows = false, preserveScroll = false, skipCampaignGroupSync = false } = {}) => {
			if (!sourceLoading && !skipCampaignGroupSync) ensureCampaignGroups();
			const oldProductWrap = preserveProductRows || preserveScroll
				? results.querySelector('.fotogenic-ai-select-table-wrap')
				: null;
			const mediaScrollTop = preserveProductRows || preserveScroll ? mediaGalleryColumn.scrollTop : 0;
			const oldScrollTop = Number(oldProductWrap?.scrollTop) || 0;
			const oldFocusKey = preserveProductRows ? activeFocusKey(results) : '';
			const oldRows = new Map(
				[...(oldProductWrap?.querySelectorAll?.('tbody tr[data-fa-source-id]') || [])]
					.map((row) => [String(row.dataset.faSourceId || ''), row])
			);
			disconnectInfiniteScroll();
            results.replaceChildren();
			results.setAttribute('aria-busy', sourceLoading ? 'true' : 'false');
			if (sourceLoading) {
				renderSourceLoading();
				results.hidden = false;
				syncPaginationVisibility({ pending: true });
				return;
			}
			if (campaignSelectionError) {
				renderCampaignSelectionError();
				if (campaignSelectionErrorKind !== 'capacity') {
					results.hidden = false;
					syncPaginationVisibility({ failed: true });
					return;
				}
			}
			if (sourceLoadError) {
				renderSourceLoadError();
				results.hidden = false;
				syncPaginationVisibility({ failed: true });
				return;
			}
            const selectedIds = new Set(getSelectedIds());
			if (route.sourceType === 'media') {
				renderMediaGrid();
				if (isInfiniteDiscovery()) {
					const sentinel = element('div', 'fotogenic-ai-product-infinite-scroll');
					sentinel.setAttribute('role', 'status');
					renderInfiniteState(sentinel);
					results.appendChild(sentinel);
					setupInfiniteScroll(mediaGalleryColumn, sentinel);
				}
				mediaGalleryColumn.scrollTop = mediaScrollTop;
			} else if (route.scope === 'bulk' && ['post', 'page'].includes(route.sourceType)) {
				renderContentTable();
            } else if (!pageData.items.length) {
                results.appendChild(element('p', 'fotogenic-ai-studio-empty-copy', query ? __( 'No matching sources.', 'fotogenic-ai' ) : __( 'No eligible sources are available.', 'fotogenic-ai' )));
			} else if (route.sourceType === 'product') {
				const wrap = element('div', 'fotogenic-ai-bulk-source-table-wrap fotogenic-ai-select-table-wrap');
				wrap.setAttribute('role', 'region');
				wrap.setAttribute('aria-label', __( 'Product source results', 'fotogenic-ai' ));
				wrap.tabIndex = isInfiniteDiscovery() ? 0 : -1;
				if (isInfiniteDiscovery()) {
					wrap.addEventListener('keydown', handleScrollableResultsKeyDown);
				}
				const table = element('table', 'fotogenic-ai-bulk-source-table');
				const caption = element('caption', 'fotogenic-ai-studio-sr-only', __( 'Product source selection', 'fotogenic-ai' ));
				const head = element('thead');
				const headRow = element('tr');
				const selectCell = element('th', 'fotogenic-ai-bulk-source-table__check');
				selectCell.scope = 'col';
				if (route.scope === 'bulk') {
					const headerCheckbox = element('input');
					headerCheckbox.type = 'checkbox';
					headerCheckbox.checked = pageSelectionComplete();
					headerCheckbox.indeterminate = pageSelectionStarted() && !headerCheckbox.checked;
					headerCheckbox.disabled = eligiblePageIds().length === 0;
					headerCheckbox.setAttribute('aria-label', isStoreQueueSelection()
						? (headerCheckbox.checked
							? __( 'Clear Product selection', 'fotogenic-ai' )
							: __( 'Select all matching Products', 'fotogenic-ai' ))
						: (pageSelectionStarted()
							? __( 'Deselect loaded products', 'fotogenic-ai' )
							: __( 'Select loaded products', 'fotogenic-ai' )));
					headerCheckbox.addEventListener('change', isStoreQueueSelection() ? toggleProductQuerySelection : toggleCurrentPage);
					selectCell.appendChild(headerCheckbox);
				} else {
					selectCell.appendChild(element('span', 'fotogenic-ai-studio-sr-only', __( 'Select', 'fotogenic-ai' )));
				}
				const productHeading = element('th', '', __( 'Product', 'fotogenic-ai' ));
				productHeading.scope = 'col';
				const sourceHeading = element('th', '', route.workflow === 'campaign_set' ? __( 'Run setup', 'fotogenic-ai' ) : __( 'Primary source', 'fotogenic-ai' ));
				sourceHeading.scope = 'col';
				const eligibilityHeading = element('th', '', __( 'Eligibility', 'fotogenic-ai' ));
				eligibilityHeading.scope = 'col';
				headRow.append(selectCell, productHeading, sourceHeading, eligibilityHeading);
				head.appendChild(headRow);
				const body = element('tbody');
				pageData.items.forEach((item) => {
					const eligible = sourceEligibleForMode(item, route, getSourceMode());
					const checked = itemSelected(item.id, eligible);
					const selectedVariationCount = selectedVariationsForParent(item.id).length;
					const row = element('tr');
					row.dataset.faSourceId = String(item.id);
					row.classList.toggle('selected-row', checked);
					row.classList.toggle('has-variation-selection', selectedVariationCount > 0);
					row.classList.toggle('active-variation-row', variationOverlay?.isOpen?.() && variationParent?.id === item.id);
					row.classList.toggle('ineligible-row', !eligible);
					row.addEventListener('click', (event) => {
						if (!eligible || event.target.closest('button, input, select, textarea, a')) return;
						toggleItem(item);
					});
					const checkCell = element('td', 'fotogenic-ai-bulk-source-table__check');
					const checkbox = element('input');
                    checkbox.type = 'checkbox';
                    checkbox.checked = checked;
                    checkbox.disabled = !eligible;
                    setFocusKey(checkbox, `source:${item.id}`);
                    checkbox.setAttribute('aria-label', sprintf( __( '%1$s %2$s', 'fotogenic-ai' ), checked ? __( 'Remove', 'fotogenic-ai' ) : __( 'Select', 'fotogenic-ai' ), item.label ));
					checkbox.addEventListener('change', () => {
						if (!toggleItem(item)) checkbox.checked = itemSelected(item.id, eligible);
					});
					checkCell.appendChild(checkbox);
					const productCell = element('td');
					const product = element('div', 'fotogenic-ai-select-product-cell');
					if (item.imageUrl) {
						const image = element('img', 'fotogenic-ai-source-picker__thumb');
                        image.src = item.imageUrl;
                        image.alt = '';
                        image.loading = 'lazy';
                        image.decoding = 'async';
						product.appendChild(image);
					} else {
						const placeholder = element('span', 'fotogenic-ai-select-product-cell__placeholder');
						placeholder.appendChild(createIcon('image-square', { weight: 'regular', size: 17 }));
						product.appendChild(placeholder);
					}
					const copy = element('div', 'fotogenic-ai-source-picker__item-copy');
					copy.appendChild(element('strong', '', item.label));
					const productDetail = item.categoryNames[0] || item.sku || item.detail;
					copy.appendChild(element('small', '', productDetail
						? sprintf(__( 'ID %1$d · %2$s', 'fotogenic-ai' ), item.id, productDetail)
						: sprintf(__( 'ID %d', 'fotogenic-ai' ), item.id)));
					product.appendChild(copy);
					productCell.appendChild(product);

					const primaryCell = element('td', 'fotogenic-ai-select-primary-source');
					if (supportsVariationSelection(route) && item.target?.targetType === 'product' && item.hasVariations) {
					const variations = element(
							'button',
							'fotogenic-ai-select-variation-button',
							__( 'Variations', 'fotogenic-ai' )
						);
						variations.type = 'button';
						setFocusKey(variations, `variations:${item.id}`);
						variations.appendChild(createIcon('caret-down', { weight: 'bold', size: 14 }));
						variations.addEventListener('click', () => void openVariationDrawer(item, variations));
						primaryCell.appendChild(variations);
					} else {
						const source = element('span', `fotogenic-ai-select-source-badge${eligible ? '' : ' is-muted'}`);
						source.append(
							createIcon('image-square', { weight: 'regular', size: 15 }),
							element('span', '', eligible
								? (route.workflow === 'campaign_set'
									? sprintf(_n( '%d image available', '%d images available', item.sourceAvailability?.totalCount || 0, 'fotogenic-ai' ), item.sourceAvailability?.totalCount || 0)
									: __( 'Featured image', 'fotogenic-ai' ))
								: __( 'Unavailable', 'fotogenic-ai' ))
						);
						primaryCell.appendChild(source);
					}
					if (route.workflow === 'campaign_set') {
						const exactTargets = selectedVariationsForParent(item.id);
						if (checked && !exactTargets.length) exactTargets.push(item);
						const targetIds = new Set(exactTargets.map((targetItem) => Number(targetItem.id)));
						const groupCount = campaignGroups().filter((group) => targetIds.has(Number(group.subjectId))).length;
						const actions = element('div', 'fotogenic-ai-campaign-product-row-actions');
						actions.append(...primaryCell.childNodes);
						const sets = setFocusKey(element('button', 'fotogenic-ai-campaign-sets-open-button', groupCount > 0
							? sprintf(__( 'Source groups · %d', 'fotogenic-ai' ), groupCount)
							: __( 'Source groups', 'fotogenic-ai' )), `campaign-sets:${item.id}`);
						sets.type = 'button';
						sets.disabled = exactTargets.length === 0;
						sets.setAttribute('aria-haspopup', 'dialog');
						sets.addEventListener('click', () => void openCampaignProductSets(item, sets));
						actions.appendChild(sets);
						primaryCell.appendChild(actions);
					}

					const eligibilityCell = element(
						'td',
						`fotogenic-ai-select-eligibility-cell${eligible ? '' : ' is-ineligible'}`
					);
					const eligibility = element('span', eligible ? 'fotogenic-ai-select-ready' : 'fotogenic-ai-select-issue');
					eligibility.append(
						createIcon(eligible ? 'check-circle' : 'warning', { weight: 'fill', size: eligible ? 17 : 15 }),
						element('span', '', eligible
							? __( 'Ready', 'fotogenic-ai' )
							: (item.eligibilityReason || __( 'No eligible source image is available.', 'fotogenic-ai' )))
					);
					eligibilityCell.appendChild(eligibility);
					row.append(checkCell, productCell, primaryCell, eligibilityCell);
					body.appendChild(row);
				});
				table.append(caption, head, body);
				wrap.appendChild(table);
				let sentinel = null;
				if (isInfiniteDiscovery()) {
					sentinel = element('div', 'fotogenic-ai-product-infinite-scroll');
					sentinel.setAttribute('role', 'status');
					sentinel.setAttribute('aria-live', 'polite');
					sentinel.setAttribute('aria-atomic', 'true');
					renderInfiniteState(sentinel);
					wrap.appendChild(sentinel);
				}
				results.appendChild(wrap);
				if (preserveProductRows && oldRows.size) {
					body.querySelectorAll('tr[data-fa-source-id]').forEach((row) => {
						const previousRow = oldRows.get(String(row.dataset.faSourceId || ''));
						if (previousRow && typeof row.replaceWith === 'function') row.replaceWith(previousRow);
					});
				}
				wrap.scrollTop = oldScrollTop;
				if (oldFocusKey) restoreFocusKey(wrap, oldFocusKey);
				if (sentinel) setupInfiniteScroll(wrap, sentinel);
			} else if (route.scope === 'bulk') {
				const wrap = element('div', 'fotogenic-ai-bulk-source-table-wrap');
				const table = element('table', 'fotogenic-ai-bulk-source-table');
				const caption = element('caption', 'fotogenic-ai-studio-sr-only', __( 'Bulk source selection', 'fotogenic-ai' ));
				const head = element('thead');
				const headRow = element('tr');
				const selectCell = element('th', 'fotogenic-ai-bulk-source-table__check', __( 'Select', 'fotogenic-ai' ));
				selectCell.scope = 'col';
				const sourceHeading = element('th', '', __( 'Source', 'fotogenic-ai' ));
				sourceHeading.scope = 'col';
				headRow.append(selectCell, sourceHeading);
				head.appendChild(headRow);
				const body = element('tbody');
				pageData.items.forEach((item) => {
					const eligible = sourceEligibleForMode(item, route, getSourceMode());
					const checked = itemSelected(item.id, eligible);
					const row = element('tr');
					const checkCell = element('td', 'fotogenic-ai-bulk-source-table__check');
					const label = element('label', 'fotogenic-ai-bulk-source-table__checkbox');
					const checkbox = element('input');
					checkbox.type = 'checkbox';
					checkbox.checked = checked;
					checkbox.disabled = !eligible;
					setFocusKey(checkbox, `source:${item.id}`);
					checkbox.setAttribute('aria-label', sprintf(__( '%1$s %2$s', 'fotogenic-ai' ), checked ? __( 'Remove', 'fotogenic-ai' ) : __( 'Select', 'fotogenic-ai' ), item.label));
					checkbox.addEventListener('change', () => {
						if (!toggleItem(item)) checkbox.checked = itemSelected(item.id, eligible);
					});
					label.append(checkbox, element('span', 'fotogenic-ai-studio-sr-only', item.label));
					checkCell.appendChild(label);
					const sourceCell = element('td');
					const source = element('div', 'fotogenic-ai-bulk-source-table__source');
					if (item.imageUrl) {
						const image = element('img', 'fotogenic-ai-source-picker__thumb');
						image.src = item.imageUrl;
						image.alt = '';
						source.appendChild(image);
					}
					const copy = element('div', 'fotogenic-ai-source-picker__item-copy');
					copy.appendChild(element('strong', '', item.label));
					if (item.detail) copy.appendChild(element('span', 'fotogenic-ai-studio-empty-copy', item.detail));
					source.appendChild(copy);
					sourceCell.appendChild(source);
					row.append(checkCell, sourceCell);
					body.appendChild(row);
				});
				table.append(caption, head, body);
				wrap.appendChild(table);
				results.appendChild(wrap);
            } else {
                pageData.items.forEach((item) => {
                    const eligible = sourceEligibleForMode(item, route, getSourceMode());
                    const row = element('article', 'fotogenic-ai-source-picker__item');
                    const copy = element('div', 'fotogenic-ai-source-picker__item-copy');
                    copy.appendChild(element('strong', '', item.label));
                    if (item.detail) {
                        copy.appendChild(element('span', 'fotogenic-ai-studio-empty-copy', item.detail));
                    }
                    const button = element('button', 'secondary', selectedIds.has(item.id) ? __( 'Selected', 'fotogenic-ai' ) : __( 'Select', 'fotogenic-ai' ));
                    button.type = 'button';
                    setFocusKey(button, `source:${item.id}`);
                    button.setAttribute('aria-pressed', selectedIds.has(item.id) ? 'true' : 'false');
                    button.setAttribute('aria-label', sprintf( __( '%1$s %2$s', 'fotogenic-ai' ), selectedIds.has(item.id) ? __( 'Remove', 'fotogenic-ai' ) : __( 'Select', 'fotogenic-ai' ), item.label ));
                    if (!eligible) {
                        button.disabled = true;
                        button.setAttribute('aria-describedby', `fotogenic-source-unavailable-${route.sourceType}-${item.id}`);
                        const reasonCopy = item.eligibilityReason || (route.sourceType === 'product' && route.scope === 'bulk' && route.workflow !== 'campaign_set'
                            ? __( 'No eligible image is available for the selected Product source mode.', 'fotogenic-ai' )
                            : __( 'No eligible source image is available.', 'fotogenic-ai' ));
                        const reason = element('p', 'fotogenic-ai-studio-empty-copy', reasonCopy);
                        reason.id = `fotogenic-source-unavailable-${route.sourceType}-${item.id}`;
                        copy.appendChild(reason);
                    }
                    button.addEventListener('click', () => toggleItem(item));
                    if (item.imageUrl) {
                        const image = element('img', 'fotogenic-ai-source-picker__thumb');
                        image.src = item.imageUrl;
                        image.alt = '';
                        image.loading = 'lazy';
                        image.decoding = 'async';
                        row.appendChild(image);
                    }
                    row.append(copy, button);
                    results.appendChild(row);
                });
            }
			pageLabel.textContent = route.scope === 'bulk' && route.sourceType === 'product'
				? `${pageData.page} / ${pageData.totalPages}`
				: sprintf( __( 'Page %1$d of %2$d', 'fotogenic-ai' ), pageData.page, pageData.totalPages );
			pageLabel.setAttribute('aria-label', sprintf( __( 'Page %1$d of %2$d', 'fotogenic-ai' ), pageData.page, pageData.totalPages ));
			previous.disabled = pageData.page <= 1;
			next.disabled = pageData.page >= pageData.totalPages;
			syncPaginationVisibility();
			syncSelectionCount();
			renderSelected();
			if (route.scope === 'bulk') {
				renderSourcePolicy();
			}
			renderToolbar();
			renderProductSearchPopover();
			syncDiscoveryVisibility();
        };

		const syncDiscoveryVisibility = () => {
			const focusedSelection = !sourceLoading && route.scope === 'single'
				&& getSelectedIds().length === 1
				&& !['product', 'media'].includes(route.sourceType);
            searchLabel.hidden = focusedSelection;
            toolbar.hidden = focusedSelection;
            status.hidden = focusedSelection;
            results.hidden = focusedSelection;
			syncPaginationVisibility();
            if (!focusedSelection) {
				productFilters.hidden = !isProductDiscovery();
            }
        };

		const searchController = createSourceSearchController({
            transport,
            onPending(pending) {
				if (pending && isInfiniteDiscovery()) resetInfiniteState();
				sourceLoading = pending;
                searchInput.setAttribute('aria-busy', (isProductDiscovery() ? productSearchPending : pending) ? 'true' : 'false');
                status.textContent = pending ? __( 'Loading sources…', 'fotogenic-ai' ) : '';
				if (pending) renderResults({ skipCampaignGroupSync: true });
				results.hidden = false;
				syncPaginationVisibility({ pending });
                previous.disabled = pending || pageData.page <= 1;
                next.disabled = pending || pageData.page >= pageData.totalPages;
            },
            onResult(result) {
                if (!result.ok) {
                    if (!result.aborted) {
						sourceLoadError = result;
						status.textContent = result.message || __( 'Sources could not be loaded.', 'fotogenic-ai' );
						renderResults();
						if (productSearchOpen && isProductDiscovery()) renderProductSearchPopover();
                        onSourceServiceError?.(result, {
                            retry: load,
                            exit: () => searchInput.focus(),
                        });
                    }
                    return;
				}
				sourceLoadError = null;
                pageData = {
                    ...result.data,
                    items: result.data.items.map((item) => normalizeItem(item, route.sourceType)).filter(Boolean),
                };
				if (isStoreQueueSelection() && currentSelection().strategy === 'query') {
					void refreshProductSelectionCount();
				}
				page = pageData.page;
                pageData.items.forEach((item) => selectedItems.set(item.id, item));
                status.textContent = sprintf(
                    _n( '%d source available.', '%d sources available.', pageData.totalItems, 'fotogenic-ai' ),
                    pageData.totalItems
                );
				if (route.sourceType === 'media') renderMediaFilters();
                renderResults();
            },
        });

		const productSuggestionsController = createSourceSearchController({
			transport,
			onPending(pending) {
				productSearchPending = pending;
				searchInput.setAttribute('aria-busy', pending ? 'true' : 'false');
				if (pending) renderProductSearchPopover();
			},
			onResult(result) {
				if (!result.ok) {
					if (result.aborted) return;
					productSearchError = result;
					onSourceServiceError?.(result, { retry: loadProductSuggestions, exit: () => searchInput.focus() });
				} else {
					productSearchError = null;
					productSearchResultQuery = productSearchQuery.trim();
					productSearchPage = {
						...result.data,
						items: result.data.items.map((item) => normalizeItem(item, 'product')).filter(Boolean),
					};
					productSearchPage.items.forEach((item) => selectedItems.set(item.id, item));
				}
				renderProductSearchPopover();
			},
		});
		const loadProductSuggestions = ({ debounce = false } = {}) => {
			productSuggestionsController.cancel();
			productSearchPending = productSearchQuery.trim().length >= PRODUCT_SEARCH_MIN_LENGTH;
			productSearchError = null;
			productSearchResultQuery = '';
			productSearchPage = null;
			searchInput.setAttribute('aria-busy', productSearchPending ? 'true' : 'false');
			renderProductSearchPopover();
			if (!productSearchPending) return;
			const request = {
				sourceType: 'product', query: productSearchQuery.trim(), page: 1,
				perPage: discoveryPageSize(), filters, bulk: route.scope === 'bulk',
			};
			return debounce ? productSuggestionsController.schedule(request) : productSuggestionsController.load(request);
		};

		const sourceQuery = () => isProductDiscovery() && query.trim().length < PRODUCT_SEARCH_MIN_LENGTH ? '' : query;
		const loadMoreSources = (retry = false) => {
			if (!isInfiniteDiscovery()) return;
			if (sourceLoading || productSearchPending) return;
			if (sourceLoadMorePending || pageData.page >= pageData.totalPages) return;
			if (sourceLoadMoreError && !retry) return;
			sourceLoadMoreError = null;
			return sourceLoadMoreController.load({
				sourceType: route.sourceType,
				query: sourceQuery(),
				page: pageData.page + 1,
				perPage: discoveryPageSize(),
				filters: route.sourceType === 'media' ? mediaFilters : filters,
				bulk: route.scope === 'bulk',
			});
		};

		sourceLoadMoreController = createSourceSearchController({
			transport,
			onPending(pending) {
				sourceLoadMorePending = pending;
				searchInput.setAttribute('aria-busy', (isProductDiscovery() ? productSearchPending : pending) ? 'true' : 'false');
				if (pending) {
					status.textContent = __( 'Loading more sources…', 'fotogenic-ai' );
					renderInfiniteState(results.querySelector('.fotogenic-ai-product-infinite-scroll'));
				}
			},
			onResult(result) {
				sourceLoadMorePending = false;
				if (!result.ok) {
					if (!result.aborted) {
						sourceLoadMoreError = result;
						status.textContent = result.message || __( 'More products could not be loaded.', 'fotogenic-ai' );
						renderInfiniteState(results.querySelector('.fotogenic-ai-product-infinite-scroll'));
					}
					return;
				}
				sourceLoadMoreError = null;
				const normalizedItems = result.data.items
					.map((item) => normalizeItem(item, route.sourceType))
					.filter(Boolean);
				pageData = {
					...result.data,
					items: mergeSourcePageItems(pageData.items, normalizedItems),
				};
				page = pageData.page;
				normalizedItems.forEach((item) => selectedItems.set(item.id, item));
				status.textContent = sprintf(
					__( '%1$d of %2$d sources loaded.', 'fotogenic-ai' ),
					pageData.items.length,
					pageData.totalItems
				);
				renderResults({ preserveProductRows: true });
			},
		});

		const load = () => searchController.load({
            sourceType: route.sourceType,
			query: sourceQuery(),
            page,
			perPage: discoveryPageSize(),
            filters: route.sourceType === 'media' ? mediaFilters : filters,
            bulk: route.scope === 'bulk',
        });

		const pageSelectionAction = (label, onSelect = toggleCurrentPage) => {
			const querySelection = currentSelection().strategy === 'query';
			const action = setFocusKey(element(
				'button',
				'fotogenic-ai-select-toolbar__page-action',
				querySelection ? __( 'Clear selection', 'fotogenic-ai' ) : label
			), 'source-select-page');
			action.type = 'button';
			action.disabled = !querySelection && eligiblePageIds().length === 0;
			if (!querySelection && route.scope === 'bulk' && !pageSelectionStarted()
				&& availablePageIds().length > 0 && availablePageIds().length < eligiblePageIds().length) {
				action.textContent = sprintf(__( 'Select %d loaded', 'fotogenic-ai' ), availablePageIds().length);
			}
			action.addEventListener('click', () => {
				if (currentSelection().strategy === 'query') {
					commitSelection({ strategy: 'explicit', selectedIds: [], excludedIds: [], query: {} });
					renderResults();
					renderSelected();
					renderToolbar();
				} else onSelect();
			});
			return action;
		};

		const renderToolbar = () => {
			toolbar.replaceChildren();
			productFilters.hidden = !isProductDiscovery();
			if (route.scope === 'bulk' && route.sourceType === 'product') {
				const copy = element('div', 'fotogenic-ai-select-toolbar__copy');
				copy.append(
					element('strong', '', sprintf(
						_n( '%d loaded match', '%d loaded matches', pageData.items.length, 'fotogenic-ai' ),
						pageData.items.length
					)),
					element('span', '', sprintf(__( '%d total', 'fotogenic-ai' ), pageData.totalItems))
				);
				toolbar.appendChild(copy);
			} else if (route.sourceType === 'media') {
				const querySelection = currentSelection().strategy === 'query';
				const copy = element('div', 'fotogenic-ai-select-toolbar__copy');
				const sortMeta = element(
					'span',
					'fotogenic-ai-select-toolbar__sort-meta',
					sprintf(__( '· %s', 'fotogenic-ai' ), __( 'Sorted newest', 'fotogenic-ai' ))
				);
				copy.append(
					element('strong', '', sprintf(_n( '%d loaded', '%d loaded', pageData.items.length, 'fotogenic-ai' ), pageData.items.length)),
					element('span', '', querySelection
						? sprintf( __( '%d total · All eligible matches selected', 'fotogenic-ai' ), pageData.totalItems )
						: sprintf(__( '%1$d total · %2$d selected', 'fotogenic-ai' ), pageData.totalItems, getSelectedIds().length)),
					sortMeta
				);
				const selectPage = pageSelectionAction(
					route.scope === 'single' ? __( 'Select image', 'fotogenic-ai' )
						: (pageSelectionStarted() ? __( 'Clear images', 'fotogenic-ai' ) : __( 'Select images', 'fotogenic-ai' )),
					() => {
					if (route.scope === 'bulk') toggleCurrentPage();
					else {
						const selectedIds = new Set(getSelectedIds().map(Number));
						const candidate = pageData.items.find((item) => item.eligible && !selectedIds.has(item.id));
						if (candidate) toggleItem(candidate);
					}
				});
				toolbar.append(copy, selectPage);
			} else if (route.scope === 'bulk' && ['post', 'page'].includes(route.sourceType)) {
				const querySelection = currentSelection().strategy === 'query';
				const noun = route.sourceType === 'post' ? __( 'posts', 'fotogenic-ai' ) : __( 'pages', 'fotogenic-ai' );
				const copy = element('div', 'fotogenic-ai-select-toolbar__copy');
				copy.append(
					element('strong', '', sprintf(__( '%1$d matching %2$s', 'fotogenic-ai' ), pageData.totalItems, noun)),
					element('span', '', querySelection
						? __( 'All eligible matches selected', 'fotogenic-ai' )
						: sprintf(__( '%d selected', 'fotogenic-ai' ), selectionEstimate()))
				);
				toolbar.appendChild(copy);
            }
			if (route.sourceType !== 'product' && currentSelection().strategy !== 'query' && getSelectedIds().length
				&& !getSelectedIds().every((id) => eligiblePageIds().includes(id))) {
				const clear = element('button', 'fotogenic-ai-select-toolbar__page-action', __( 'Clear selected', 'fotogenic-ai' ));
				clear.type = 'button';
				clear.addEventListener('click', () => commitSelection({ strategy: 'explicit', selectedIds: [], excludedIds: [], query: {} }));
				toolbar.appendChild(clear);
			}
            syncDiscoveryVisibility();
        };

		const reconcileBulkSelectionAfterDiscoveryChange = () => {
			const selection = currentSelection();
			if (route.scope !== 'bulk') return;
			if (isStoreQueueSelection()) return;
			if (selection.strategy === 'query') {
				commitSelection({ strategy: 'explicit', selectedIds: [], excludedIds: [], query: {} });
				status.textContent = __( 'Filters changed. Select the sources you want to use.', 'fotogenic-ai' );
			}
		};
		searchInput.addEventListener('input', () => {
			if (isProductDiscovery()) {
				productSearchQuery = searchInput.value;
				loadProductSuggestions({ debounce: true });
				openProductSearch();
				if (!productSearchQuery.trim() && query) {
					searchController.cancel();
					resetInfiniteState();
					query = '';
					page = 1;
					sourceLoading = false;
					sourceLoadError = null;
					reconcileBulkSelectionAfterDiscoveryChange();
					if (cataloguePage) {
						pageData = cataloguePage;
						page = pageData.page;
						renderResults();
						const wrap = results.querySelector('.fotogenic-ai-select-table-wrap');
						if (wrap) wrap.scrollTop = catalogueScrollTop;
					} else load();
				}
				return;
			}
			query = searchInput.value;
			page = 1;
			reconcileBulkSelectionAfterDiscoveryChange();
            searchController.schedule({
                sourceType: route.sourceType,
                query,
                page,
				perPage: discoveryPageSize(),
                filters: route.sourceType === 'media' ? mediaFilters : filters,
                bulk: route.scope === 'bulk',
			});
		});
		mediaFilterTrigger.addEventListener('click', () => {
			mediaFilterReturnFocus = mediaFilterTrigger;
			mediaFilterDraft = { ...mediaFilters };
			if (mediaFilterOpen) {
				closeMediaFilters({ restoreFocus: true });
				return;
			}
			window.clearTimeout(mediaFilterCloseTimer);
			mediaFilterCloseTimer = 0;
			mediaFilterOpen = true;
			mediaFilterPopover.hidden = false;
			mediaFilterPopover.classList.remove('is-closing');
			mediaFilterPopover.classList.add('is-open');
			mediaFilterTrigger.classList.add('is-open');
			mediaFilterTrigger.setAttribute('aria-expanded', 'true');
			renderMediaFilters();
			mediaFilterPopover.querySelector('select')?.focus?.();
		});
		document.addEventListener('pointerdown', dismissMediaFilters);
		document.addEventListener('keydown', closeMediaFiltersWithEscape);
		searchInput.addEventListener('focus', () => {
			if (suppressProductSearchFocus) return;
			openProductSearch();
			if (isProductDiscovery() && !productSearchPending && productSearchQuery.trim().length >= PRODUCT_SEARCH_MIN_LENGTH
				&& productSearchResultQuery !== productSearchQuery.trim()) loadProductSuggestions();
		});
		searchInput.addEventListener('keydown', (event) => {
			if (event.key === 'Escape' && productSearchOpen) {
				event.preventDefault();
				closeProductSearch();
				return;
			}
			if (event.key !== 'ArrowDown' || !productSearchOpen) return;
			const firstResult = productSearchPopover.querySelector('.fotogenic-ai-product-search-result input:not(:disabled)');
			if (!firstResult) return;
			event.preventDefault();
			firstResult.focus();
		});
		const applyBulkFilterChange = () => {
			cataloguePage = null;
			productSuggestionsController.cancel();
			productSearchPending = false;
			productSearchPage = null;
			productSearchError = null;
			productSearchQuery = query;
			productSearchResultQuery = '';
			searchInput.value = query;
			reconcileBulkSelectionAfterDiscoveryChange();
			load();
		};
        previous.addEventListener('click', () => {
            page = Math.max(1, pageData.page - 1);
            load();
        });
        next.addEventListener('click', () => {
			page = Math.min(pageData.totalPages, pageData.page + 1);
            load();
        });
		if (typeof compactDiscoveryMedia?.addEventListener === 'function') {
			compactDiscoveryMedia.addEventListener('change', handleDiscoveryModeChange);
		} else {
			compactDiscoveryMedia?.addListener?.(handleDiscoveryModeChange);
		}

		syncPresentation();
		renderMediaFilters();
		syncBulkQueryControls();
        renderToolbar();
        productFilters.hidden = !isProductDiscovery();
        renderSelected();
        renderSourcePolicy();
        syncDiscoveryVisibility();
		if (!productFilters.hidden) loadCategories();
        load();
		void hydrateSelectedMedia();

		return {
			update(nextRoute, { rehydrateVisible = false } = {}) {
                const focusKey = activeFocusKey(mount);
				const changed = nextRoute.workflow !== route.workflow
                    || nextRoute.sourceType !== route.sourceType
                    || nextRoute.scope !== route.scope;
				if (changed) {
					closeCampaignOverlay({ restoreFocus: false });
					productSuggestionsController.cancel();
					cancelMediaUpload();
					resetInfiniteState();
				}
				route = nextRoute;
				if (changed) {
					syncPresentation();
					cataloguePage = null;
					closeVariationDrawer();
					closeProductSearch({ immediate: true });
					variationParent = null;
                    query = '';
                    filters = { categories: [], stock: [] };
					mediaFilters = { ...MEDIA_FILTER_DEFAULTS };
                    mediaFilterDraft = { ...MEDIA_FILTER_DEFAULTS };
					closeMediaFilters({ immediate: true });
					sourceLoadError = null;
					productSearchPending = false;
					productSearchResultQuery = '';
					productSearchQuery = '';
					productSearchPage = null;
					productSearchError = null;
                    page = 1;
					pageData = { items: [], page: 1, totalPages: 1, totalItems: 0 };
					productSelectionCountToken += 1;
					productSelectionCountController?.abort?.();
					productSelectionCountController = null;
					productSelectionCount = null;
					productSelectionCountSignature = '';
					productSelectionCountPending = false;
					sourceLoading = true;
                    searchInput.value = '';
					categoryFilter.setSelected([]);
					stockFilter.setSelected([]);
                    syncBulkQueryControls();
                    renderToolbar();
					renderSelected();
                    renderResults();
                    renderSourcePolicy();
                    if (!productFilters.hidden) loadCategories();
                    load();
					void hydrateSelectedMedia();
                } else {
					if (rehydrateVisible) {
						clearCampaignSelectionError();
						pageData.items.forEach((item) => selectedItems.set(item.id, item));
					}
					renderResults({ preserveScroll: true });
					renderSourcePolicy();
				}
				if (!campaignOverlaySyncSuspended) campaignOverlaySync?.();
				syncDiscoveryVisibility();
                restoreFocusKey(mount, focusKey);
            },
			focusSearch() {
                searchInput.focus();
            },
			destroy() {
				destroyed = true;
				cancelMediaUpload();
				searchController.destroy();
				productSuggestionsController.destroy();
				sourceLoadMoreController?.destroy?.();
				disconnectInfiniteScroll();
				window.clearTimeout(productSearchCloseTimer);
				window.clearTimeout(mediaFilterCloseTimer);
				document.removeEventListener('pointerdown', dismissProductSearch);
				document.removeEventListener('pointerdown', dismissMediaFilters);
				document.removeEventListener('keydown', closeMediaFiltersWithEscape);
				if (typeof compactDiscoveryMedia?.removeEventListener === 'function') {
					compactDiscoveryMedia.removeEventListener('change', handleDiscoveryModeChange);
				} else {
					compactDiscoveryMedia?.removeListener?.(handleDiscoveryModeChange);
				}
				closeProductSearch({ immediate: true });
				closeMediaFilters({ immediate: true });
				variationToken += 1;
				variationController?.abort?.();
				variationOverlay?.destroy?.();
				variationLayer?.remove?.();
				closeCampaignOverlay({ restoreFocus: false });
				mediaSummaryToken += 1;
				mediaSummaryController?.abort?.();
                productContextToken += 1;
                categoryToken += 1;
                categoryController?.abort?.();
				categoryController = null;
				categoriesLoading = false;
				productContextController?.abort?.();
				productSelectionCountToken += 1;
				productSelectionCountController?.abort?.();
				categoryFilter.destroy();
				stockFilter.destroy();
				syncContinuePlacement();
				mount.replaceChildren();
            },
        };
    };

    Studio.sourcePicker = Object.freeze({
        createSourcePicker,
        createSourceSearchController,
		mergeSourcePageItems,
        normalizeBulkSelection,
        selectBulkPage,
		replaceParentWithVariations,
        normalizeItem,
		normalizeProductImages,
		validateMediaAttachmentSelection,
		sourceEligibleForMode,
		supportsVariationSelection,
    });
})();
