// Telemetry opt-in (KL-76, Alpine carve-out KL-131). First-run modal
// asking for consent to send anonymous usage / crash data, plus the
// Settings → Anonymous Usage row toggle.
//
// Two modes:
//   - 'optional' (default): user can say no; toggle freely later.
//   - 'required' (early access — window.CONDUCTOR_EARLY_ACCESS):
//     toggle is locked-checked, the modal copy explains the gate,
//     and "No thanks" quits the app instead of writing
//     telemetry_opt_in=false.
//
// Mode-conditional copy lives in HTML via data-mode-optional /
// data-mode-required attributes — each element binds x-text against
// $el.dataset.modeRequired or .modeOptional based on store mode. Keeps
// the copywriter-editable layout in HTML rather than copying strings
// into the store.

const earlyAccess = !!window.CONDUCTOR_EARLY_ACCESS;

function storeDefinition() {
    return {
        // --- Server snapshot ---
        enabled: false,
        hasMadeChoice: false,

        // --- Modal state ---
        modalShown: false,
        mode: 'optional',  // 'optional' | 'required'
        get requiredMode() { return this.mode === 'required'; },

        // --- Settings-row state ---
        get statusText() { return this.enabled ? 'On — thanks!' : 'Off'; },
        get statusClass() {
            return this.enabled ? 'setting-status set-env' : 'setting-status unset';
        },
        get locked() { return earlyAccess; },

        async refresh() {
            try {
                const resp = await fetch('/api/settings/telemetry');
                const data = await resp.json();
                this.enabled = !!data.enabled;
                this.hasMadeChoice = !!data.has_made_choice;

                // Show the modal in either case:
                //   1) Optional mode + first-run (existing behavior).
                //   2) Early-access mode + telemetry currently off
                //      (covers first-run AND any user who previously
                //      opted out before early access landed).
                const needsConsent = !this.hasMadeChoice;
                const earlyAccessGate = earlyAccess && !this.enabled;
                if (needsConsent || earlyAccessGate) {
                    this.mode = earlyAccessGate ? 'required' : 'optional';
                    this.modalShown = true;
                }
            } catch (_) { /* non-critical */ }
        },

        async setEnabled(enabled) {
            try {
                const resp = await fetch('/api/settings/telemetry', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({enabled}),
                });
                const data = await resp.json();
                this.enabled = !!data.enabled;
            } catch (_) { /* non-critical */ }
        },

        // Honor the early-access lock at the value level too — even if
        // someone bypasses the disabled attribute via DevTools, refuse
        // to write the "off" state.
        async toggleFromSettings(checked) {
            if (earlyAccess && !checked) {
                this.enabled = true;  // snap back
                return;
            }
            await this.setEnabled(checked);
        },

        async optInYes() {
            await this.setEnabled(true);
            this.modalShown = false;
        },

        async optInNo(btnEl) {
            if (earlyAccess) {
                // Required mode: "No thanks" exits the app cleanly.
                // Visual feedback while the shutdown signal travels —
                // the window will close shortly.
                if (btnEl) {
                    btnEl.disabled = true;
                    btnEl.textContent = 'Closing…';
                }
                try {
                    await fetch('/api/app/quit', {method: 'POST'});
                } catch (_) { /* the window is going away regardless */ }
                return;
            }
            await this.setEnabled(false);
            this.modalShown = false;
        },
    };
}

function ensureStore() {
    if (!window.Alpine) return null;
    if (!window.Alpine.store('telemetry')) {
        window.Alpine.store('telemetry', storeDefinition());
    }
    return window.Alpine.store('telemetry');
}

if (window.Alpine) {
    ensureStore();
} else {
    document.addEventListener('alpine:init', ensureStore);
}

export function initTelemetry() {
    let store = ensureStore();
    if (!store) {
        document.addEventListener('alpine:init', () => {
            ensureStore()?.refresh();
        }, {once: true});
    } else {
        store.refresh();
    }

    // Defensive: if a parent handler / library adds Escape→close for
    // modals, swallow it in required mode so the user has to make a
    // button choice. Capture phase to win over deeper listeners.
    document.addEventListener('keydown', (event) => {
        if (event.key !== 'Escape') return;
        const s = window.Alpine?.store('telemetry');
        if (!s || !s.modalShown || !s.requiredMode) return;
        event.stopPropagation();
        event.preventDefault();
    }, true);
}
