/** @type {import('./$types').LayoutLoad} */
// console.log(`ae_root +layout.ts: start`);

// import { error } from '@sveltejs/kit';
import { lookup_site_domain } from '$lib/ae_core/ae_core__site';
import type { key_val } from '$lib/stores/ae_stores';
// import type { ae_SiteDomain } from '$lib/types/ae_types';

export const ssr = false;
export const prerender = false;

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_BOOTSTRAP_KEY
    // PUBLIC_AE_NO_ACCOUNT_ID,
    // PUBLIC_AE_NO_ACCOUNT_ID_TOKEN
} from '$env/static/public';

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: 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_api_init: key_val = {
    ver: '2026-05-13_04',
    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,
    headers: {},
    account_id: ae_account_id
};

const ae_api_headers: key_val = {
    'Content-Type': 'application/json',
    'x-aether-api-key': api_secret_key,
    'x-ae-ignore-extra-fields': 'true'
};

ae_api_init['headers'] = ae_api_headers;

export async function load({ fetch, params, parent, route, url }) {
    const log_lvl: number = 1;

    let account_id: any;

    const ae_acct: key_val = {
        api: {
            ...ae_api_init,
            headers: { ...ae_api_headers } // Local clone
        },
        ds: {},
        loc: {
            account_id: '',
            site_id: '',
            site_domain_id: '',
            iframe: false
        },
        sess: {},
        slct: {}
    };

    // Initialize API fetch with SvelteKit fetch
    ae_api_init['fetch'] = fetch;

    // IMMEDIATE AUTH SYNC: Read JWT from localStorage to avoid race conditions
    if (typeof localStorage !== 'undefined') {
        try {
            const ae_loc_raw = localStorage.getItem('ae_loc');
            if (ae_loc_raw) {
                const ae_loc_json = JSON.parse(ae_loc_raw);
                if (ae_loc_json.jwt) {
                    ae_api_init['jwt'] = ae_loc_json.jwt;
                }

                // Enforce passcode JWT TTL on every page load.
                // Decodes the JWT payload (base64, no secret needed) and resets the
                // session to anonymous if the passcode JWT has expired.
                // User login JWTs (auth_type !== 'passcode') are never touched here.
                // This block is always active but only fires once USE_API_PASSCODE_AUTH
                // has been flipped and the user has a passcode JWT in their ae_loc.
                if (ae_loc_json?.jwt) {
                    try {
                        const parts = ae_loc_json.jwt.split('.');
                        if (parts.length === 3) {
                            const jwt_payload = JSON.parse(atob(parts[1]));
                            const json_str =
                                typeof jwt_payload.json_str === 'string'
                                    ? JSON.parse(jwt_payload.json_str)
                                    : jwt_payload.json_str;
                            if (
                                json_str?.auth_type === 'passcode' &&
                                jwt_payload.eat < Date.now() / 1000
                            ) {
                                // Passcode session has expired — drop to anonymous.
                                ae_loc_json.jwt = null;
                                ae_loc_json.access_type = 'anonymous';
                                localStorage.setItem('ae_loc', JSON.stringify(ae_loc_json));
                            }
                        }
                    } catch {
                        // Malformed JWT — leave untouched, let existing handling deal with it.
                    }
                }
            }
        } catch (e) {
            // Silently fail on storage read
        }
    }

    const ae_loc_init: key_val = {};
    const ds_code_li: null | key_val = {};

    const data_struct: key_val = {
        account_id: null,
        ae_acct: {},
        ae_loc: {},
        ae_api: ae_api_init,
        ae_ds: {},
        ae_hub: {},
        ae_m_sponsorships: {},
        ae_m_events: {},
        ae_m_events_speakers: {},
        ae_m_idaa: {},
        ae_slct: {},
        iframe: false,
        ae_root_layout_ts: true,
        params: params,
        route: route,
        url: url,
        sections: [
            { slug: 'new', title: 'New Test' },
            { slug: 'manage', title: 'Manage Test' },
            { slug: 'test', title: 'Test Test' }
        ],
        submenu: {}
    };

    const fqdn = url.host;
    // Optional access key provided via URL `?key=...` to support restricted site domains
    const access_key = url.searchParams.get('key') || undefined;

    let result: any = null;
    let api_error = false;
    let is_native = false;

    // 1. FAST PATH: Check Dexie for cached site domain first
    // This allows the load function to return nearly instantly if the user has visited before.
    if (typeof window !== 'undefined' && (window as any).indexedDB) {
        try {
            // Use the db_core instance directly for a quick lookup
            const { db_core } = await import('$lib/ae_core/db_core');
            const cached = await db_core.site_domain
                .where('fqdn')
                .equals(fqdn)
                .first();
            if (cached) {
                if (log_lvl)
                    console.log(
                        'ROOT LOAD: Found cached site domain. Evaluating cache vs URL key.'
                    );

                // If the URL contains an access_key, we must ensure the cached
                // entry is valid for that key. If the cache has no keys or the
                // keys don't match, force a live lookup to revalidate.
                if (access_key) {
                    const cachedSiteKey =
                        (cached as any).access_key ||
                        (cached as any).site_access_key ||
                        (cached as any).site_domain_access_key ||
                        '';
                    const cachedDomainKey =
                        (cached as any).site_domain_access_key ||
                        (cached as any).site_access_key ||
                        (cached as any).access_key ||
                        '';

                    if (!cachedSiteKey && !cachedDomainKey) {
                        if (log_lvl)
                            console.log(
                                'BOOTSTRAP: Cache has no access keys; forcing live lookup because URL contains a key.'
                            );
                        // leave `result` null so slow-path lookup runs
                    } else if (
                        access_key === cachedSiteKey ||
                        access_key === cachedDomainKey
                    ) {
                        if (log_lvl)
                            console.log('BOOTSTRAP: URL key matches cached access key; using cached object.');
                        result = cached as any;
                    } else {
                        if (log_lvl)
                            console.log('BOOTSTRAP: URL key does not match cached keys; forcing live lookup to revalidate.');
                        // leave `result` null so slow-path lookup runs
                    }
                } else {
                    // No access_key in URL — safe to use cached value
                    result = cached as any;
                }
            }
        } catch (e) {
            if (log_lvl)
                console.warn('ROOT LOAD: Failed to read from Dexie cache.', e);
        }
    }

    // Detect Aether Native Bridge (Electron)
    if (typeof window !== 'undefined' && (window as any).aetherNative) {
        is_native = true;
        if (log_lvl)
            console.log(
                'ROOT LOAD: Detected Aether Native Bridge. Requesting device config...'
            );
        try {
            const native_device_config = await (
                window as any
            ).aetherNative.get_device_config();
            if (native_device_config) {
                if (log_lvl)
                    console.log(
                        'ROOT LOAD: Native device config received:',
                        native_device_config
                    );
                // Map native device config to the expected result structure
                // Use native as source of truth if available
                result = {
                    ...native_device_config,
                    // Ensure naming consistency
                    account_id:
                        native_device_config.account_id ||
                        native_device_config.account_id_random,
                    site_id:
                        native_device_config.site_id ||
                        native_device_config.site_id_random,
                    site_domain_id:
                        native_device_config.site_domain_id ||
                        native_device_config.site_domain_id_random
                };

                // Inject native device metadata into the location state with SAFE MERGE
                if (native_device_config.native_device) {
                    const incoming_dev = native_device_config.native_device;

                    // String-Only ID Vision: Ensure semantic fields use the random string ID
                    if (incoming_dev.event_device_id_random)
                        incoming_dev.event_device_id =
                            incoming_dev.event_device_id_random;
                    if (incoming_dev.event_id_random)
                        incoming_dev.event_id = incoming_dev.event_id_random;
                    if (incoming_dev.id_random)
                        incoming_dev.id = incoming_dev.id_random;

                    // 1. Recover existing user overrides from localStorage
                    let existing_dev = {};
                    try {
                        const raw = localStorage.getItem('ae_loc');
                        if (raw)
                            existing_dev = JSON.parse(raw).native_device || {};
                    } catch (e) {}

                    // 2. Merge: Priority to EXISTING overrides for specific timers
                    ae_loc_init['native_device'] = {
                        ...incoming_dev,
                        // Persist these specific user-controlled fields
                        check_event_loop_period:
                            (existing_dev as any).check_event_loop_period ||
                            incoming_dev.check_event_loop_period,
                        check_event_device_loop_period:
                            (existing_dev as any)
                                .check_event_device_loop_period ||
                            incoming_dev.check_event_device_loop_period,
                        check_event_location_loop_period:
                            (existing_dev as any)
                                .check_event_location_loop_period ||
                            incoming_dev.check_event_location_loop_period,
                        check_event_session_loop_period:
                            (existing_dev as any)
                                .check_event_session_loop_period ||
                            incoming_dev.check_event_session_loop_period,
                        // Use API value if present; default to 2 (never preserve from localStorage — stale values cause orphaned cache dirs)
                        hash_prefix_length: incoming_dev.hash_prefix_length || 2
                    };

                    // Map specific operational paths
                    ae_loc_init['local_file_cache_path'] =
                        incoming_dev.local_file_cache_path;
                    ae_loc_init['host_file_temp_path'] =
                        incoming_dev.host_file_temp_path;
                    ae_loc_init['recording_path'] = incoming_dev.recording_path;
                }

                // IMPORTANT: Update API settings with the native-authorized key if present
                if (native_device_config.aether_api_key) {
                    ae_api_init['api_secret_key'] =
                        native_device_config.aether_api_key;
                    ae_api_headers['x-aether-api-key'] =
                        native_device_config.aether_api_key;
                }
            }
        } catch (err) {
            console.error(
                'ROOT LOAD: Failed to fetch native device config.',
                err
            );
        }
    }

    // 2. SLOW PATH: Wait for API site lookup only if we have no result yet
    if (!result) {
        try {
            if (log_lvl)
                console.log(
                    `ROOT LOAD: No cache. Starting site lookup V3 for ${fqdn}...`
                );

            // Use dedicated Bootstrap key — limited permissions, no account_id required.
            // Key is injected at build time from PUBLIC_AE_BOOTSTRAP_KEY in .env.
            const bootstrap_api_cfg = {
                ...ae_api_init,
                api_secret_key: PUBLIC_AE_BOOTSTRAP_KEY,
                headers: {
                    ...ae_api_init.headers,
                    'x-aether-api-key': PUBLIC_AE_BOOTSTRAP_KEY,
                    'x-no-account-id': 'bypass' // Force explicit bypass for bootstrap
                }
            };

            result = await lookup_site_domain({
                api_cfg: bootstrap_api_cfg,
                fqdn,
                view: 'base',
                log_lvl,
                access_key
            });
            if (log_lvl)
                console.log(
                    `ROOT LOAD: Site lookup result for ${fqdn}:`,
                    result
                );
        } catch (err) {
            console.error(
                `ROOT LOAD: Site lookup critical failure for ${fqdn}.`,
                err
            );
            api_error = true;
        }
    } else {
        // We have a result (cache or native), fire off the refresh in the background to update Dexie
        if (log_lvl)
            console.log(
                'ROOT LOAD: Result already obtained. Background refresh triggered.'
            );
        lookup_site_domain({
            api_cfg: ae_api_init,
            fqdn,
            view: 'base',
            log_lvl: 0,
            access_key
        });
    }

    // Defensive check: if result is false (common from API helper) or null, use emergency ghost
    if (
        !result ||
        typeof result !== 'object' ||
        result.account_id === 'ghost'
    ) {
        console.warn(
            `ROOT LOAD: Falsy or Ghost result for ${fqdn}. Forcing fallback message.`
        );
        result = {
            id: 'ghost',
            id_random: 'ghost',
            account_id_random: 'ghost',
            account_code: 'ghost',
            account_name: api_error
                ? 'API Connection Failed'
                : 'Domain Not Found or Missing Access Key',
            site_id_random: 'ghost',
            site_domain_id_random: 'ghost',
            enable: '1',
            cfg_json: {},
            style_href: '',
            header_image_path: ''
        };
    }

    const json_data = result;
    // ... rest of the mapping logic ...
    account_id = json_data.account_id || 'ghost';
    data_struct.account_id = account_id;
    ae_acct.account_id = account_id;

    if (log_lvl) console.log(`ROOT LOAD: Using account_id: ${account_id}`);

    // Update the local clones
    ae_acct.api.account_id = account_id;
    ae_acct.api.headers['x-account-id'] = account_id;

    ae_loc_init['is_native'] = is_native;
    ae_loc_init['account_id'] = account_id;
    ae_loc_init['account_code'] = json_data.account_code || 'ghost';
    ae_loc_init['account_name'] = json_data.account_name || 'Ghost Account';

    ae_loc_init['site_id'] = json_data.site_id || 'ghost';
    ae_loc_init['site_domain_id'] =
        json_data.site_domain_id || json_data.site_domain_id || 'ghost';
    ae_loc_init['site_enable'] = json_data.enable || '1';
    ae_loc_init['site_header_image_path'] = json_data.header_image_path || '';
    ae_loc_init['site_style_href'] = json_data.style_href || '';
    ae_loc_init['site_google_tracking_id'] = json_data.google_tracking_id || '';
    ae_loc_init['site_access_code_kv'] = json_data.access_code_kv_json || {};
    ae_loc_init['site_cfg_json'] = json_data.cfg_json || {};
    // Apply site-level theme defaults only when there is no persisted ae_loc
    // in localStorage (first-run). URL params and manual selection still override.
    try {
        // site_cfg_json may be an object or a JSON string depending on the API/backend.
        let scfg_raw = ae_loc_init['site_cfg_json'];
        let scfg: any = scfg_raw;
        if (typeof scfg_raw === 'string') {
            try {
                scfg = JSON.parse(scfg_raw);
            } catch (e) {
                scfg = {};
            }
        }

        // Inspect persisted `ae_loc` in localStorage to determine whether the
        // user has already selected a theme. Some persisted-store implementations
        // write a default `ae_loc` object immediately, so the mere presence of
        // the key is not a reliable indicator of a user choice.
        let persistedRaw: string | null = null;
        try {
            if (typeof localStorage !== 'undefined') persistedRaw = localStorage.getItem('ae_loc');
        } catch (e) {
            persistedRaw = null;
        }

        let persistedObj: any = null;
        let persistedHasUserTheme = false;
        if (persistedRaw) {
            try {
                persistedObj = JSON.parse(persistedRaw);
            } catch (e) {
                persistedObj = null;
            }
            if (persistedObj) {
                // Explicit flag wins.
                if (persistedObj.user_theme_selected === true) {
                    persistedHasUserTheme = true;
                } else if (persistedObj.theme_name && persistedObj.theme_name !== 'AE_Firefly') {
                    // If the persisted theme differs from the global default, assume
                    // it was a prior user choice (backcompat for older installs).
                    persistedHasUserTheme = true;
                }
            }
        }

        if (scfg && typeof scfg === 'object' && !persistedHasUserTheme) {
            // Accept common keys for theme name so site authors have flexibility.
            const themeName = scfg.theme_name ?? scfg.theme ?? scfg.themeName ?? scfg.site_theme;
            if (themeName) ae_loc_init['theme_name'] = themeName;
            if (scfg.theme_mode && (scfg.theme_mode === 'light' || scfg.theme_mode === 'dark'))
                ae_loc_init['theme_mode'] = scfg.theme_mode;
        }
    } catch (e) {
        // Defensive: if parsing fails, don't block boot.
    }
    ae_loc_init['site_access_key'] = json_data.access_key || '';
    ae_loc_init['site_domain_access_key'] =
        json_data.site_domain_access_key || '';

    ae_loc_init['base_url'] = url.origin;
    ae_loc_init['hostname'] = url.hostname;

    // Access key gate — re-enabled 2026-04-28.
    // Only write allow_access when a key is actively present in the URL.
    // If no key on refresh/navigation, do NOT set allow_access — the persisted
    // value from the original keyed visit survives the ae_loc spread in +layout.svelte.
    // Setting it unconditionally (even to `true`) overwrites the persisted key string
    // on every refresh, which was the root cause of the 2026-04-01 lockout bug.
    ae_loc_init['key_checked'] = true;
    if (access_key) {
        ae_loc_init['allow_access'] = access_key;
    }

    // if (!account_id) {
    //     error(500, {
    //         message: 'The account ID was not found! Check the API.'
    //     });
    // }

    // account_name is already set above (line ~385). This was a duplicate that
    // overwrote it with a different fallback string — removed.

    // ae_acct['api'] = ae_api_init; // DO NOT USE: This overwrites our isolated clone from line 65
    ae_acct['loc'] = ae_loc_init;
    ae_acct['ds'] = ds_code_li;
    ae_acct['slct'] = {
        account_id: account_id,
        site_domain_id: ae_loc_init.site_domain_id,
        site_id: ae_loc_init.site_id
        // event_id: ae_loc_init.site_cfg_json?.slct__event_id,
        // event_badge_template_id: ae_loc_init.site_cfg_json?.slct__event_badge_template_id,
        // sponsorship_cfg_id: ae_loc_init.site_cfg_json?.slct__sponsorship_cfg_id
    };

    data_struct[account_id] = ae_acct;

    if (log_lvl)
        console.log(
            'ROOT LOAD: Final data_struct structure ready.',
            Object.keys(data_struct)
        );

    return data_struct;
}
