/* ============================================================
   PPphp Designer — API layer
   Wraps the existing backend endpoints:
     GET  /project/{slug}/designer/load
     POST /project/{slug}/designer/save     { designer }
     POST /project/{slug}/designer/template { table, pageType }
     POST /project/{slug}/designer/layout   { layout }
   ============================================================ */
(function () {
    'use strict';
    var PPD = window.PPD = window.PPD || {};
    var boot = window.PpDesignerBootstrap || {};
    var base = (boot.baseUrl || '/').replace(/\/+$/, '');
    var slug = boot.projectSlug || '';

    function url(path) { return base + '/project/' + encodeURIComponent(slug) + '/designer' + path; }
    function miscUrl(path) { return base + '/project/' + encodeURIComponent(slug) + '/misc' + path; }
    function pagesUrl(path) { return base + '/project/' + encodeURIComponent(slug) + path; }
    function postTo(fullUrl, body) {
        return fetch(fullUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
            credentials: 'same-origin',
            body: JSON.stringify(body || {})
        }).then(function (r) { return r.json(); });
    }

    function getJson(path) {
        return fetch(url(path), { headers: { 'Accept': 'application/json' }, credentials: 'same-origin' })
            .then(function (r) { return r.json(); });
    }
    function postJson(path, body) {
        return fetch(url(path), {
            method: 'POST',
            headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
            credentials: 'same-origin',
            body: JSON.stringify(body || {})
        }).then(function (r) { return r.json(); });
    }

    PPD.api = {
        load: function () { return getJson('/load'); },
        save: function (designer) { return postJson('/save', { designer: designer }); },
        // Partial save: only the page slots that actually changed. `baseToken`
        // is the token the server returned for the state this delta was built
        // on — if the stored state moved on (another tab, another user), the
        // server answers { needFull: true } and the caller re-sends everything.
        saveDelta: function (ops, baseToken) { return postJson('/save', { ops: ops, baseToken: baseToken }); },
        template: function (table, pageType, variant) { return postJson('/template', { table: table, pageType: pageType, variant: variant || '' }); },
        // Create a new BLANK custom page (custom_<slug>) under a table, or a
        // table-less "standalone" page when `standalone` is true.
        addPage: function (table, label, standalone) { return postJson('/add-page', { table: table, label: label, standalone: !!standalone }); },
        renamePage: function (table, pageType, label) { return postJson('/rename-page', { table: table, pageType: pageType, label: label }); },
        deletePage: function (table, pageType) { return postJson('/delete-page', { table: table, pageType: pageType }); },
        // Restore ONE page (e.g. the dashboard) from the project's factory snapshot.
        restoreFactoryPage: function (table, pageType) { return postJson('/restore-factory-page', { table: table, pageType: pageType }); },
        layout: function (layout) { return postJson('/layout', { layout: layout }); },
        icons: function (query, pack, limit) {
            var q = '/icons?q=' + encodeURIComponent(query || '') + (pack ? '&pack=' + encodeURIComponent(pack) : '') + (limit ? '&limit=' + encodeURIComponent(limit) : '');
            return getJson(q);
        },
        fieldPreview: function (body) { return postJson('/field-preview', body || {}); },
        lookupOptions: function (body) { return postJson('/lookup-options', body || {}); },
        widgetData: function (body) { return postJson('/widget-data', body || {}); },
        // Assign a field's Edit/View controls once, at the field level — the build
        // applies them on every page. { table, field, edit:{type,settings}, view:{…} }
        saveFieldControl: function (body) { return postJson('/field-control', body || {}); },
        // Misc module — Label Editor + Table Settings are the single source of truth;
        // the Designer writes through these so both modules stay in sync.
        miscLabelSave: function (lang, section, key, value) {
            return postTo(miscUrl('/labels/save'), { langCode: lang, section: section, key: key, value: value });
        },
        miscTableSave: function (table, data) {
            return postTo(miscUrl('/save'), { section: 'table', tableName: table, data: data });
        },
        // Persist a table's Pages config (pages.json byTable[t]) — the same
        // merge-safe endpoint the Pages module uses. Lets the Designer edit
        // list behaviour (freeze/views/group/kanban) in one shared source.
        pagesSaveState: function (table, state) {
            return postTo(pagesUrl('/pages/save-state'), { tableName: table, state: state });
        }
    };
})();
