(() => {
    'use strict';

    window.FotogenicAI = window.FotogenicAI || {};
    const Studio = window.FotogenicAI.Studio = window.FotogenicAI.Studio || {};
    const { __ } = Studio.i18n;

    const SOURCE_PATHS = Object.freeze({
        product: '/studio/products',
        media: '/studio/media',
        post: '/studio/posts',
        page: '/studio/pages',
    });

    const SUMMARY_PATHS = Object.freeze({
        product: '/studio/product-summary',
        media: '/studio/media-summary',
        post: '/studio/post-summary',
        page: '/studio/page-summary',
    });
	const AUTH_ERROR_CODES = new Set([
		'fotogenic_ai_auth_session_expired',
		'fotogenic_ai_missing_auth_session',
	]);

    const PRODUCT_CONTEXT_PATH = '/studio/product';
	const PRODUCT_VARIATIONS_PATH = '/studio/product-variations';
    const GENERATE_CONFIGURATION_PATH = '/studio/generate-configuration';
    const UNIVERSAL_PRESET_PATHS = Object.freeze({
        list: '/studio/presets',
        get: '/studio/presets/get',
        save: '/studio/presets/save',
        delete: '/studio/presets/delete',
    });
    const LIBRARY_PATHS = Object.freeze({
        list: '/studio/library',
        add: '/studio/library/add',
    });

    const safeRelativePath = (path) => (
        typeof path === 'string'
        && path.startsWith('/')
        && !path.startsWith('//')
        && !path.includes('://')
        && !path.split('?')[0].split('/').includes('..')
    );

    const namespaceFromRestUrl = (restUrl) => {
        const value = String(restUrl || '').replace(/\/$/, '');
        const marker = '/wp-json/';
        const index = value.indexOf(marker);
        return index >= 0 ? `/${value.slice(index + marker.length)}` : '/fotogenic-ai/v1';
    };

    const appendQuery = (path, params) => {
        const query = new URLSearchParams();
        Object.entries(params || {}).forEach(([key, value]) => {
            if (Array.isArray(value)) {
                value.forEach((item) => query.append(`${key}[]`, String(item)));
            } else if (value !== undefined && value !== null) {
                query.set(key, String(value));
            }
        });
        const suffix = query.toString();
        return suffix ? `${path}?${suffix}` : path;
    };

    const safeCode = (value) => {
        const code = String(value || '').trim().toLowerCase().slice(0, 64);
        return /^[a-z0-9][a-z0-9_-]*$/.test(code) ? code : '';
    };

    const normalizeError = (error) => {
        const aborted = error?.name === 'AbortError' || error?.code === 'abort' || error?.aborted === true;
        const detail = error?.data && typeof error.data === 'object' ? error.data : {};
        const nested = detail?.data && typeof detail.data === 'object' ? detail.data : {};
        const status = Math.max(0, Math.floor(Number(error?.status || detail.status || nested.status)) || 0);
        const code = safeCode(error?.code || detail.code || nested.code);
		const authExpired = AUTH_ERROR_CODES.has(code);
		const explicitUncertain = [error?.uncertain, detail.uncertain, nested.uncertain]
			.find((value) => typeof value === 'boolean');
        return {
            ok: false,
            aborted,
            status,
            code,
			authExpired,
			uncertain: !aborted && (typeof explicitUncertain === 'boolean'
				? explicitUncertain
				: (status === 0 || status >= 500)),
            message: aborted ? '' : (status === 403
                ? __( 'You do not have permission to access this source.', 'fotogenic-ai' )
                : __( 'The Studio request could not be completed.', 'fotogenic-ai' )),
        };
    };

    const normalizeOptions = (items, maximum = 200) => {
        const options = [];
        const seen = new Set();
        (Array.isArray(items) ? items : []).some((item) => {
            const rawId = typeof item === 'string' ? item : (item?.id ?? item?.value ?? item?.key ?? item?.slug);
            const id = String(rawId || '').trim().slice(0, 160);
            if (!id || seen.has(id)) {
                return false;
            }
            seen.add(id);
            const rawLabel = typeof item === 'string' ? item : (item?.label ?? item?.name ?? item?.title ?? id);
            const option = { id, label: String(rawLabel || id).trim().slice(0, 200) || id };
            if (item && typeof item === 'object') {
                const description = String(item.description || '').trim().slice(0, 500);
                if (description) option.description = description;
            }
            options.push(option);
            return options.length >= maximum;
        });
        return options;
    };

    const normalizeConfigurationOptions = (payload) => {
		const configuration = payload?.selections && typeof payload.selections === 'object' ? payload : null;
        if (!configuration) {
            return {};
        }
        return Object.entries(configuration.selections).reduce((result, [key, items]) => {
            if (/^[A-Za-z][A-Za-z0-9_]*$/.test(key)) {
                result[key] = normalizeOptions(items);
            }
            return result;
        }, {});
    };

    const normalizeImageGenerationQualityOptions = (payload) => {
		return Array.isArray(payload?.imageGenerationQualities)
			? normalizeOptions(payload.imageGenerationQualities)
			: [];
    };

	const normalizeCampaignSetQualityOptions = (payload) => {
		return Array.isArray(payload?.campaignSetQualities)
			? normalizeOptions(payload.campaignSetQualities)
			: [];
	};

    const normalizeStyleOptions = (payload) => {
		const configuration = payload?.selections && typeof payload.selections === 'object' ? payload : null;
        return configuration ? normalizeOptions(configuration.styles) : [];
    };

    const normalizeConfigurationOptionSources = (payload) => ({
        configuration: normalizeConfigurationOptions(payload),
        image_generation_qualities: normalizeImageGenerationQualityOptions(payload),
		campaign_set_qualities: normalizeCampaignSetQualityOptions(payload),
        styles: normalizeStyleOptions(payload),
    });

    const hasConfigurationOptions = (optionSources) => Boolean(
        Object.keys(optionSources?.configuration || {}).length
        && optionSources?.image_generation_qualities?.length
        && optionSources?.campaign_set_qualities?.length
    );

    const createTransport = ({ boot = {}, apiFetch, fetchImpl, onAuthExpired } = {}) => {
        const restUrl = String(boot.restUrl || '').replace(/\/$/, '');
        const namespace = namespaceFromRestUrl(restUrl);
        const nonce = String(boot.nonce || '');
        const wpApiFetch = apiFetch || window.wp?.apiFetch;
        const nativeFetch = fetchImpl || window.fetch?.bind(window);
		const notifyAuthExpired = (detail) => {
			if (typeof onAuthExpired !== 'function') return;
			try {
				onAuthExpired(detail);
			} catch {
				window.console?.error?.('Fotogenic AI: the expired account session could not be projected.');
			}
		};
		const normalizeRequestError = (error, path) => {
			const result = normalizeError(error);
			if (result.authExpired) {
				notifyAuthExpired({ path, status: result.status, code: result.code });
			}
			return result;
		};

        const request = async (path, { method = 'GET', data, signal } = {}) => {
            if (!safeRelativePath(path)) {
                return { ok: false, aborted: false, status: 0, message: __( 'The Studio route is unavailable.', 'fotogenic-ai' ) };
            }
            try {
                let body;
                if (typeof wpApiFetch === 'function') {
                    body = await wpApiFetch({
                        path: `${namespace}${path}`,
                        method,
                        data,
                        signal,
                    });
                } else {
                    if (!restUrl || typeof nativeFetch !== 'function') {
                        return { ok: false, aborted: false, status: 0, message: __( 'WordPress REST access is unavailable.', 'fotogenic-ai' ) };
                    }
                    const headers = { Accept: 'application/json' };
                    const options = { method, credentials: 'same-origin', headers, signal };
                    if (nonce) {
                        headers['X-WP-Nonce'] = nonce;
                    }
                    if (data !== undefined) {
                        headers['Content-Type'] = 'application/json';
                        options.body = JSON.stringify(data);
                    }
                    const response = await nativeFetch(`${restUrl}${path}`, options);
                    const contentType = String(response.headers?.get?.('content-type') || '');
                    body = contentType.includes('application/json') ? await response.json() : null;
                    if (!response.ok) {
                        return normalizeRequestError({ status: response.status, data: body }, path);
                    }
                }
                return { ok: true, status: 200, data: body };
            } catch (error) {
                return normalizeRequestError(error, path);
            }
        };

        const getSourcePage = async (sourceType, {
            query = '',
            page = 1,
            perPage = 12,
            filters = {},
            signal,
        } = {}) => {
            const path = SOURCE_PATHS[sourceType];
            if (!path) {
                return { ok: false, status: 0, message: __( 'This source type is unavailable.', 'fotogenic-ai' ) };
            }
            const normalizedPage = Math.min(10000, Math.max(1, Math.floor(Number(page)) || 1));
            const normalizedPerPage = Math.min(24, Math.max(1, Math.floor(Number(perPage)) || 12));
            const normalizedQuery = String(query || '').trim().replace(/\s+/g, ' ').slice(0, 100);
            const categories = Array.isArray(filters?.categories)
                ? [...new Set(filters.categories.map(Number).filter((id) => Number.isInteger(id) && id > 0))].slice(0, 50)
                : [];
            const stock = Array.isArray(filters?.stock)
                ? [...new Set(filters.stock.map(String).filter((value) => ['instock', 'outofstock', 'onbackorder'].includes(value)))]
                : [];
			const mediaFilters = sourceType === 'media' ? {
				type: ['all', 'jpg', 'png', 'webp'].includes(String(filters?.type || '')) ? String(filters.type) : 'all',
				date: ['all', 'today', 'week', 'month', 'older'].includes(String(filters?.date || '')) ? String(filters.date) : 'all',
				orientation: ['all', 'square', 'landscape', 'portrait'].includes(String(filters?.orientation || '')) ? String(filters.orientation) : 'all',
				size: ['all', 'under_300kb', '300kb_and_over'].includes(String(filters?.size || '')) ? String(filters.size) : 'all',
			} : {};
            const result = await request(appendQuery(path, {
                q: normalizedQuery,
                page: normalizedPage,
                perPage: normalizedPerPage,
                ...(sourceType === 'product' ? { categories, stock } : {}),
				...mediaFilters,
            }), { signal });
            if (!result.ok) {
                return result;
            }
            const payload = result.data;
            if (!payload || !Array.isArray(payload.items)) {
                return { ok: false, status: 0, message: __( 'The source response was not valid.', 'fotogenic-ai' ) };
            }
            return {
                ok: true,
                data: {
                    items: payload.items,
                    page: Math.min(10000, Math.max(1, Math.floor(Number(payload.page)) || normalizedPage)),
                    perPage: normalizedPerPage,
                    totalPages: Math.min(10000, Math.max(1, Math.floor(Number(payload.totalPages)) || 1)),
                    totalItems: Math.max(0, Math.floor(Number(payload.totalItems)) || 0),
                },
            };
        };

        const getEstimateContext = ({ tier = '', balance = false, signal } = {}) => request('/studio/estimate-context', {
            method: 'POST', data: { tier, balance }, signal,
        });

        const getProductSelectionPage = async (selection, { page = 1, perPage = 10, signal } = {}) => {
            const result = await request('/studio/products/selection', {
                method: 'POST',
                signal,
                data: {
                    q: selection.query?.search || '',
                    categories: selection.query?.categories || [],
                    stock: selection.query?.stock || [],
                    selectedIds: selection.selectedIds || [],
                    excludedIds: selection.excludedIds || [],
                    page,
                    perPage,
                },
            });
            if (!result.ok) return result;
            if (!Array.isArray(result.data?.items) || !Number.isSafeInteger(result.data.totalItems)
                || result.data.totalItems < 0 || result.data.items.length > perPage
                || result.data.items.some((item) => !Number.isSafeInteger(item?.id) || item.id < 1)
                || new Set(result.data.items.map((item) => item.id)).size !== result.data.items.length
                || (!result.data.items.length && result.data.totalItems > (page - 1) * perPage)) {
                return { ok: false, message: __( 'The product selection response was not valid.', 'fotogenic-ai' ) };
            }
            return result;
        };

        const getSourceSummary = async (sourceType, id, { signal } = {}) => {
            const path = SUMMARY_PATHS[sourceType];
            const normalizedId = Math.floor(Number(id));
            if (!path || normalizedId <= 0) {
                return { ok: false, status: 0, message: __( 'The selected source is unavailable.', 'fotogenic-ai' ) };
            }
            const result = await request(appendQuery(path, { id: normalizedId }), { signal });
            if (!result.ok) {
                return result;
            }
            const payload = result.data;
            return payload && typeof payload === 'object'
                ? { ok: true, data: payload }
                : { ok: false, status: 0, message: __( 'The selected source response was not valid.', 'fotogenic-ai' ) };
        };

        const getProductContext = async (productId, { signal } = {}) => {
            const normalizedId = Math.floor(Number(productId));
            if (normalizedId <= 0) {
                return { ok: false, status: 0, message: __( 'The selected Product is unavailable.', 'fotogenic-ai' ) };
            }
            const result = await request(appendQuery(PRODUCT_CONTEXT_PATH, { productId: normalizedId }), { signal });
            if (!result.ok) {
                return result;
            }
            const payload = result.data;
            if (!payload || typeof payload !== 'object' || Number(payload.product?.id) !== normalizedId) {
                return { ok: false, status: 0, message: __( 'The selected Product images are unavailable.', 'fotogenic-ai' ) };
            }
            return { ok: true, data: payload };
        };

		const getProductVariations = async (parentProductId, {
			query = '',
			page = 1,
			perPage = 8,
			stock = '',
			attributes = {},
			signal,
		} = {}) => {
			const normalizedParentId = Math.floor(Number(parentProductId));
			if (normalizedParentId <= 0) {
				return { ok: false, status: 0, message: __( 'The parent Product is unavailable.', 'fotogenic-ai' ) };
			}
			const normalizedPage = Math.min(100, Math.max(1, Math.floor(Number(page)) || 1));
			const normalizedPerPage = Math.min(50, Math.max(1, Math.floor(Number(perPage)) || 8));
			const normalizedStock = ['instock', 'outofstock', 'onbackorder'].includes(String(stock || ''))
				? String(stock)
				: '';
			const normalizedAttributes = Object.fromEntries(
				Object.entries(attributes && typeof attributes === 'object' ? attributes : {})
					.slice(0, 4)
					.map(([key, value]) => [
						String(key || '').trim().slice(0, 80),
						String(value || '').trim().slice(0, 120),
					])
					.filter(([key, value]) => key && value)
			);
			const result = await request(appendQuery(PRODUCT_VARIATIONS_PATH, {
				parentProductId: normalizedParentId,
				q: String(query || '').trim().replace(/\s+/g, ' ').slice(0, 100),
				page: normalizedPage,
				perPage: normalizedPerPage,
				stock: normalizedStock,
				attributes: Object.keys(normalizedAttributes).length ? JSON.stringify(normalizedAttributes) : '',
			}), { signal });
			if (!result.ok) return result;
			const payload = result.data;
			if (
				!payload
				|| Number(payload.parentProductId) !== normalizedParentId
				|| !Array.isArray(payload.items)
			) {
				return { ok: false, status: 0, message: __( 'The variation response was not valid.', 'fotogenic-ai' ) };
			}
			return {
				ok: true,
				data: {
					items: payload.items,
					attributeOptions: (Array.isArray(payload.attributeOptions) ? payload.attributeOptions : [])
						.map((attribute) => ({
							key: String(attribute?.key || '').trim(),
							label: String(attribute?.label || '').trim(),
							options: [...new Set((Array.isArray(attribute?.options) ? attribute.options : [])
								.map((value) => String(value || '').trim())
								.filter(Boolean))],
						}))
						.filter((attribute) => attribute.key && attribute.options.length),
					parentProductId: normalizedParentId,
					page: Math.min(100, Math.max(1, Math.floor(Number(payload.page)) || normalizedPage)),
					perPage: normalizedPerPage,
					totalPages: Math.min(100, Math.max(1, Math.floor(Number(payload.totalPages)) || 1)),
					totalItems: Math.max(0, Math.floor(Number(payload.totalItems)) || 0),
				},
			};
		};

        const preflight = async (draft, { signal } = {}) => {
            const path = boot.rest?.universalPreflight;
            if (!safeRelativePath(path)) {
                return { ok: false, status: 0, message: __( 'Authoritative pricing is unavailable.', 'fotogenic-ai' ) };
            }
            const result = await request(path, { method: 'POST', data: { draft }, signal });
            if (!result.ok) {
                return result;
            }
            const payload = result.data;
            return payload && typeof payload === 'object'
                ? { ok: true, data: payload }
                : { ok: false, status: 0, message: __( 'Authoritative pricing is unavailable.', 'fotogenic-ai' ) };
        };

        const snapshotBulk = async (draft, { signal } = {}) => {
            const path = boot.rest?.bulkSnapshot;
            if (!safeRelativePath(path)) {
                return { ok: false, status: 0, message: __( 'This page cannot prepare your review. Reload Studio and try again.', 'fotogenic-ai' ) };
            }
            const result = await request(path, { method: 'POST', data: { draft }, signal });
            if (!result.ok) {
                return result;
            }
            const payload = result.data;
            if (
                !payload
                || payload.snapshotVersion !== 1
                || !payload.draft
                || payload.draft.selection?.strategy !== 'explicit'
                || !Array.isArray(payload.draft.selection?.selectedIds)
                || typeof payload.draftFingerprint !== 'string'
                || !/^[a-f0-9]{64}$/.test(payload.draftFingerprint)
                || typeof payload.snapshotFingerprint !== 'string'
                || !/^[a-f0-9]{64}$/.test(payload.snapshotFingerprint)
                || !payload.preflight
                || !Array.isArray(payload.selected)
            ) {
                return { ok: false, status: 0, message: __( 'We could not verify the review. Reload Studio and try again.', 'fotogenic-ai' ) };
            }
            return { ok: true, data: payload };
        };

		const snapshotStoreQueue = (envelope, { signal } = {}) => routeRequest('storeQueueSnapshot', {
			method: 'POST',
			data: envelope,
			signal,
			unavailable: __( 'Whole-store Product preparation is unavailable.', 'fotogenic-ai' ),
		});

        const getProductCategories = async ({ signal } = {}) => {
            const path = boot.rest?.productCategories;
            if (!safeRelativePath(path)) {
                return { ok: false, status: 0, message: __( 'Product categories are unavailable.', 'fotogenic-ai' ) };
            }
            const result = await request(path, { signal });
            if (!result.ok) return result;
            const payload = result.data;
            if (!payload || !Array.isArray(payload.items)) {
                return { ok: false, status: 0, message: __( 'Product categories are unavailable.', 'fotogenic-ai' ) };
            }
            return {
                ok: true,
                data: payload.items.map((item) => ({
                    id: Math.floor(Number(item?.id)),
                    name: String(item?.name || '').trim().slice(0, 200),
                    count: Math.max(0, Math.floor(Number(item?.count)) || 0),
                })).filter((item) => item.id > 0 && item.name),
            };
        };

        const getWorkflowManifest = async ({ signal } = {}) => {
            const path = boot.rest?.universalManifest;
            if (!safeRelativePath(path)) {
                return { ok: false, status: 0, message: __( 'The Studio workflow definition is unavailable.', 'fotogenic-ai' ) };
            }
            const result = await request(path, { signal });
            if (!result.ok) {
                return result;
            }
            const payload = result.data;
            return payload && typeof payload === 'object'
                ? { ok: true, data: payload }
                : { ok: false, status: 0, message: __( 'The Studio workflow definition is unavailable.', 'fotogenic-ai' ) };
        };

        const getConfigurationOptions = async ({ signal } = {}) => {
			const path = boot.rest?.configuration;
            if (!safeRelativePath(path)) {
                return { ok: false, status: 0, message: __( 'Configuration options are unavailable.', 'fotogenic-ai' ) };
            }
            const result = await request(path, { signal });
            if (!result.ok) {
                return result;
            }
            const optionSources = normalizeConfigurationOptionSources(result.data);
			return hasConfigurationOptions(optionSources)
                ? { ok: true, data: optionSources }
                : { ok: false, status: 0, message: __( 'Configuration options are unavailable.', 'fotogenic-ai' ) };
        };

		const routeRequest = async (routeName, { method = 'GET', data, params, signal, unavailable, nullable = false } = {}) => {
            const path = boot.rest?.[routeName];
            if (!safeRelativePath(path)) {
                return { ok: false, aborted: false, status: 0, code: '', uncertain: false, message: unavailable };
            }
            const requestPath = params ? appendQuery(path, params) : path;
            const result = await request(requestPath, { method, data, signal });
            if (!result.ok) return result;
            const payload = result.data;
            return (nullable && payload === null) || (payload && typeof payload === 'object')
                ? { ok: true, status: result.status, data: payload }
                : { ok: false, aborted: false, status: 0, code: 'invalid_response', uncertain: true, message: unavailable };
        };

        const fixedStudioRequest = async (path, { method = 'GET', data, params, signal, unavailable } = {}) => {
            const requestPath = params ? appendQuery(path, params) : path;
            const result = await request(requestPath, { method, data, signal });
            if (!result.ok) return result;
            const payload = result.data;
            return payload && typeof payload === 'object'
                ? { ok: true, status: result.status, data: payload }
                : { ok: false, aborted: false, status: 0, code: 'invalid_response', uncertain: false, message: unavailable };
        };

        const autoConfigure = (configurationRequest, { signal } = {}) => fixedStudioRequest(GENERATE_CONFIGURATION_PATH, {
            method: 'POST',
            data: { request: configurationRequest },
            signal,
            unavailable: __( 'Configuration could not be generated. Review the selected images and try again.', 'fotogenic-ai' ),
        });

        const listPresets = (route, { signal } = {}) => fixedStudioRequest(UNIVERSAL_PRESET_PATHS.list, {
            params: {
                workflow: route.workflow,
                sourceType: route.sourceType,
                scope: route.scope,
            },
            signal,
            unavailable: __( 'Saved presets are unavailable.', 'fotogenic-ai' ),
        });

        const getPreset = (presetUuid, route, { signal } = {}) => fixedStudioRequest(UNIVERSAL_PRESET_PATHS.get, {
            params: {
                uuid: String(presetUuid || ''),
                workflow: route.workflow,
                sourceType: route.sourceType,
                scope: route.scope,
            },
            signal,
            unavailable: __( 'The selected preset could not be loaded.', 'fotogenic-ai' ),
        });

        const savePreset = ({ presetUuid = '', name = '', snapshot } = {}, { signal } = {}) => fixedStudioRequest(UNIVERSAL_PRESET_PATHS.save, {
            method: 'POST',
            data: {
                presetUuid: String(presetUuid || ''),
                name: String(name || ''),
                snapshot,
            },
            signal,
            unavailable: __( 'The preset could not be saved.', 'fotogenic-ai' ),
        });

        const deletePreset = (presetUuid, route, { signal } = {}) => fixedStudioRequest(UNIVERSAL_PRESET_PATHS.delete, {
            method: 'POST',
            data: {
                presetUuid: String(presetUuid || ''),
                workflow: route.workflow,
                sourceType: route.sourceType,
                scope: route.scope,
            },
            signal,
            unavailable: __( 'The preset could not be removed.', 'fotogenic-ai' ),
        });

        const listLibrary = (type, { page = 1, perPage = 12, signal } = {}) => fixedStudioRequest(LIBRARY_PATHS.list, {
            params: {
                type: ['model', 'environment'].includes(type) ? type : '',
                page: Math.min(100, Math.max(1, Math.floor(Number(page)) || 1)),
                perPage: Math.min(48, Math.max(1, Math.floor(Number(perPage)) || 12)),
            },
            signal,
            unavailable: __( 'Saved references are unavailable.', 'fotogenic-ai' ),
        });

        const addLibraryItem = (type, attachmentId, { signal } = {}) => fixedStudioRequest(LIBRARY_PATHS.add, {
            method: 'POST',
            data: {
                type: ['model', 'environment'].includes(type) ? type : '',
                attachmentId: Math.max(0, Math.floor(Number(attachmentId)) || 0),
            },
            signal,
            unavailable: __( 'The reference could not be added to the saved library.', 'fotogenic-ai' ),
        });

        const startSingle = (envelope) => routeRequest('universalStart', {
            method: 'POST',
            data: envelope,
            unavailable: __( 'Generation start is unavailable.', 'fotogenic-ai' ),
        });

        const startBulk = (envelope) => routeRequest('bulkStart', {
            method: 'POST',
            data: envelope,
            unavailable: __( 'Bulk generation start is unavailable.', 'fotogenic-ai' ),
        });

		const startStoreQueue = (envelope) => routeRequest('storeQueueStart', {
			method: 'POST',
			data: envelope,
			unavailable: __( 'Product queue start is unavailable.', 'fotogenic-ai' ),
		});

        const getActiveRun = (identity, { signal } = {}) => routeRequest('activeRun', {
            params: {
                sourceType: identity.sourceType,
                subjectId: identity.subjectId,
                workflow: identity.workflow,
                requestId: identity.requestId,
            },
            signal,
            unavailable: __( 'Generation status is unavailable.', 'fotogenic-ai' ),
        });

        const pollRun = (identity, { signal } = {}) => routeRequest('pollRun', {
            method: 'POST',
            data: {
                jobIds: identity.jobIds,
                workflow: identity.workflow,
                requestId: identity.requestId,
                runId: identity.runId,
                sourceType: identity.sourceType,
                subjectId: identity.subjectId,
            },
            signal,
            unavailable: __( 'Generation status is unavailable.', 'fotogenic-ai' ),
        });

        const getGlobalHistory = ({ page = 1, perPage = 12, query = '', status = 'all', signal } = {}) => routeRequest('globalHistory', {
            params: {
                page: Math.min(1000, Math.max(1, Math.floor(Number(page)) || 1)),
                perPage: Math.min(48, Math.max(1, Math.floor(Number(perPage)) || 12)),
                query: String(query || '').trim().slice(0, 200),
                status: ['queued', 'starting', 'processing', 'paused', 'stopping', 'uncertain', 'partial', 'completed', 'failed', 'stopped', 'removed'].includes(String(status || '').toLowerCase())
                    ? String(status).toLowerCase()
                    : 'all',
            },
            signal,
            unavailable: __( 'Run history is unavailable.', 'fotogenic-ai' ),
        });

		const resultIdentityPayload = (identity, attachmentIds) => {
            const payload = {
                runId: String(identity?.runId || '').slice(0, 64),
                requestId: String(identity?.requestId || '').toLowerCase().slice(0, 36),
                workflow: String(identity?.workflow || ''),
                sourceType: String(identity?.sourceType || ''),
                scope: String(identity?.scope || ''),
                subjectId: Math.max(0, Math.floor(Number(identity?.subjectId)) || 0),
                attachmentIds: [...new Set((Array.isArray(attachmentIds) ? attachmentIds : [])
                    .map((value) => Math.max(0, Math.floor(Number(value)) || 0))
                    .filter(Boolean))].slice(0, 10),
            };
            if (identity?.runItemId) {
                payload.runItemId = String(identity.runItemId).toLowerCase().slice(0, 36);
                payload.campaignGroupId = identity.campaignGroupId
                    ? String(identity.campaignGroupId).toLowerCase().slice(0, 36)
                    : null;
                payload.itemOrdinal = Math.max(0, Math.floor(Number(identity.itemOrdinal)) || 0);
                payload.targetIdentity = {
                    targetType: String(identity.targetIdentity?.targetType || ''),
                    targetId: Math.max(0, Math.floor(Number(identity.targetIdentity?.targetId)) || 0),
                    parentProductId: Math.max(0, Math.floor(Number(identity.targetIdentity?.parentProductId)) || 0),
                    variationId: Math.max(0, Math.floor(Number(identity.targetIdentity?.variationId)) || 0),
                };
            }
            if (payload.scope === 'bulk') {
                payload.bulkRunUuid = String(identity?.bulkRunUuid || '').toLowerCase().slice(0, 36);
                payload.bulkItemId = Math.max(0, Math.floor(Number(identity?.bulkItemId)) || 0);
            }
            return payload;
        };

        const applyResult = (identity, action, attachmentIds) => routeRequest('resultApply', {
            method: 'POST',
            data: { ...resultIdentityPayload(identity, attachmentIds), action: String(action || '') },
            unavailable: __( 'The result action is unavailable.', 'fotogenic-ai' ),
        });

        const removeResult = (identity, attachmentId) => routeRequest('resultRemove', {
            method: 'POST',
            data: resultIdentityPayload(identity, [attachmentId]),
            unavailable: __( 'Generated attachment removal is unavailable.', 'fotogenic-ai' ),
        });

		const getBulkProgress = ({ runUuid, signal } = {}) => routeRequest('bulkProgress', {
            method: 'POST',
            data: {
				runUuid: String(runUuid || ''),
            },
            signal,
            unavailable: __( 'Bulk status is unavailable.', 'fotogenic-ai' ),
        });

		const getActiveBulk = ({ signal } = {}) => routeRequest('bulkActive', {
            signal,
			nullable: true,
            unavailable: __( 'Bulk recovery is unavailable.', 'fotogenic-ai' ),
        });

		const getStoreQueueProgress = ({ queueUuid, page = 1, perPage = 25, status = '', signal } = {}) => routeRequest('storeQueueProgress', {
			params: {
				queueUuid: String(queueUuid || ''),
				page: Math.min(100000, Math.max(1, Math.floor(Number(page)) || 1)),
				perPage: Math.min(48, Math.max(1, Math.floor(Number(perPage)) || 25)),
				status: String(status || ''),
			},
			signal,
			unavailable: __( 'Product queue status is unavailable.', 'fotogenic-ai' ),
		});

		const getActiveStoreQueue = ({ signal } = {}) => routeRequest('storeQueueActive', {
			signal,
			nullable: true,
			unavailable: __( 'Product queue recovery is unavailable.', 'fotogenic-ai' ),
		});

		const controlStoreQueue = (action, queueUuid) => routeRequest(action, {
			method: 'POST',
			data: { queueUuid: String(queueUuid || '') },
			unavailable: __( 'The Product queue control is unavailable.', 'fotogenic-ai' ),
		});

        const controlBulk = (action, runUuid) => routeRequest(action, {
            method: 'POST',
            data: { runUuid: String(runUuid || '') },
            unavailable: __( 'The bulk control is unavailable.', 'fotogenic-ai' ),
        });

        return Object.freeze({
            request,
            getSourcePage,
            getProductSelectionPage,
            getEstimateContext,
            getSourceSummary,
            getProductContext,
			getProductVariations,
			getWorkflowManifest,
			getConfigurationOptions,
			preflight,
            snapshotBulk,
			snapshotStoreQueue,
            getProductCategories,
            autoConfigure,
            listPresets,
            getPreset,
            savePreset,
            deletePreset,
            listLibrary,
            addLibraryItem,
            startSingle,
            startBulk,
			startStoreQueue,
            getActiveRun,
			pollRun,
			getGlobalHistory,
			applyResult,
            removeResult,
            getBulkProgress,
            getActiveBulk,
			getStoreQueueProgress,
			getActiveStoreQueue,
            pauseBulk: (runUuid) => controlBulk('bulkPause', runUuid),
            resumeBulk: (runUuid) => controlBulk('bulkResume', runUuid),
            stopBulk: (runUuid) => controlBulk('bulkStop', runUuid),
			pauseStoreQueue: (queueUuid) => controlStoreQueue('storeQueuePause', queueUuid),
			resumeStoreQueue: (queueUuid) => controlStoreQueue('storeQueueResume', queueUuid),
			stopStoreQueue: (queueUuid) => controlStoreQueue('storeQueueStop', queueUuid),
        });
    };

    Studio.transport = Object.freeze({
        createTransport,
        safeRelativePath,
		normalizeError,
        normalizeConfigurationOptions,
        normalizeConfigurationOptionSources,
        hasConfigurationOptions,
    });
})();
