// ── Save & Auto‑save ─────────────────────────────────────────────────
// Correctness model:
//   • Every edit reads the DOM, syncs ALL in-memory caches immediately
//     (so switching tables / reloading never reads stale data), and
//     schedules a short per-table debounced network save.
//   • Table switch / unload flushes pending saves.
//   • The central navbar Save sends the FULL byTable map so it can never
//     wipe other tables (ModuleState::save overwrites the whole file).

let autoSaveTimers = {};   // per-table debounce timers

// Read the current table's config straight from the DOM.
function readDomConfig() {
    const pageTypes = [];
    document.querySelectorAll('.page-type-check:checked').forEach(cb => pageTypes.push(cb.value));
    const functionality = {};
    document.querySelectorAll('.func-check').forEach(cb => { functionality[cb.dataset.key] = cb.checked; });
    // Normalise settings to a plain OBJECT — an empty PHP array (`[]`) arrives as a
    // JS array, and JSON.stringify drops named props set on an array, silently
    // losing per-page settings on save.
    let settings = (currentConfig && currentConfig.settings) || {};
    if (Array.isArray(settings)) settings = {};
    return {
        pageTypes,
        functionality,
        settings,
        keyColumns: (currentKeyColumns || []).slice()
    };
}

// Keep every in-memory cache pointing at the same fresh state object.
function syncCaches(table, state) {
    if (!table) return;
    currentConfig = state;
    allPagesStates[table] = state;
    if (typeof pagesConfig === 'object' && pagesConfig) pagesConfig[table] = state;
}

// Persist a single table (merge-safe endpoint — preserves other tables).
// `keepalive` lets the request finish even if the user navigates to another
// (full-page-load) SPA module right after — so a save is never lost to a fast
// navigation.
function persistState(table, state) {
    if (!table) return Promise.resolve();
    return fetch(`${baseUrl}/project/${projectSlug}/pages/save-state`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ tableName: table, state }),
        keepalive: true
    }).catch(err => console.warn('Pages auto-save failed', err));
}

// Called on every click/change. Captures + caches instantly, debounces the network call per table.
function autoSaveCurrentPageState() {
    if (isPageUnloading || !currentTableName) return;
    const table = currentTableName;
    const state = readDomConfig();
    syncCaches(table, state);                 // instant: caches are never stale
    if (autoSaveTimers[table]) clearTimeout(autoSaveTimers[table]);
    autoSaveTimers[table] = setTimeout(() => {
        delete autoSaveTimers[table];
        persistState(table, state);
    }, 300);
}

// Flush all pending debounced saves right now (before table switch / unload).
function flushPendingSaves() {
    Object.keys(autoSaveTimers).forEach(table => {
        clearTimeout(autoSaveTimers[table]);
        delete autoSaveTimers[table];
        if (allPagesStates[table]) persistState(table, allPagesStates[table]);
    });
}

// Immediate (non-debounced) save of the current table.
function saveCurrentConfig() {
    if (!currentTableName) return;
    const table = currentTableName;
    const state = readDomConfig();
    syncCaches(table, state);
    persistState(table, state);
}

// Central navbar Save → send the FULL byTable map (never wipe other tables).
document.addEventListener('projectSave', (e) => {
    if (e.detail.module !== 'pages') return;
    if (currentTableName) syncCaches(currentTableName, readDomConfig());
    const base = (typeof pagesConfig === 'object' && pagesConfig) ? pagesConfig : {};
    const byTable = Object.assign({}, base, allPagesStates || {});
    e.detail.payload = { byTable, activeTable: currentTableName || null };
});

// Reliable save when the page is being hidden / unloaded.
function beaconSave() {
    isPageUnloading = true;
    if (!currentTableName) return;
    const state = readDomConfig();
    syncCaches(currentTableName, state);
    try {
        const blob = new Blob([JSON.stringify({ tableName: currentTableName, state })], { type: 'application/json' });
        navigator.sendBeacon(`${baseUrl}/project/${projectSlug}/pages/save-state`, blob);
    } catch (err) { /* best-effort */ }
}
window.addEventListener('pagehide', beaconSave);
window.addEventListener('beforeunload', () => { isPageUnloading = true; });

window.autoSaveCurrentPageState = autoSaveCurrentPageState;
window.saveCurrentConfig = saveCurrentConfig;
window.flushPendingSaves = flushPendingSaves;
window.readDomConfig = readDomConfig;
window.syncCaches = syncCaches;
