// First-run permission primer (KL-52, Alpine conversion KL-121).
//
// On macOS first launch, the backend blocks subsystem init on a
// threading.Event so the OS prompts for microphone + local network
// land *after* the user reads this modal. POST /api/permissions/continue
// flips the gate. Other platforms and repeat launches report
// first_run=false from the state endpoint and this module is a no-op.

import {registerNotificationAction} from '../js/notifications.js';

const DEFAULT_BTN_LABEL = "I'm ready — show the prompts";
const STARTING_LABEL = 'Starting…';

function storeDefinition() {
    return {
        shown: false,
        busy: false,
        error: '',
        btnLabel: DEFAULT_BTN_LABEL,
        async continue() {
            if (this.busy) return;
            this.busy = true;
            this.btnLabel = STARTING_LABEL;
            this.error = '';
            try {
                const r = await fetch('/api/permissions/continue', {method: 'POST'});
                const data = await r.json().catch(() => ({}));
                if (!r.ok || data.ok === false) {
                    throw new Error(data.error || `HTTP ${r.status}`);
                }
                this.shown = false;
            } catch (e) {
                this.busy = false;
                this.btnLabel = DEFAULT_BTN_LABEL;
                this.error = `Couldn't continue: ${e.message || e}`;
            }
        },
    };
}

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

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

// Recovery banners (KL-52). When _init_subsystems detects a macOS
// permission failure it pushes a notification with one of these
// action ids. The backend resolves the right Privacy & Security
// pane URL — we don't try to navigate the browser there ourselves
// because x-apple.systempreferences: isn't an http(s) scheme.
async function openMacSettings(pane) {
    try {
        await fetch('/api/permissions/open-settings', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify({pane}),
        });
    } catch (e) { /* user can still open it manually */ }
}
registerNotificationAction('open_microphone_settings',
    () => openMacSettings('microphone'));
registerNotificationAction('open_local_network_settings',
    () => openMacSettings('local_network'));

export async function initWelcome() {
    let state;
    try {
        const r = await fetch('/api/permissions/state');
        state = await r.json();
    } catch (e) {
        // State endpoint unreachable means the gate is broken on the
        // server side too — bailing here avoids a permanent blank
        // dashboard. The user will see a connection-lost toast from
        // the socket layer instead.
        return;
    }

    if (!state || !state.first_run) return;

    let store = ensureStore();
    if (!store) {
        // Alpine hasn't fired alpine:init yet — wait, then retry.
        await new Promise(resolve => {
            document.addEventListener('alpine:init', resolve, {once: true});
        });
        store = ensureStore();
    }
    if (store) store.shown = true;
}
