// store_versions MUST be first import — its side-effect wipes stale localStorage
// before svelte-persisted-store hydrates from it.
import { AE_LOC_VERSION } from '$lib/stores/store_versions';

import { auth_loc_defaults } from '$lib/stores/ae_stores__auth_loc_defaults';

import { persisted } from 'svelte-persisted-store';

import { readable, writable } from 'svelte/store';
import type { Readable, Writable } from 'svelte/store';

import {
    PUBLIC_AE_API_PROTOCOL,
    PUBLIC_AE_API_SERVER,
    PUBLIC_AE_API_BAK_SERVER,
    PUBLIC_AE_API_PORT,
    PUBLIC_AE_API_PATH,
    PUBLIC_AE_API_SECRET_KEY,
    PUBLIC_AE_API_CRUD_SUPER_KEY,
    PUBLIC_AE_NO_ACCOUNT_ID,
    // PUBLIC_AE_NO_ACCOUNT_ID_TOKEN,
    // PUBLIC_AE_ACCOUNT_ID,
    // PUBLIC_AE_EVENT_ID,
    // PUBLIC_AE_SPONSORSHIP_CFG_ID
} from '$env/static/public';

const api_server_fqdn = PUBLIC_AE_API_SERVER; // 'api.oneskyit.com'
const api_base_url = `${PUBLIC_AE_API_PROTOCOL}://${PUBLIC_AE_API_SERVER}:${PUBLIC_AE_API_PORT}${PUBLIC_AE_API_PATH}`;
const api_base_url_bak = `${PUBLIC_AE_API_PROTOCOL}://${PUBLIC_AE_API_BAK_SERVER}:${PUBLIC_AE_API_PORT}${PUBLIC_AE_API_PATH}`;

const api_secret_key = PUBLIC_AE_API_SECRET_KEY;
const api_crud_super_key = PUBLIC_AE_API_CRUD_SUPER_KEY;

// const ae_account_id = PUBLIC_AE_ACCOUNT_ID;
const ae_account_id: null | string = null;
const ae_no_account_id = PUBLIC_AE_NO_ACCOUNT_ID;
// const ae_no_account_id_token = PUBLIC_AE_NO_ACCOUNT_ID_TOKEN;
// const ae_event_id = PUBLIC_AE_EVENT_ID;
// const ae_sponsorship_cfg_id = PUBLIC_AE_SPONSORSHIP_CFG_ID;

// Loose bag-of-anything type used throughout the store. Once stores are broken into
// typed domain files, individual structs will have proper interfaces instead.
export type key_val = {
    [key: string]: any;
};

import { string_snippets } from '$lib/ae_utils/ae_string_snippets';
export const ae_snip = string_snippets;

// Deployment version stamp. Compared against ae_sess.ver in +layout.svelte to detect
// stale persisted data after a deploy (triggers a reload). Bump this alongside
// ae_app_session_data_defaults.ver whenever a deploy changes expected stored shape.
// See store_versions.ts for the schema-level localStorage wipe mechanism (separate concern).
const ver = '2025-05-01_1445';

// *** BEGIN *** Longer-term app data. This should be stored to local storage.
const ae_app_local_data_defaults: key_val = {
    __version: AE_LOC_VERSION, // Schema version gate — see store_versions.ts
    last_page_reload: null,
    last_cache_refresh: Date.now(),
    cache_expired: false,
    // Deployment stamp — compared against ae_sess.ver in +layout.svelte to trigger
    // a reload when the persisted local data predates the current deploy.
    ver: ver,

    name: 'Aether - App Hub',

    theme: 'light',
    theme_mode: 'light',
    theme_name: 'AE_Firefly', // OSIT default theme
    // When true the user has explicitly chosen a theme (dropdown or URL param).
    // Use this to avoid overwriting an explicit user choice with a site default.
    user_theme_selected: false,
    font_size_mode: 'default', // 'default' | 'larger' | 'smaller'
    iframe: false,

    browser_type: null, // Safari needs special handling for scrolling in iframes.

    title: `OSIT's Æ`,

    debug_mode: false,
    edit_mode: false,
    adv_mode: false,
    sync_local_config: true, // When true, pulls site config from the remote API on load.

    // Auth and identity section — see ae_stores__auth_loc_defaults.ts.
    ...auth_loc_defaults,

    qry__enabled: 'enabled', // all, disabled, enabled
    qry__hidden: 'not_hidden', // all, hidden, not_hidden
    qry__limit: 20,
    qry__offset: 0,

    admin: {
        show_element__sql_qry: false,
        show_element__sql_qry_results: false
    },

    sys_menu: {
        hide: false,
        expand: false,
        hide_access_type: false,
        expand_access_type: false,
        hide_edit_mode: false,
        expand_edit_mode: false,
        hide_user: false,
        expand_user: false,
        hide_theme: false,
        expand_theme: false,
        hide_app_cfg: false,
        expand_app_cfg: false
    },
    debug_menu: {
        hide: false,
        expand: false
    },

    app_cfg: {
        show_element__header: false,
        show_element__footer: false,
        show_element__menu: false,
        show_element__menu_btn: true,

        show_element__access_type: true,
        show_element__passcode_input: true,
        show_element__cfg: true,
        show_element__cfg_detail: false,
        show_element__sign_in_out: true, // Show the sign-in/out button in the UI
        show_opt__debug: true,
        show_opt__permissions: true,
        show_opt__reset: true,
        show_opt__sync: true,
        show_opt__theme: true,
        show_opt__utilities: true
    },

    files: {
        processed_file_kv: {},
        uploaded_file_kv: {},
        video_clip_file_kv: {},
        add_to_use_files_method: 'upload' // upload, select
    },

    hub: {
        show_element__cfg: true,
        show_element__cfg_detail: false,
        show_element__access_type: true,
        theme_mode: 'light',
        theme_name: 'wintry', // wintry

        classes__form:
            'border border-surface-200 p-4 space-y-4 rounded-container',

        qr: {}
    },
};

export const ae_loc: Writable<key_val> = persisted(
    'ae_loc',
    ae_app_local_data_defaults
);

// *** BEGIN *** Temporary app data. This should be stored to session storage.
const ae_app_session_data_defaults: key_val = {
    // Deployment stamp — compared against ae_loc.ver in +layout.svelte.
    // When these differ, the app reloads to flush stale persisted data.
    ver: ver,
    log_lvl: 0,

    disable_sys_header: false,
    disable_sys_nav: false,
    disable_sys_footer: false,

    sys_menu: {
        expand: false,
        focus_passcode_input: false
    },

    debug_menu: {
        hide_quick_info: true
    },

    app_cfg: {
        show_element__passcode_input: true
    },

    ds: {
        submit_status: null
    },
    ds_loaded: {
        hub__site__root_page_header: false,
        hub__site__root_page_content: false,
        hub__site__root_page_footer: false
    },

    files: {
        disable_submit__hosted_file_obj: false,
        processed_file_kv: {},
        uploaded_file_kv: {},
        video_clip_file_kv: {},
        processed_file_list: [],
        status__file_list: null,
        video_clip_file_list: [],
        submit_status: null,
        clip_complete: null
    },

    person: {
        show_report__person_li: false,

        qry_limit__people: 100
    },

    show__modal_change_password: false,

    // Per-file progress keyed by file_id (downloads) or temp_id (uploads).
    // Shape: { status, endpoint, filename, size_total, size_loaded, percent_completed }
    api_download_kv: {},
    api_upload_kv: {},

    test: true
};
export const ae_sess = writable(ae_app_session_data_defaults);

export const ae_api_data_struct: key_val = {
    ver: '2024-08-11_11',
    fqdn: api_server_fqdn,
    base_url: api_base_url,
    base_url_bak: api_base_url_bak,
    api_secret_key: api_secret_key,
    api_secret_key_bak: api_secret_key,
    api_crud_super_key: api_crud_super_key, // Used for operations that bypass normal account-scoped CRUD limits.
    headers: {},
    account_id: ae_account_id
};

const ae_api_headers: key_val = {};
ae_api_headers['Content-Type'] = 'application/json';
ae_api_headers['x-aether-api-key'] = ae_api_data_struct.api_secret_key;
if (ae_account_id) {
    ae_api_headers['x-account-id'] = ae_account_id;
}
if (ae_no_account_id) {
    ae_api_headers['x-no-account-id'] = ae_no_account_id;
}
ae_api_data_struct['headers'] = ae_api_headers;

export const ae_api = writable(ae_api_data_struct);

// General-purpose reactive trigger. Set any truthy value to signal consumers to re-query.
const ae_trig_template: key_val = {};
export const ae_trig = writable(ae_trig_template);

/* *** BEGIN *** Initialize slct and slct_trigger */
/* The slct and slct_trigger variable should not be stored in local storage. Only use session storage because browser tabs can be open to different accounts, events, sponsorships, etc. */

// Intended for temporary session storage.
// Updated 2024-03-15
const slct_obj_template: key_val = {
    account_id: ae_account_id,
    account_obj: {},
    event_id: null,
    event_obj: {},
    event_obj_li: [],
    event_presentation_id: null,
    event_presentation_obj: {},
    event_presentation_obj_li: [],
    event_presenter_id: null,
    event_presenter_obj: {},
    event_presenter_obj_li: [],
    event_session_id: null,
    event_session_obj: {},
    event_session_obj_li: [],
    sponsorship_id: null,
    sponsorship_obj: {},
    sponsorship_obj_li: [],
    sponsorship_cfg_id: null,
    sponsorship_cfg_obj: {},
    sponsorship_cfg_obj_li: [],
    post_id: null,
    post_obj: {},
    post_obj_li: [],
    post_comment_id: null,
    post_comment_obj: {},
    post_comment_obj_li: []
};
// In-memory only (not persisted) — separate browser tabs can have different selections.
export const slct = writable(slct_obj_template);

// Increment (or set any truthy value) to tell subscribers that the selection changed
// and they should re-query their data.
export const slct_trigger: any = writable(null);

// Auth error signal — set by API helpers on 401/403 to trigger the session-expired banner in the root layout.
// Only set from browser context (never SSR). 'expired' covers both 401 and 403 responses.
export const ae_auth_error = writable<{
    type: 'expired' | null;
    ts: number | null;
}>({ type: null, ts: null });

// Reactive clock — updates every second. Used for live countdown and elapsed-time displays.
export const time = readable(new Date(), function start(set) {
    const interval = setInterval(() => {
        set(new Date());
    }, 1000);

    return function stop() {
        clearInterval(interval);
    };
});
