document.addEventListener('DOMContentLoaded', () => {
    const { __, sprintf } = wp.i18n;
    const icons = window.FotogenicAI?.Shared?.ui?.icon;
    if (!icons?.create || !icons?.update) {
        throw new Error('Fotogenic AI: icon.js must load before settings.js');
    }
    const settingsBoot = window.FotogenicAI?.Admin?.settings || {};
    const restUrl = typeof settingsBoot.restUrl === 'string' ? settingsBoot.restUrl : '';
    const restNonce = typeof settingsBoot.restNonce === 'string' ? settingsBoot.restNonce : '';

    const ctx = {
        i18n: { __: (s) => (wp.i18n && typeof wp.i18n.__ === 'function' ? wp.i18n.__(s, 'fotogenic-ai') : s) },
        restUrl,
        restNonce,
        debugLoggingEnabled: settingsBoot?.debugLoggingEnabled === true || settingsBoot?.debugLoggingEnabled === 1 || settingsBoot?.debugLoggingEnabled === '1',
        state: {
            currentStepKey: 'settings',
            nonceOverlayShown: false,
            authExpired: false,
            authErrorSuppressUntil: 0,
            authLoginPending: false,
            authLoginStartedAt: 0,
            authPostLoginRefreshPromise: null,
        },
    };
    ctx.handleAuthExpired = () => {
        handleAuthExpiredSession();
    };
    const overlayRoot = document.getElementById('fotogenic-ai-error-overlay-root');
    const createErrorSystem = window.FotogenicAI?.Shared?.core?.error?.createErrorSystem;
    if (overlayRoot && typeof createErrorSystem === 'function') {
        ctx.errors = createErrorSystem(ctx);
    }
    let restFetch = null;
    const createRestFetch = window.FotogenicAI?.Shared?.api?.restFetch?.createRestFetch;
    if (typeof createRestFetch === 'function' && restUrl && restNonce) {
        restFetch = createRestFetch(restUrl, restNonce, {
            setNonceExpired: () => {},
            onNonceExpired: () => {
                if (ctx.state.nonceOverlayShown) return;
                ctx.state.nonceOverlayShown = true;
                if (ctx.errors?.report) {
                    const buildError = window.FotogenicAI?.Shared?.core?.error?.buildError;
                    if (buildError) {
                        const err = buildError('INVALID_NONCE', ctx.i18n.__('Session expired. Please reload the page.'), { source: 'network' });
                        ctx.errors.report(err, { onRetry: () => window.location.reload(), retryLabel: __('Reload', 'fotogenic-ai') });
                    }
                }
            },
            setAuthExpired: () => {
                ctx.state.authExpired = true;
                ctx.state.authErrorSuppressUntil = Date.now() + 1500;
            },
            onAuthExpired: () => {
                handleAuthExpiredSession();
            },
        });
    }

    let activeController = null;
    const apiFetch = async (path, options = {}) => {
        if (!restFetch) {
            return { ok: false, data: { message: __('REST context is missing.', 'fotogenic-ai') } };
        }
        const result = await restFetch(path, {
            method: options.method || 'GET',
            body: options.body,
            signal: options.signal,
        });
        if (result.status === 204) {
            return { ok: true, data: {} };
        }
        return {
            ok: result.ok,
            data: result.data || {},
            message: result.message,
            status: result.status,
            aborted: result.aborted,
            authExpired: result.authExpired === true,
            handledAuthExpired: result.handledAuthExpired === true,
        };
    };

    const settingsForm = document.getElementById('fotogenic-ai-settings-form');
    const settingsRoot = document.querySelector('.fotogenic-ai-settings');
    const settingsShell = document.querySelector('.fotogenic-ai-settings-shell');
    const configRefreshButton = document.getElementById('fotogenic-ai-config-refresh');
    const authWrap = document.getElementById('fotogenic-ai-auth-wrap');
    const authTitle = document.getElementById('fotogenic-ai-auth-title');
    const authEmail = document.getElementById('fotogenic-ai-auth-email');
    const authManageButton = document.getElementById('fotogenic-ai-auth-manage');
    const authLoginButton = document.getElementById('fotogenic-ai-auth-login');
    const authLogoutButton = document.getElementById('fotogenic-ai-auth-logout');
    const authLogoutRow = document.getElementById('fotogenic-ai-settings-logout-row');
    const logoutConfirmLayer = document.getElementById('fotogenic-ai-settings-logout-confirm');
    const logoutConfirmPanel = logoutConfirmLayer?.querySelector('.fotogenic-ai-settings-confirm');
    const logoutConfirmButton = document.getElementById('fotogenic-ai-settings-logout-confirm-button');
    const logoutCancelButton = document.getElementById('fotogenic-ai-settings-logout-cancel');
    const customInstructionsField = document.getElementById('fotogenic-ai-settings-custom-instructions');
    const customInstructionsCount = document.getElementById('fotogenic-ai-settings-guidance-count');
    const saveButton = document.getElementById('fotogenic-ai-settings-save');
    const debugLoggingCheckbox = document.getElementById('fotogenic-ai-settings-debug-logging');
    const debugTrigger = document.getElementById('fotogenic-ai-settings-debug-trigger');
    const debugWorkspace = document.getElementById('fotogenic-ai-settings-debug-workspace');
    const optionName = settingsForm ? settingsForm.dataset.optionName || '' : '';
    const AUTH_SYNC_KEY = 'fotogenic_ai_auth_sync';
    const AUTH_SYNC_CHANNEL = 'fotogenic_ai_auth';
    let lastHandledAuthSyncId = '';
    let experienceController = null;
    let lastFocusRefreshAt = 0;

    let lastSavedSettingsSignature = '';
    let activeSaveSignature = '';
    let settingsDirty = false;
    let loadDebugWorkspace = () => Promise.resolve();
    let logoutConfirmOverlay = null;
    ctx.state.auth = settingsBoot?.auth && typeof settingsBoot.auth === 'object' ? settingsBoot.auth : {};
    ctx.state.authConnected = !!ctx.state.auth.connected;

    const containedOverlayFactory = window.FotogenicAI?.Shared?.ui?.containedOverlay?.create;
    if (logoutConfirmLayer && logoutConfirmPanel && typeof containedOverlayFactory === 'function') {
        logoutConfirmOverlay = containedOverlayFactory({
            layer: logoutConfirmLayer,
            panel: logoutConfirmPanel,
            decorate: false,
            closeOnBackdrop: true,
            initialFocus: logoutCancelButton,
            onClose: (overlay) => overlay.close(),
        });
    }

    if (settingsShell) {
        const availableHeightProperty = '--fa-settings-available-height';
        const geometryAbortController = new AbortController();
        let geometryFrame = 0;
        const syncAvailableHeight = () => {
            geometryFrame = 0;
            const viewportHeight = document.documentElement.clientHeight;
            const shellTop = settingsShell.getBoundingClientRect().top;
            const pageBottomSpace = Number.parseFloat(window.getComputedStyle(settingsShell).marginBottom) || 0;
            settingsShell.style.setProperty(availableHeightProperty, `${Math.max(0, viewportHeight - shellTop - pageBottomSpace)}px`);
        };
        const scheduleGeometrySync = () => {
            if (geometryAbortController.signal.aborted || geometryFrame) return;
            geometryFrame = window.requestAnimationFrame(syncAvailableHeight);
        };
        const visualViewport = window.visualViewport;
        const geometryObserver = typeof ResizeObserver === 'function'
            ? new ResizeObserver(scheduleGeometrySync)
            : null;
        const listenerOptions = { passive: true, signal: geometryAbortController.signal };

        window.addEventListener('resize', scheduleGeometrySync, listenerOptions);
        window.addEventListener('scroll', scheduleGeometrySync, listenerOptions);
        visualViewport?.addEventListener('resize', scheduleGeometrySync, listenerOptions);
        visualViewport?.addEventListener('scroll', scheduleGeometrySync, listenerOptions);
        geometryObserver?.observe(settingsShell.parentElement ?? settingsShell);
        window.addEventListener('pagehide', () => {
            if (geometryFrame) window.cancelAnimationFrame(geometryFrame);
            geometryObserver?.disconnect();
            geometryAbortController.abort();
            settingsShell.style.removeProperty(availableHeightProperty);
        }, { once: true });
        scheduleGeometrySync();
    }

    function createButtonSpinner() {
		const span = icons.create('arrows-clockwise', { weight: 'regular', size: 20 });
		span.classList.add('fotogenic-ai-icon--spin');
        span.setAttribute('role', 'status');
        span.setAttribute('aria-label', __('Loading', 'fotogenic-ai'));
        return span;
    }

    function setButtonLoading(button, loading) {
        if (!button) return;
        if (loading) {
            if (!button.classList.contains('is-loading')) {
                button.dataset.restoreFocusAfterLoading = document.activeElement === button ? '1' : '0';
            }
            const rect = button.getBoundingClientRect();
            if (typeof button.dataset.originalContent === 'undefined' || button.dataset.originalContent === '') {
                button.dataset.originalContent = button.innerHTML;
            }
            button.style.minWidth = rect.width + 'px';
            button.style.minHeight = rect.height + 'px';
            button.innerHTML = '';
            button.appendChild(createButtonSpinner());
            button.disabled = true;
            button.classList.add('is-loading');
        } else {
			const spinner = button.querySelector('.fotogenic-ai-icon--spin');
            if (spinner) spinner.remove();
            if (typeof button.dataset.originalContent !== 'undefined' && button.dataset.originalContent !== '') {
                button.innerHTML = button.dataset.originalContent;
            }
            button.style.minWidth = '';
            button.style.minHeight = '';
            button.disabled = false;
            button.classList.remove('is-loading');
            const shouldRestoreFocus = button.dataset.restoreFocusAfterLoading === '1';
            delete button.dataset.restoreFocusAfterLoading;
            if (shouldRestoreFocus) {
                window.requestAnimationFrame(() => {
                    if (
                        button.isConnected
                        && !button.disabled
                        && !button.hidden
                        && button.getClientRects().length > 0
                    ) {
                        button.focus({ preventScroll: true });
                    }
                });
            }
        }
    }

    const syncConfigRefreshAvailability = () => {
        if (!configRefreshButton) return;
        const disabled = !ctx.state.authConnected || configRefreshButton.classList.contains('is-loading');
        configRefreshButton.disabled = disabled;
        configRefreshButton.setAttribute('aria-disabled', disabled ? 'true' : 'false');
    };

	const setLogoutPending = (pending) => {
		if (!authLogoutButton) return;
		ctx.state.authLogoutPending = pending === true;
		if (pending) {
			if (authLogoutRow) {
				authLogoutRow.hidden = false;
				authLogoutRow.setAttribute('aria-busy', 'true');
			}
			authLogoutButton.hidden = false;
			authLogoutButton.style.display = 'inline-flex';
		}
		setButtonLoading(authLogoutButton, pending);
		if (pending) {
			const label = document.createElement('span');
			label.textContent = __( 'Logging out…', 'fotogenic-ai' );
			authLogoutButton.appendChild(label);
			authLogoutButton.setAttribute('aria-busy', 'true');
			authLogoutButton.setAttribute('aria-label', __( 'Logging out', 'fotogenic-ai' ));
			return;
		}
		authLogoutRow?.removeAttribute('aria-busy');
		authLogoutButton.removeAttribute('aria-busy');
		authLogoutButton.removeAttribute('aria-label');
	};

    let notify = null;
    const createNotifySystem = window.FotogenicAI?.Shared?.ui?.notifications?.createNotifySystem;
    if (typeof createNotifySystem === 'function') {
        const root = document.getElementById('fotogenic-ai-notifications-root');
        if (root) {
            notify = createNotifySystem({ i18n: ctx.i18n, restUrl, restNonce });
        }
    }

    const transientToastOpts = { activity: false };

    const createNotificationCenter = window.FotogenicAI?.Shared?.ui?.notifications?.notificationCenter?.create;
    if (
        typeof createNotificationCenter === 'function'
        && document.querySelector('[data-fa-header-actions]')
    ) {
        createNotificationCenter({
            root: document.querySelector('.fotogenic-ai-settings-shell'),
            restFetch,
            i18n: ctx.i18n,
            notify,
        });
    }
    const beginAuthLoginPending = () => {
        ctx.state.authLoginPending = true;
        ctx.state.authLoginStartedAt = Date.now();
        if (authLoginButton && !authLoginButton.classList.contains('is-loading')) {
            setButtonLoading(authLoginButton, true);
        }
    };

    const finishAuthLoginPending = () => {
        ctx.state.authLoginPending = false;
        ctx.state.authLoginStartedAt = 0;
        setButtonLoading(authLoginButton, false);
    };

    function handleAuthExpiredSession() {
        ctx.state.authExpired = true;
        ctx.state.authErrorSuppressUntil = Date.now() + 1500;
        finishAuthLoginPending();
		setLogoutPending(false);
        applyAuthStatus({
            ...(ctx.state.auth && typeof ctx.state.auth === 'object' ? ctx.state.auth : {}),
            connected: false,
            balance: null,
        });
        updateCreditsDisplay(null);
        if (creditsCache?.clearBalance) {
            creditsCache.clearBalance();
        }
        if (authTitle) {
            authTitle.textContent = __('Session expired', 'fotogenic-ai');
        }
        window.dispatchEvent(new CustomEvent('fotogenic-ai:auth-changed', {
            detail: { auth: { connected: false, balance: null, expired: true } },
        }));
        if (notify) {
            notify.warning(__('Your Fotogenic session expired. Log in again to continue.', 'fotogenic-ai'), {
                dedupeKey: 'fotogenic-auth-expired',
            });
        }
    }

    const showAuthBootNotice = () => {
        const notice = settingsBoot?.authNotice;
        if (!notify || !notice || typeof notice !== 'object') {
            return;
        }
        const message = String(notice.message || '').trim();
        if (!message) {
            return;
        }
        if (notice.type === 'success' && notice.connected === true) {
            window.dispatchEvent(new CustomEvent('fotogenic-ai:auth-transition', {
                detail: { state: 'login_success' },
            }));
            return;
        }
        if (notice.type === 'success') {
            notify.success(message);
            return;
        }
        if (notice.type === 'error') {
            notify.warning(message);
            return;
        }
        notify.info(message);
    };

    const setStatus = (message, state) => {
        if (!notify) return;
        if (state === 'loading') notify.info(message, transientToastOpts);
        else if (state === 'success') notify.success(message);
        else if (state === 'error') notify.warning(message);
    };

    const setConfigRefreshStatus = (message, state) => {
        if (!notify) return;
        if (state === 'loading') notify.info(message, transientToastOpts);
        else if (state === 'success') notify.success(message);
        else if (state === 'error') notify.warning(message);
    };

    const showAuthSyncNotice = (notice) => {
        if (!notify || !notice || typeof notice !== 'object') {
            return;
        }
        const message = String(notice.message || '').trim();
        if (!message) {
            return;
        }
        if (notice.type === 'success') {
            notify.success(message);
            return;
        }
        if (notice.type === 'error') {
            notify.warning(message);
            return;
        }
        notify.info(message);
    };

    const shouldDeferAuthNoticeUntilStatus = (notice) => {
        if (!notice || typeof notice !== 'object') {
            return false;
        }
        return notice.type !== 'error' && !!notice.connected;
    };

    const syncAuthStatusFromServer = (notice = null) => {
        apiFetch('/auth/status', { method: 'GET' }).then(({ ok, data, handledAuthExpired }) => {
            if (handledAuthExpired) {
                return;
            }
            if (!ok) {
                if (ctx.state.authLoginPending && notice && !notice.connected) {
                    finishAuthLoginPending();
                }
                if (notice && !shouldDeferAuthNoticeUntilStatus(notice)) {
                    showAuthSyncNotice(notice);
                }
                return;
            }
            const wasConnected = !!ctx.state.authConnected;
            applyAuthStatus(data);
            updateCreditsDisplay(data?.balance ?? null);
            const finalizePending = () => {
                if (!ctx.state.authLoginPending) {
                    return;
                }
                if (data.connected || (notice && !notice.connected)) {
                    finishAuthLoginPending();
                }
            };
            if (!wasConnected && data.connected) {
                runPostLoginRefresh(data).then(({ connected }) => {
                    finalizePending();
                    if (connected) {
                        window.dispatchEvent(new CustomEvent('fotogenic-ai:auth-changed', {
                            detail: { auth: { ...data, connected: true } },
                        }));
                    } else {
                        requestExperience({ force: true });
                    }
                }).catch(() => {
                    finalizePending();
                });
            } else {
                finalizePending();
            }
            if (notice && !shouldDeferAuthNoticeUntilStatus(notice)) {
                showAuthSyncNotice(notice);
            }
        }).catch(() => {
            if (ctx.state.authLoginPending && notice && !notice.connected) {
                finishAuthLoginPending();
            }
            if (notice && !shouldDeferAuthNoticeUntilStatus(notice)) {
                showAuthSyncNotice(notice);
            }
        });
    };

    const runPostLoginRefresh = (authStatus = null) => {
        if (ctx.state.authPostLoginRefreshPromise) {
            return ctx.state.authPostLoginRefreshPromise;
        }

        const fallbackAuth = authStatus && typeof authStatus === 'object' ? authStatus : {};
        const promise = apiFetch('/settings/cache/refresh', { method: 'POST' }).then(async ({ ok, data, handledAuthExpired }) => {
            if (handledAuthExpired) {
                return { ok: false, connected: false, balance: null };
            }

            let nextAuth = fallbackAuth;
            let balance = null;

            if (ok && data && typeof data === 'object') {
                nextAuth = data?.auth && typeof data.auth === 'object' ? data.auth : fallbackAuth;
                applyAuthStatus(nextAuth);

                const refreshedBalance = Number(data?.credits?.balance);
                if (Number.isFinite(refreshedBalance)) {
                    balance = refreshedBalance;
                    updateCreditsDisplay(balance);
                    if (creditsCache?.setBalance) {
                        creditsCache.setBalance(balance);
                    }
                    return { ok: true, connected: !!nextAuth.connected, balance };
                }
            } else if (Object.keys(fallbackAuth).length) {
                applyAuthStatus(fallbackAuth);
            }

            if (nextAuth?.connected) {
                const refreshedBalance = await refreshCreditsFromApi();
                if (Number.isFinite(refreshedBalance)) {
                    balance = refreshedBalance;
                    return { ok: true, connected: true, balance };
                }
            }

            return { ok: ok && !!nextAuth?.connected, connected: !!nextAuth?.connected, balance };
        }).finally(() => {
            ctx.state.authPostLoginRefreshPromise = null;
        });

        ctx.state.authPostLoginRefreshPromise = promise;
        return promise;
    };

    const handleAuthSyncEvent = (notice) => {
        if (!notice || typeof notice !== 'object') {
            return;
        }
        const eventId = String(notice.id || '').trim();
        if (!eventId || eventId === lastHandledAuthSyncId) {
            return;
        }
        lastHandledAuthSyncId = eventId;
        syncAuthStatusFromServer(notice);
    };

    const parseAuthSyncStorageNotice = (rawValue) => {
        try {
            const notice = JSON.parse(String(rawValue || ''));
            return notice && typeof notice === 'object' && !Array.isArray(notice) ? notice : null;
        } catch (error) {
            return null;
        }
    };

    showAuthBootNotice();

    ctx.state.authSyncTransport = 'storage-focus';

    if (typeof BroadcastChannel !== 'undefined') {
        try {
            const authSyncChannel = new BroadcastChannel(AUTH_SYNC_CHANNEL);
            authSyncChannel.addEventListener('message', (event) => {
                handleAuthSyncEvent(event?.data);
            });
            ctx.state.authSyncTransport = 'broadcast-storage-focus';
        } catch (error) {
            ctx.state.authSyncTransport = 'storage-focus';
        }
    }

    window.addEventListener('storage', (event) => {
        if (event.key !== AUTH_SYNC_KEY || !event.newValue) {
            return;
        }
        const notice = parseAuthSyncStorageNotice(event.newValue);
        if (!notice) {
            return;
        }
        handleAuthSyncEvent(notice);
    });

    window.addEventListener('focus', () => {
        if (!ctx.state.authConnected) {
            syncAuthStatusFromServer();
            return;
        }
        if (Date.now() - lastFocusRefreshAt < 5000) {
            return;
        }
        lastFocusRefreshAt = Date.now();
        refreshCreditsFromApi().finally(() => {
            requestExperience({ force: true });
        });
    });

    const setDeepValue = (target, keys, value) => {
        let current = target;
        keys.forEach((key, index) => {
            if (index === keys.length - 1) {
                current[key] = value;
                return;
            }
            if (!current[key] || typeof current[key] !== 'object') {
                current[key] = {};
            }
            current = current[key];
        });
    };

    const extractKeys = (name) => {
        if (!optionName || !name.startsWith(`${optionName}[`)) {
            return [];
        }
        const matches = name.match(/\[([^\]]+)\]/g);
        if (!matches) {
            return [];
        }
        return matches.map((match) => match.slice(1, -1));
    };

    const applyAuthStatus = (authStatus) => {
        const nextStatus = authStatus && typeof authStatus === 'object' ? authStatus : {};
        const connected = !!nextStatus.connected;
		const logoutPending = connected && ctx.state.authLogoutPending === true;
        ctx.state.auth = nextStatus;
        ctx.state.authConnected = connected;
        if (connected) {
            ctx.state.authExpired = false;
        }
        if (settingsRoot) {
            settingsRoot.dataset.authConnected = connected ? '1' : '0';
        }
        if (authWrap) {
            authWrap.classList.toggle('is-connected', connected);
            authWrap.classList.toggle('is-disconnected', !connected);
        }
        if (authTitle) {
            authTitle.textContent = connected
                ? __('Connected', 'fotogenic-ai')
                : __('Not connected', 'fotogenic-ai');
        }
        if (authEmail) {
            const email = connected && typeof nextStatus.user?.email === 'string'
                ? nextStatus.user.email.trim()
                : '';
            authEmail.textContent = email;
            authEmail.hidden = !email;
        }
        if (authLogoutRow) {
            authLogoutRow.hidden = !connected;
        }
        if (authManageButton) {
            authManageButton.disabled = !connected;
            authManageButton.setAttribute('aria-disabled', connected ? 'false' : 'true');
            authManageButton.dataset.accountUrl = String(nextStatus.accountUrl || authManageButton.dataset.accountUrl || '');
        }
        syncConfigRefreshAvailability();
        if (authLogoutButton) {
			setLogoutPending(logoutPending);
            authLogoutButton.hidden = !connected;
            authLogoutButton.style.display = connected ? 'inline-flex' : 'none';
        }
        if (!connected && logoutConfirmOverlay?.isOpen()) {
            logoutConfirmOverlay.close({ restoreFocus: false });
        }
        if (authLoginButton) {
            if (ctx.state.authLoginPending && !connected) {
                if (!authLoginButton.classList.contains('is-loading')) {
                    setButtonLoading(authLoginButton, true);
                }
            } else {
                setButtonLoading(authLoginButton, false);
            }
            authLoginButton.hidden = false;
            authLoginButton.style.display = 'inline-flex';
            authLoginButton.dataset.authAction = connected ? 'topup' : 'login';
            if (!authLoginButton.classList.contains('is-loading')) {
                const icon = authLoginButton.querySelector('[data-fa-settings-auth-primary-icon]');
                const label = authLoginButton.querySelector('[data-auth-primary-label]');
                if (icon) {
                    icons.update(icon, connected ? 'credit-card' : 'sign-in', { weight: 'bold', size: 17 });
                }
                if (label) {
                    label.textContent = connected ? __('Top up', 'fotogenic-ai') : __('Connect', 'fotogenic-ai');
                }
            }
        }
        updateCreditsDisplay(nextStatus?.balance ?? null);
    };

    window.addEventListener('fotogenic-ai:auth-changed', (event) => {
        const auth = event.detail?.auth || event.detail || {};
        if (!auth || typeof auth !== 'object') return;
        applyAuthStatus(auth);
        if (!auth.connected) {
            updateCreditsDisplay(null);
            creditsCache?.clearBalance?.();
        }
        requestExperience({ force: true });
    });

    const buildSettingsPayload = () => {
        const payload = {};
        const fields = settingsForm.querySelectorAll('input[name], select[name], textarea[name]');
        fields.forEach((field) => {
            if (field.disabled) {
                return;
            }
            const keys = extractKeys(field.name);
            if (!keys.length) {
                return;
            }

            if (field.type === 'radio' && !field.checked) {
                return;
            }

            let value = field.value;
            if (field.type === 'checkbox') {
                value = field.checked ? '1' : '0';
            }
            if (field.tagName === 'SELECT' && field.multiple) {
                value = Array.from(field.selectedOptions).map((option) => option.value);
            }

            setDeepValue(payload, keys, value);
        });
        return payload;
    };

    const getSettingsSignature = () => (settingsForm ? JSON.stringify(buildSettingsPayload()) : '');

    const updateGuidanceCount = () => {
        if (!customInstructionsCount || !customInstructionsField) return;
        customInstructionsCount.textContent = sprintf(
            __('%1$s / %2$s', 'fotogenic-ai'),
            customInstructionsField.value.length.toLocaleString(),
            Number(5000).toLocaleString()
        );
    };

    const updateDirtyState = () => {
        settingsDirty = getSettingsSignature() !== lastSavedSettingsSignature;
    };

    const reportSettingsFailure = (result, retry) => {
        if (ctx.errors?.normalizeAndReport) {
            ctx.errors.normalizeAndReport(
                result,
                {
                    source: 'settings',
                    endpoint: '/settings/save',
                    method: 'POST',
                    status: result?.status,
                },
                {
                    onRetry: retry,
                    retryLabel: __('Try again', 'fotogenic-ai'),
                }
            );
        }
    };

    function saveSettings() {
        const settingsPayload = buildSettingsPayload();
        const nextSignature = JSON.stringify(settingsPayload);
        if (nextSignature === lastSavedSettingsSignature) {
            updateDirtyState();
            setStatus(__('Plugin settings saved.', 'fotogenic-ai'), 'success');
            return Promise.resolve(true);
        }
        if (activeController && nextSignature === activeSaveSignature) {
            return Promise.resolve(false);
        }
        if (activeController) {
            activeController.abort();
        }
        const controller = new AbortController();
        activeController = controller;
        activeSaveSignature = nextSignature;
        setButtonLoading(saveButton, true);
        return apiFetch('/settings/save', {
            method: 'POST',
            body: { settings: settingsPayload },
            signal: controller.signal,
        }).then((result) => {
            const { ok, data, aborted, handledAuthExpired } = result;
            if (aborted) return false;
            if (!ok) {
                if (handledAuthExpired) {
                    return false;
                }
                setStatus(data?.message || __('Save failed.', 'fotogenic-ai'), 'error');
                reportSettingsFailure(result, saveSettings);
                return false;
            }
            applyAuthStatus(data?.auth);
            setStatus(__('Plugin settings saved.', 'fotogenic-ai'), 'success');
            lastSavedSettingsSignature = nextSignature;
            if (ctx.state.authConnected && typeof refreshCreditsAfterSave === 'function') {
                refreshCreditsAfterSave();
            } else if (!ctx.state.authConnected) {
                updateCreditsDisplay(null);
                if (creditsCache?.clearBalance) {
                    creditsCache.clearBalance();
                }
            }
            return true;
        }).catch((error) => {
            setStatus(__('Save failed.', 'fotogenic-ai'), 'error');
            reportSettingsFailure(error, saveSettings);
            return false;
        }).finally(() => {
            if (activeController === controller) {
                activeController = null;
                activeSaveSignature = '';
            }
            setButtonLoading(saveButton, false);
            updateDirtyState();
        });
    }

    if (settingsForm) {
        settingsForm.addEventListener('submit', (event) => {
            event.preventDefault();
            saveSettings();
        });

        settingsForm.querySelectorAll('input[name], select[name], textarea[name]').forEach((field) => {
            field.addEventListener('input', () => {
                if (field === customInstructionsField) updateGuidanceCount();
                updateDirtyState();
            });
            field.addEventListener('change', updateDirtyState);
        });
        lastSavedSettingsSignature = getSettingsSignature();
        updateGuidanceCount();
        updateDirtyState();

        if (debugLoggingCheckbox && debugTrigger && debugWorkspace) {
            debugLoggingCheckbox.addEventListener('change', () => {
                const enabled = debugLoggingCheckbox.checked;
                debugTrigger.hidden = !enabled;
                if (!enabled) {
                    debugWorkspace.hidden = true;
                    debugTrigger.classList.remove('is-open');
                    debugTrigger.setAttribute('aria-expanded', 'false');
                    const label = debugTrigger.querySelector('[data-debug-trigger-label]');
                    if (label) label.textContent = __('Open log', 'fotogenic-ai');
                }
            });
        }
    }

    window.addEventListener('beforeunload', (event) => {
        if (!settingsDirty) return;
        event.preventDefault();
        event.returnValue = '';
    });

    const openAuthDestination = (rawUrl) => {
        try {
            const value = String(rawUrl || '').trim();
            if (!value) {
                throw new Error('Missing account URL.');
            }
            const destination = new URL(value, window.location.href);
            if (destination.protocol !== 'https:' && destination.protocol !== 'http:') {
                throw new Error('Unsupported account URL protocol.');
            }
            const opened = window.open(destination.href, '_blank', 'noopener,noreferrer');
            if (opened) opened.opener = null;
            return true;
        } catch (error) {
            setStatus(__('Could not open the Fotogenic account.', 'fotogenic-ai'), 'error');
            return false;
        }
    };

    if (authManageButton) {
        authManageButton.addEventListener('click', () => {
            if (!ctx.state.authConnected || authManageButton.disabled) return;
            openAuthDestination(authManageButton.dataset.accountUrl);
        });
    }

    if (authLoginButton) {
        authLoginButton.addEventListener('click', () => {
            if (ctx.state.authConnected || authLoginButton.dataset.authAction === 'topup') {
                openAuthDestination(authLoginButton.dataset.topupUrl);
                return;
            }
            beginAuthLoginPending();
            apiFetch('/auth/start', {
                method: 'POST',
                body: { source: 'settings' },
            }).then(({ ok, data, handledAuthExpired }) => {
                if (handledAuthExpired) {
                    finishAuthLoginPending();
                    return;
                }
                if (!ok || !data?.authorizationUrl) {
                    finishAuthLoginPending();
                    setStatus(data?.message || __('Failed to start Fotogenic login.', 'fotogenic-ai'), 'error');
                    return;
                }
                try {
                    const authorizationUrl = new URL(String(data.authorizationUrl), window.location.href);
                    if (authorizationUrl.protocol !== 'https:' && authorizationUrl.protocol !== 'http:') {
                        throw new Error('Unsupported authorization URL protocol.');
                    }
                    window.location.assign(authorizationUrl.href);
                } catch (error) {
                    finishAuthLoginPending();
                    setStatus(__('Failed to start Fotogenic login.', 'fotogenic-ai'), 'error');
                }
            }).catch(() => {
                finishAuthLoginPending();
                setStatus(__('Failed to start Fotogenic login.', 'fotogenic-ai'), 'error');
            });
        });
    }

    if (authLogoutButton) {
        const reportLogoutFailure = (result) => {
            if (!ctx.errors?.normalizeAndReport) return;
            ctx.errors.normalizeAndReport(
                result,
                {
                    source: 'settings',
                    endpoint: '/auth/logout',
                    method: 'POST',
                    status: result?.status,
                },
                {
                    onRetry: () => performLogout(),
                    retryLabel: __('Try again', 'fotogenic-ai'),
                }
            );
        };
		const settleLogoutConfirmation = ({ restoreFocus = true } = {}) => {
			setButtonLoading(logoutConfirmButton, false);
			logoutConfirmOverlay?.close({ restoreFocus });
		};
		const performLogout = () => {
			if (ctx.state.authLogoutPending === true) return;
			setLogoutPending(true);
			setButtonLoading(logoutConfirmButton, true);
            apiFetch('/auth/logout', { method: 'POST' }).then((result) => {
                const { ok, data, handledAuthExpired } = result;
                if (!ok) {
                    if (handledAuthExpired) {
							setLogoutPending(false);
							settleLogoutConfirmation({ restoreFocus: false });
                        return;
                    }
					setLogoutPending(false);
					settleLogoutConfirmation();
                    setStatus(data?.message || __('Failed to disconnect Fotogenic.', 'fotogenic-ai'), 'error');
                    reportLogoutFailure(result);
                    return;
                }
				setButtonLoading(logoutConfirmButton, false);
				logoutConfirmOverlay?.close({ restoreFocus: false });
                applyAuthStatus(data?.auth);
                updateCreditsDisplay(null);
                if (creditsCache?.clearBalance) {
                    creditsCache.clearBalance();
                }
                setStatus(__('Disconnected from Fotogenic AI.', 'fotogenic-ai'), 'success');
                window.dispatchEvent(new CustomEvent('fotogenic-ai:auth-changed', {
                    detail: { auth: data?.auth || { connected: false, balance: null } },
                }));
				window.requestAnimationFrame(() => authLoginButton?.focus({ preventScroll: true }));
            }).catch((error) => {
					setLogoutPending(false);
					settleLogoutConfirmation();
                setStatus(__('Failed to disconnect Fotogenic.', 'fotogenic-ai'), 'error');
                reportLogoutFailure(error);
            });
		};
		authLogoutButton.addEventListener('click', () => {
			if (ctx.state.authLogoutPending === true) return;
			if (!logoutConfirmOverlay) {
				setStatus(__('The disconnect confirmation is unavailable. Reload Settings and try again.', 'fotogenic-ai'), 'error');
				return;
			}
			logoutConfirmOverlay.open({ returnFocus: authLogoutButton, initialFocus: logoutCancelButton });
        });
		logoutCancelButton?.addEventListener('click', () => logoutConfirmOverlay?.close());
		logoutConfirmButton?.addEventListener('click', performLogout);
    }

    if (configRefreshButton) {
        configRefreshButton.addEventListener('click', () => {
            if (!ctx.state.authConnected || configRefreshButton.disabled) return;
            setButtonLoading(configRefreshButton, true);
			syncConfigRefreshAvailability();
			apiFetch('/settings/configuration/refresh', { method: 'POST' }).then(({ ok, data, handledAuthExpired }) => {
                if (!ok) {
                    if (handledAuthExpired) {
                        return;
                    }
                    setConfigRefreshStatus(data?.message || __('Failed to refresh options.', 'fotogenic-ai'), 'error');
                    return;
                }
                setConfigRefreshStatus(__('Options refreshed.', 'fotogenic-ai'), 'success');
                requestExperience({ force: true });
            }).catch(() => {
                setConfigRefreshStatus(__('Failed to refresh options.', 'fotogenic-ai'), 'error');
            }).finally(() => {
                setButtonLoading(configRefreshButton, false);
                syncConfigRefreshAvailability();
            });
        });
    }

    const logContainer = document.getElementById('fotogenic-ai-debug-log');
    const creditsCache = window.FotogenicAI?.Shared?.creditsCache;
    const creditsTotalEl = document.getElementById('fotogenic-ai-credits-total');
    const accountCreditsEl = document.getElementById('fotogenic-ai-settings-account-credits');
    const creditsRefreshButton = document.getElementById('fotogenic-ai-credits-refresh');
    const pluginCacheRefreshButton = document.getElementById('fotogenic-ai-plugin-cache-refresh')
        || document.getElementById('fotogenic-ai-credits-refresh');
    const experienceRest = settingsBoot?.rest && typeof settingsBoot.rest === 'object' ? settingsBoot.rest : {};

    const followExperienceAction = (action) => {
        const actionId = String(action?.action || '').trim();
        if (actionId === 'connect') {
            window.setTimeout(() => authLoginButton?.click(), 120);
            return;
        }
        const url = String(action?.url || '').trim();
        if (!url) return;
        if (action?.newTab) {
            const link = document.createElement('a');
            link.href = url;
            link.target = '_blank';
            link.rel = 'noopener noreferrer';
            link.hidden = true;
            document.body.appendChild(link);
            link.click();
            link.remove();
            return;
        }
        window.setTimeout(() => window.location.assign(url), 120);
    };

    const initializeExperienceController = () => {
        const createController = window.FotogenicAI?.Shared?.ui?.experienceDialog?.createExperienceController;
        const claimEndpoint = String(experienceRest.experienceClaim || '').trim();
        const dismissEndpoint = String(experienceRest.experienceDismiss || '').trim();
        if (typeof createController !== 'function' || !claimEndpoint || !dismissEndpoint) {
            return null;
        }
        return createController({
            imageUrls: settingsBoot?.experienceImages,
            restoreFocusTo: ctx.state.authConnected ? configRefreshButton : authLoginButton,
            claim: (payload) => apiFetch(claimEndpoint, { method: 'POST', body: payload }),
            dismiss: (payload) => apiFetch(dismissEndpoint, { method: 'POST', body: payload }),
            notify,
            onAction: followExperienceAction,
            onError: ({ operation }) => {
                notify?.warning?.(operation === 'dismiss'
                    ? __('The notice was closed, but its state could not be saved.', 'fotogenic-ai')
                    : __('Account notices could not be loaded.', 'fotogenic-ai'));
            },
        });
    };

    function requestExperience(options = {}) {
        return experienceController?.claimNext?.(options) || Promise.resolve(null);
    }

    experienceController = initializeExperienceController();

    const updateCreditsDisplay = (balance) => {
        const numeric = balance === null || typeof balance === 'undefined' || balance === ''
            ? Number.NaN
            : Number(balance);
        if (creditsTotalEl) {
            creditsTotalEl.textContent = Number.isFinite(numeric) ? String(Math.round(numeric)) : '—';
        }
        if (accountCreditsEl) {
            accountCreditsEl.textContent = ctx.state.authConnected
                ? (Number.isFinite(numeric)
                    ? sprintf(__('%s credits', 'fotogenic-ai'), Math.round(numeric).toLocaleString())
                    : __('Balance unknown', 'fotogenic-ai'))
                : __('Connect to continue', 'fotogenic-ai');
        }
        if (creditsRefreshButton) {
            creditsRefreshButton.hidden = !ctx.state.authConnected;
        }
    };

    const extractCreditsBalance = (payload) => {
        const balance = Number(payload?.balance ?? NaN);
        return Number.isFinite(balance) ? balance : null;
    };

    const refreshCreditsFromApi = () => {
        if (!creditsTotalEl && !accountCreditsEl) return Promise.resolve(null);
        if (!ctx.state.authConnected) {
            updateCreditsDisplay(null);
            if (creditsCache?.clearBalance) {
                creditsCache.clearBalance();
            }
            return Promise.resolve(null);
        }
        const refreshPromise = creditsCache?.ensure
            ? creditsCache.ensure(() => apiFetch('/credits/refresh', { method: 'POST' }), { force: true })
            : apiFetch('/credits/refresh', { method: 'POST' }).then(({ ok, data }) => (ok ? extractCreditsBalance(data) : null));
        return Promise.resolve(refreshPromise).then((balance) => {
            if (Number.isFinite(balance)) {
                updateCreditsDisplay(balance);
                return balance;
            }
            return null;
        });
    };

    if (creditsRefreshButton) {
        creditsRefreshButton.addEventListener('click', () => {
            setButtonLoading(creditsRefreshButton, true);
            refreshCreditsFromApi().then((balance) => {
                if (Number.isFinite(balance)) {
                    setStatus(__('Credits refreshed.', 'fotogenic-ai'), 'success');
                } else if (ctx.state.authConnected) {
                    setStatus(__('Could not refresh credits.', 'fotogenic-ai'), 'error');
                }
            }).finally(() => setButtonLoading(creditsRefreshButton, false));
        });
    }

    const fetchCreditsStatus = () => apiFetch('/credits/status').then(({ ok, data }) => {
        if (!ok || !data) {
            creditsCache?.reportFailure?.('status', data?.code || 'request_failed');
            return { cached: false, balance: null, errorCode: data?.code || 'request_failed' };
        }
        return {
            cached: data.cached === true,
            balance: extractCreditsBalance(data),
            fetchedAt: data.fetchedAt,
            ttlSeconds: data.ttlSeconds,
            provenance: data.provenance || 'unavailable',
        };
    }).catch(() => {
        creditsCache?.reportFailure?.('status', 'network_error');
        return { cached: false, balance: null, errorCode: 'network_error' };
    });

    function refreshCreditsAfterSave() {
        if (!creditsTotalEl || !ctx.state.authConnected) return;
        fetchCreditsStatus().then(({ cached, balance, ...meta }) => {
            if (cached && Number.isFinite(balance)) {
                updateCreditsDisplay(balance);
                if (creditsCache?.setBalance) {
                    creditsCache.setBalance(balance, meta);
                }
                return;
            }
            return refreshCreditsFromApi();
        });
    }

    const creditsText = creditsTotalEl ? String(creditsTotalEl.textContent || '').trim() : '';
    applyAuthStatus(ctx.state.auth);
    const hasApiKeyConfigured = ctx.state.authConnected
        || String(settingsRoot?.dataset?.authConnected || '') === '1';
    const initialBalance = creditsText && creditsText !== '—' ? Number(creditsText) : NaN;
    if (creditsCache?.setBalance && Number.isFinite(initialBalance)) {
        creditsCache.setBalance(initialBalance);
    }
    const cachedBalance = creditsCache?.getBalance?.();
    const hasCachedBalance = Number.isFinite(cachedBalance);
    if (creditsTotalEl && hasApiKeyConfigured && hasCachedBalance && (creditsText === '' || creditsText === '—')) {
        updateCreditsDisplay(cachedBalance);
    }
    // Refresh credits on load only when there is a cache miss.
    if (creditsTotalEl && hasApiKeyConfigured && !hasCachedBalance && (creditsText === '' || creditsText === '—')) {
        fetchCreditsStatus().then(({ cached, balance, ...meta }) => {
            if (cached && Number.isFinite(balance)) {
                updateCreditsDisplay(balance);
                if (creditsCache?.setBalance) {
                    creditsCache.setBalance(balance, meta);
                }
                return;
            }
            refreshCreditsFromApi();
        });
    }

    if (pluginCacheRefreshButton) {
        pluginCacheRefreshButton.addEventListener('click', () => {
            setButtonLoading(pluginCacheRefreshButton, true);
            apiFetch('/settings/cache/refresh', { method: 'POST' }).then(({ ok, data, handledAuthExpired }) => {
                setButtonLoading(pluginCacheRefreshButton, false);
                if (!ok) {
                    if (handledAuthExpired) {
                        return;
                    }
                    if (notify) notify.warning(data?.message || __('Failed to refresh plugin cache.', 'fotogenic-ai'));
                    return;
                }
                applyAuthStatus(data?.auth);
                const balance = Number(data?.credits?.balance);
                if (Number.isFinite(balance)) {
                    updateCreditsDisplay(balance);
                    if (creditsCache?.setBalance) {
                        creditsCache.setBalance(balance);
                    }
                } else if (!ctx.state.authConnected) {
                    updateCreditsDisplay(null);
                    if (creditsCache?.clearBalance) {
                        creditsCache.clearBalance();
                    }
                }
                if (notify) notify.success(__('Plugin cache refreshed.', 'fotogenic-ai'));
                requestExperience({ force: true });
            });
        });
    }

    window.addEventListener('fotogenic-ai:credits-updated', (event) => {
        if (event?.detail && Object.hasOwn(event.detail, 'balance')) {
            updateCreditsDisplay(event.detail.balance);
        }
        requestExperience();
    });
    requestExperience();

    if (!logContainer) {
        return;
    }

    const logDate = document.getElementById('fotogenic-ai-log-date');
    const logLevel = document.getElementById('fotogenic-ai-log-level');
    const logRefresh = document.getElementById('fotogenic-ai-log-refresh');
    const logDownload = document.getElementById('fotogenic-ai-log-download');
    const logClear = document.getElementById('fotogenic-ai-log-clear');
    const logTableBody = document.querySelector('#fotogenic-ai-log-table tbody');
    const logPrev = document.getElementById('fotogenic-ai-log-prev');
    const logNext = document.getElementById('fotogenic-ai-log-next');
    const logPage = document.getElementById('fotogenic-ai-log-page');
    const logPageSize = document.getElementById('fotogenic-ai-log-page-size');
    const logPagination = document.getElementById('fotogenic-ai-log-pagination');
    const debugLogState = document.getElementById('fotogenic-ai-debug-log-state');
    const debugLogTableWrap = document.getElementById('fotogenic-ai-debug-log-table-wrap');
    const logCount = document.getElementById('fotogenic-ai-log-count');
    const clearConfirmLayer = document.getElementById('fotogenic-ai-settings-clear-confirm');
    const clearConfirmPanel = clearConfirmLayer?.querySelector('.fotogenic-ai-settings-confirm');
    const clearConfirmButton = document.getElementById('fotogenic-ai-settings-clear-confirm-button');
    const clearCancelButton = document.getElementById('fotogenic-ai-settings-clear-cancel');

    let logPageNumber = 1;
    let perPage = 5;
    let filteredLogTotal = 0;
    let storedLogTotal = 0;
    let debugLoaded = false;
    let debugRequestController = null;
    let clearConfirmOverlay = null;

    const setLogStatus = (message, state) => {
        if (!notify || !message) return undefined;
        if (state === 'loading') return notify.info(message, transientToastOpts);
        if (state === 'success') notify.success(message);
        else if (state === 'error') notify.warning(message);
        return undefined;
    };

    const hasActiveLogFilters = () => (
        (logDate && logDate.value !== 'all')
        || (logLevel && logLevel.value !== 'all')
    );

    const renderDebugState = (state, message = '') => {
        if (!debugLogState) return;
        debugLogState.innerHTML = '';
        debugLogState.hidden = false;
        debugLogState.classList.toggle('is-error', state === 'error');
        debugLogState.setAttribute('role', state === 'error' ? 'alert' : 'status');
        if (debugLogTableWrap) debugLogTableWrap.hidden = true;

        const icon = state === 'loading'
            ? icons.create('arrows-clockwise', { weight: 'regular', size: 20 })
            : icons.create(state === 'error' ? 'warning' : 'gear-six', { weight: state === 'error' ? 'fill' : 'regular', size: 20 });
		icon.classList.toggle('fotogenic-ai-icon--spin', state === 'loading');
        debugLogState.appendChild(icon);

        const status = document.createElement('strong');
        status.textContent = message || (
            state === 'loading'
                ? __('Refreshing debug log…', 'fotogenic-ai')
                : (state === 'error'
                    ? __('Debug log could not be loaded.', 'fotogenic-ai')
                    : (hasActiveLogFilters()
                        ? __('No entries match these filters.', 'fotogenic-ai')
                        : __('The debug log is empty.', 'fotogenic-ai')))
        );
        debugLogState.appendChild(status);

        if (state === 'error') {
            const retry = document.createElement('button');
            retry.type = 'button';
            retry.dataset.debugLogRetry = '1';
            retry.textContent = __('Try again', 'fotogenic-ai');
            debugLogState.appendChild(retry);
        }
    };

    const updateLogControls = (total, availableTotal = total) => {
        const totalPages = Math.max(1, Math.ceil(total / perPage));
        filteredLogTotal = Math.max(0, Number(total) || 0);
        storedLogTotal = Math.max(0, Number(availableTotal) || 0);
        if (logPage) logPage.textContent = `${logPageNumber} / ${totalPages}`;
        if (logPrev) logPrev.disabled = logPageNumber <= 1;
        if (logNext) logNext.disabled = logPageNumber >= totalPages;
        if (logPagination) logPagination.hidden = false;
        if (logCount) {
            logCount.textContent = sprintf(
                total === 1 ? __('%s entry', 'fotogenic-ai') : __('%s entries', 'fotogenic-ai'),
                total.toLocaleString()
            );
        }
        if (logDownload) logDownload.disabled = storedLogTotal <= 0;
        if (logClear) logClear.disabled = storedLogTotal <= 0;
    };

    const normalizeLogLevel = (level) => {
        const normalized = String(level || '').toLowerCase();
        if (normalized === 'api' || normalized === 'info') return 'INFO';
        if (normalized === 'warn' || normalized === 'warning') return 'WARNING';
        if (normalized === 'error') return 'ERROR';
        return '';
    };

    const renderLogs = (entries, total, availableTotal = total) => {
        if (!logTableBody) return;
        logTableBody.innerHTML = '';
        entries.forEach((entry) => {
            const row = document.createElement('tr');
            const timeCell = document.createElement('td');
            timeCell.dataset.label = __('Date', 'fotogenic-ai');
            timeCell.textContent = entry.formatted_timestamp || entry.timestamp || '';
            row.appendChild(timeCell);

            const levelCell = document.createElement('td');
            levelCell.dataset.label = __('Level', 'fotogenic-ai');
            const level = normalizeLogLevel(entry.level);
            const levelBadge = document.createElement('span');
            levelBadge.className = `fotogenic-ai-debug-level is-${level.toLowerCase()}`;
            levelBadge.textContent = level;
            levelCell.appendChild(levelBadge);
            row.appendChild(levelCell);

            const contextCell = document.createElement('td');
            contextCell.dataset.label = __('Context', 'fotogenic-ai');
            contextCell.textContent = entry.context ? JSON.stringify(entry.context) : '';
            row.appendChild(contextCell);

            const eventCell = document.createElement('td');
            eventCell.dataset.label = __('Event', 'fotogenic-ai');
            eventCell.textContent = entry.event || '';
            row.appendChild(eventCell);

            logTableBody.appendChild(row);
        });

        updateLogControls(total, availableTotal);
        if (!entries.length) {
            renderDebugState('empty');
            return;
        }
        if (debugLogState) debugLogState.hidden = true;
        if (debugLogTableWrap) debugLogTableWrap.hidden = false;
    };

    const fetchLogs = ({ announceSuccess = false } = {}) => {
        if (!restUrl || !restNonce) {
            setLogStatus(__('REST context is missing.', 'fotogenic-ai'), 'error');
            renderDebugState('error');
            return Promise.resolve(false);
        }
        const dateValue = logDate ? logDate.value : 'all';
        const levelValue = logLevel ? logLevel.value : 'all';
        const selectedPageSize = Number(logPageSize?.value || perPage);
        perPage = [5, 10].includes(selectedPageSize) ? selectedPageSize : 5;
        const params = new URLSearchParams();
        if (dateValue && dateValue !== 'all') {
            params.set('date_range', dateValue);
        }
        if (levelValue && levelValue !== 'all') {
            params.set('level', levelValue);
        }
        params.set('page', String(logPageNumber));
        params.set('per_page', String(perPage));

        if (debugRequestController) debugRequestController.abort();
        const controller = new AbortController();
        debugRequestController = controller;
        renderDebugState('loading');

        return apiFetch(`/logs/list?${params.toString()}`, { signal: controller.signal }).then(({ ok, data, aborted }) => {
            if (debugRequestController !== controller || aborted) return false;
            if (!ok) {
                setLogStatus(data?.message || __('Failed to load logs.', 'fotogenic-ai'), 'error');
                renderDebugState('error');
                return false;
            }
            const total = Math.max(0, Number(data?.total || 0));
            const totalPages = Math.max(1, Math.ceil(total / perPage));
            if (logPageNumber > totalPages) {
                logPageNumber = totalPages;
                return fetchLogs({ announceSuccess });
            }
            renderLogs(
                Array.isArray(data?.entries) ? data.entries : [],
                total,
                Math.max(0, Number(data?.available_total ?? total))
            );
            if (announceSuccess) setLogStatus(__('Debug log refreshed.', 'fotogenic-ai'), 'success');
            return true;
        }).catch((error) => {
            if (debugRequestController !== controller || error?.name === 'AbortError') return false;
            setLogStatus(error?.message || __('Failed to load logs.', 'fotogenic-ai'), 'error');
            renderDebugState('error');
            return false;
        }).finally(() => {
            if (debugRequestController === controller) debugRequestController = null;
        });
    };

    const downloadLogs = () => {
        if (!restUrl || !restNonce) {
            setLogStatus(__('REST context is missing.', 'fotogenic-ai'), 'error');
            return Promise.resolve();
        }
        const loadingId = setLogStatus(__('Preparing download…', 'fotogenic-ai'), 'loading');
        return fetch(`${restUrl}/logs/download`, {
            method: 'GET',
            credentials: 'same-origin',
            headers: {
                'X-WP-Nonce': restNonce,
            },
        })
            .then((response) => response.blob().then((blob) => ({ ok: response.ok, blob, name: response.headers.get('Content-Disposition') })))
            .then(({ ok, blob, name }) => {
                if (notify && loadingId) notify.dismiss(loadingId);
                if (!ok) {
                    setLogStatus(__('Failed to download logs.', 'fotogenic-ai'), 'error');
                    return;
                }
                const url = window.URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = url;
                let filename = 'fotogenic-ai-logs.log';
                if (name && /filename="([^"]+)"/.test(name)) {
                    filename = RegExp.$1;
                }
                link.download = filename;
                document.body.appendChild(link);
                link.click();
                link.remove();
                window.URL.revokeObjectURL(url);
                setLogStatus(__('Logs downloaded.', 'fotogenic-ai'), 'success');
            })
            .catch(() => {
                if (notify && loadingId) notify.dismiss(loadingId);
                setLogStatus(__('Failed to download logs.', 'fotogenic-ai'), 'error');
            });
    };

    const clearLogs = () => {
        const loadingId = setLogStatus(__('Clearing…', 'fotogenic-ai'), 'loading');
        return apiFetch('/logs/clear', { method: 'POST' }).then(({ ok, data }) => {
            if (notify && loadingId) notify.dismiss(loadingId);
            if (!ok) {
                setLogStatus(data?.message || __('Failed to clear logs.', 'fotogenic-ai'), 'error');
                return false;
            }
            setLogStatus(__('Logs cleared.', 'fotogenic-ai'), 'success');
            logPageNumber = 1;
            renderLogs([], 0, 0);
            return true;
        });
    };

    if (clearConfirmLayer && clearConfirmPanel && typeof containedOverlayFactory === 'function') {
        clearConfirmOverlay = containedOverlayFactory({
            layer: clearConfirmLayer,
            panel: clearConfirmPanel,
            decorate: false,
            closeOnBackdrop: true,
            initialFocus: clearCancelButton,
            onClose: (overlay) => overlay.close(),
        });
    }

    if (logPrev) {
        logPrev.addEventListener('click', () => {
            logPageNumber = Math.max(1, logPageNumber - 1);
            setButtonLoading(logPrev, true);
            fetchLogs().finally(() => {
                setButtonLoading(logPrev, false);
                updateLogControls(filteredLogTotal, storedLogTotal);
            });
        });
    }

    if (logNext) {
        logNext.addEventListener('click', () => {
            logPageNumber += 1;
            setButtonLoading(logNext, true);
            fetchLogs().finally(() => {
                setButtonLoading(logNext, false);
                updateLogControls(filteredLogTotal, storedLogTotal);
                if (debugLogTableWrap) debugLogTableWrap.scrollTop = 0;
            });
        });
    }

    if (logRefresh) {
        logRefresh.addEventListener('click', () => {
            setButtonLoading(logRefresh, true);
            fetchLogs({ announceSuccess: true }).finally(() => setButtonLoading(logRefresh, false));
        });
    }
    if (logDownload) {
        logDownload.addEventListener('click', () => {
            setButtonLoading(logDownload, true);
            downloadLogs().finally(() => setButtonLoading(logDownload, false));
        });
    }
    if (logClear) {
        logClear.addEventListener('click', () => {
            clearConfirmOverlay?.open({ returnFocus: logClear });
        });
    }
    if (clearCancelButton) {
        clearCancelButton.addEventListener('click', () => clearConfirmOverlay?.close());
    }
    if (clearConfirmButton) {
        clearConfirmButton.addEventListener('click', () => {
            setButtonLoading(clearConfirmButton, true);
            clearLogs().then((cleared) => {
                if (!cleared) return;
                clearConfirmOverlay?.close({ restoreFocus: false });
                debugWorkspace?.focus({ preventScroll: true });
            }).finally(() => setButtonLoading(clearConfirmButton, false));
        });
    }

    if (logDate) {
        logDate.addEventListener('change', () => {
            logPageNumber = 1;
            fetchLogs();
        });
    }

    if (logLevel) {
        logLevel.addEventListener('change', () => {
            logPageNumber = 1;
            fetchLogs();
        });
    }

    if (logPageSize) {
        logPageSize.addEventListener('change', () => {
            const selectedPageSize = Number(logPageSize.value);
            perPage = [5, 10].includes(selectedPageSize) ? selectedPageSize : 5;
            logPageNumber = 1;
            fetchLogs();
        });
    }

    if (debugLogState) {
        debugLogState.addEventListener('click', (event) => {
            const retry = event.target.closest('[data-debug-log-retry]');
            if (!retry) return;
            fetchLogs();
        });
    }

    loadDebugWorkspace = () => {
        if (debugLoaded) return Promise.resolve();
        debugLoaded = true;
        return fetchLogs().catch((error) => {
            setLogStatus(error?.message || __('Failed to load logs.', 'fotogenic-ai'), 'error');
            renderDebugState('error');
        });
    };

    if (debugTrigger && debugWorkspace) {
        debugTrigger.addEventListener('click', () => {
            const open = debugWorkspace.hidden;
            debugWorkspace.hidden = !open;
            debugTrigger.classList.toggle('is-open', open);
            debugTrigger.setAttribute('aria-expanded', open ? 'true' : 'false');
            const label = debugTrigger.querySelector('[data-debug-trigger-label]');
            if (label) label.textContent = open ? __('Hide log', 'fotogenic-ai') : __('Open log', 'fotogenic-ai');
            if (open) {
                loadDebugWorkspace().finally(() => debugWorkspace.focus({ preventScroll: true }));
            }
        });
    }

    if (debugWorkspace && !debugWorkspace.hidden && debugLoggingCheckbox?.checked) {
        loadDebugWorkspace();
    }
});
