// gf-ui.js — Refined UI theme controls.
// Drives the document-element data attributes the design CSS keys off
// (data-theme / data-density / --accent-h) and persists them to localStorage.
// The pre-paint init in App.razor reads the same keys so there is no flash.
window.gfUi = {
    setTheme: function (t) {
        document.documentElement.dataset.theme = t;
        try { localStorage.setItem('gf-theme', t); } catch (e) { /* unavailable */ }
    },
    setDensity: function (d) {
        document.documentElement.dataset.density = d;
        try { localStorage.setItem('gf-density', d); } catch (e) { /* unavailable */ }
    },
    setAccentHue: function (h) {
        document.documentElement.style.setProperty('--accent-h', h);
        try { localStorage.setItem('gf-accent-h', h); } catch (e) { /* unavailable */ }
    },
    get: function (k) {
        try { return localStorage.getItem(k); } catch (e) { return null; }
    },
    // A HALF-TICKED CHECKBOX IS A PROPERTY, NOT AN ATTRIBUTE. `indeterminate` reflects from no
    // content attribute, so rendering it as markup emits a setAttribute the browser ignores and the
    // box draws plain empty. Only an assignment like this one shows the third state.
    setIndeterminate: function (el, on) {
        if (el) el.indeterminate = !!on;
    },
    scrollToId: function (id) {
        var el = document.getElementById(id);
        if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
    }
};

// gfUpload — browser-side direct-to-storage upload helper for the Schema S7 asset flow.
// The .NET side first requests a pre-signed URL (product:asset_upload_url), then calls
// putFile(...) to PUT the chosen file straight to that URL (no server round-trip of bytes),
// then links it via product:image_add / product:codelist_value_image_set.
window.gfUpload = {
    // Returns { name, type, size } for the file currently selected in the <input id=…>,
    // or null when nothing is selected. Used to derive the contentType for the upload ticket.
    fileInfo: function (inputId) {
        var el = document.getElementById(inputId);
        if (!el || !el.files || el.files.length === 0) return null;
        var f = el.files[0];
        return { name: f.name, type: f.type || 'application/octet-stream', size: f.size };
    },
    // PUTs the selected file to the pre-signed url. Returns { ok, status, error } and never throws.
    putFile: async function (inputId, url, contentType) {
        var el = document.getElementById(inputId);
        if (!el || !el.files || el.files.length === 0) {
            return { ok: false, status: 0, error: 'no-file-selected' };
        }
        var f = el.files[0];
        try {
            var resp = await fetch(url, {
                method: 'PUT',
                body: f,
                headers: { 'Content-Type': contentType || f.type || 'application/octet-stream' }
            });
            return { ok: resp.ok, status: resp.status, error: resp.ok ? null : ('http-' + resp.status) };
        } catch (e) {
            return { ok: false, status: 0, error: (e && e.message) ? e.message : 'fetch-failed' };
        }
    },
    // Clears the file input after a completed (or abandoned) upload.
    clear: function (inputId) {
        var el = document.getElementById(inputId);
        if (el) el.value = '';
    }
};
