import { browser } from '$app/environment';
import type { key_val } from '$lib/stores/ae_stores';
import { api } from '$lib/api/api';

import {
    load_ae_obj_id__activity_log,
    load_ae_obj_li__activity_log,
    create_ae_obj__activity_log,
    update_ae_obj__activity_log
} from '$lib/ae_core/ae_core__activity_log';

import {
    load_ae_obj_id__person,
    load_ae_obj_li__person,
    create_ae_obj__person,
    delete_ae_obj_id__person,
    update_ae_obj__person
} from '$lib/ae_core/ae_core__person';

import {
    auth_ae_obj__username_password,
    auth_ae_obj__user_id_user_auth_key,
    send_email_auth_ae_obj__user_id,
    qry_ae_obj_li__user_email,
    auth_ae_obj__user_id_change_password
} from '$lib/ae_core/ae_core__user';

import { generate_qr_code, js_generate_qr_code } from '$lib/ae_core/core__qr_code';

import { check_hosted_file_obj_w_hash } from '$lib/ae_core/core__check_hosted_file_obj_w_hash';

import { load_ae_obj_li__time_zone } from '$lib/ae_core/core__time_zones';

import { load_ae_obj_li__country } from '$lib/ae_core/core__countries';

import { load_ae_obj_li__country_subdivision } from '$lib/ae_core/core__country_subdivisions';

import {
    load_ae_obj_id__hosted_file,
    load_ae_obj_li__hosted_file,
    delete_ae_obj_id__hosted_file
} from '$lib/ae_core/core__hosted_files';

// This has more generic general purpose functions that can eventually replace the custom ones per object type.
import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';

import { add_url_params, clean_headers } from '$lib/ae_core/core__api_helpers';

const ae_promises: key_val = {}; // Promise<any>;

// Updated 2024-03-29
async function load_ae_obj_id__site_domain({
    api_cfg,
    fqdn,
    try_cache = false,
    timeout = 7000,
    log_lvl = 0
}: {
    api_cfg: any;
    fqdn: string;
    try_cache?: boolean;
    timeout?: number;
    log_lvl?: number;
}) {
    if (log_lvl) {
        console.log(
            `*** load_ae_obj_id__site_domain() *** api.base_url=${api_cfg.base_url}, fqdn=${fqdn}, timeout=${timeout}`
        );
    }

    let no_account_id = false;
    if (!api_cfg.account_id) {
        no_account_id = true;
        // api_cfg.headers['x_account_id'] = 'nothing here';
    }
    no_account_id = true;

    const params = {};

    // ae_sess.hub.site_domain_id_qry_status = 'loading';
    ae_promises.load__site_domain_obj = api
        .get_ae_obj_id_crud({
            api_cfg: api_cfg,
            no_account_id: no_account_id,
            obj_type: 'site_domain',
            obj_id: fqdn, // NOTE: This is the FQDN, not normally the ID.
            use_alt_table: true, // NOTE: This will use the table_name_alt value (v_site_domain_fqdn_id) instead of the table_name value in the API config.
            use_alt_base: true, // NOTE: This will use the base_name_alt value (Site_Domain_FQDN_ID_Base) instead of the base_name value in the API config.
            params: params,
            timeout: timeout,
            log_lvl: log_lvl
        })
        .then(function (site_domain_obj_get_result) {
            if (site_domain_obj_get_result) {
                // slct.site_domain_obj = site_domain_obj_get_result;
                // console.log(`site_domain object:`, get(slct).site_domain_obj);

                // ae_loc.account_id = $slct.site_domain_obj.account_id_random;
                // ae_loc.site_id = $slct.site_domain_obj.site_id_random;
                // ae_loc.site_domain_id = $slct.site_domain_obj.site_domain_id_random;
                return site_domain_obj_get_result;
            } else {
                console.log('No results returned.');
                return null;
            }
        })
        .catch(function (error: any) {
            console.log('No results returned or failed.', error);
        });

    return ae_promises.load__site_domain_obj;
}

// Updated 2026-01-29
async function load_ae_obj_code__data_store({
    api_cfg,
    code,
    data_type = 'text',
    for_type = null,
    for_id = null,
    try_cache = true,
    save_idb = false,
    timeout = 9000,
    log_lvl = 0
}: {
    api_cfg: any;
    code: string;
    data_type?: string;
    for_type?: string | null;
    for_id?: string | null;
    try_cache?: boolean;
    save_idb?: boolean;
    timeout?: number;
    log_lvl?: number;
}) {
    if (log_lvl) {
        console.log(`*** load_ae_obj_code__data_store() *** code=${code}`);
    }

    if (!code) {
        console.log(`*ae_func* No code provided!`);
        return false;
    }

    if (!api_cfg.account_id) {
        console.log(`*ae_func* No account_id found in API config!`);
        return false;
    }

    ae_promises.load__data_store_obj = api
        .get_data_store_obj_w_code({
            api_cfg: api_cfg,
            data_store_code: code,
            data_type: data_type,
            timeout: timeout,
            log_lvl: log_lvl
        })
        .then(function (get_ds_result) {
            let return_this = null;
            if (get_ds_result) {
                if (log_lvl) {
                    console.log(`*ae_func* Got a result for code ${code}`);
                }

                if (!get_ds_result.data_store_id_random) {
                    console.log('*ae_func* Something went wrong? No data store ID found.');
                    return false;
                }

                // let ae_ds_tmp: key_val = {};
                const ds_code_obj = {
                    id: null,
                    account_id: null,
                    code: code,
                    name: null,
                    type: data_type,
                    for_type: null, // for_type
                    for_id: null, // for_id
                    access_read: null, // 'super', 'administrator', 'trusted', 'anonymous'
                    access_write: null, // 'super', 'administrator', 'trusted', 'anonymous'
                    access_delete: null, // 'super', 'administrator', 'trusted', 'anonymous'
                    html: null,
                    json: null,
                    md: null,
                    text: null,
                    updated_on: null,
                    chk_account_id: api_cfg.account_id,
                    loaded_on: new Date().toISOString()
                };
                let val_json: key_val;
                let val_html: key_val;
                let val_md: key_val;
                let val_sql: key_val;
                let val_text: string;

                // Set the loaded_on datetime to the current time for reference later. This will be used to determine if the data store is stale.
                // ds_code_obj.loaded_on = new Date().toISOString();
                // Set the chk_account_id as a backup check to make sure the data store belongs to the account for the current site. This should not be needed, but here we are...
                // ds_code_obj.chk_account_id = api_cfg.account_id;

                ds_code_obj.id = get_ds_result.data_store_id_random;
                ds_code_obj.account_id = get_ds_result.account_id_random;
                ds_code_obj.code = get_ds_result.code; // This will overwrite whatever was passed in.
                ds_code_obj.name = get_ds_result.name;
                ds_code_obj.type = get_ds_result.type; // This will overwrite whatever was passed in.
                if (data_type == 'html') {
                    ds_code_obj.html = get_ds_result.text;
                    val_html = get_ds_result.text;
                    return_this = get_ds_result.html;
                } else if (data_type == 'json') {
                    ds_code_obj.json = get_ds_result.json;
                    val_json = get_ds_result.json;
                    return_this = get_ds_result.json;
                } else if (data_type == 'md') {
                    ds_code_obj.text = get_ds_result.text;
                    val_md = get_ds_result.text;
                    return_this = get_ds_result.text;
                } else if (data_type == 'sql') {
                    ds_code_obj.text = get_ds_result.text;
                    val_sql = get_ds_result.text;
                    return_this = get_ds_result.text;
                } else {
                    ds_code_obj.text = get_ds_result.text;
                    val_text = get_ds_result.text;
                    return_this = get_ds_result.text;
                }

                // if (data_type == 'text') {
                //     // console.log(get_ds_result.text);
                //     return_this = get_ds_result.text;
                // } else if (data_type == 'json') {
                //     // console.log(get_ds_result.json);
                //     return_this = get_ds_result.json;
                // }

                if (save_idb) {
                    if (browser) {
                        const key_prefix = 'ae_ds__';
                        if (log_lvl) {
                            console.log(
                                `*ae_func* localStorage key: ${code}, value:`,
                                get_ds_result
                            );
                        }
                        localStorage.setItem(`${key_prefix}${code}`, JSON.stringify(get_ds_result));
                    } else {
                        if (log_lvl) {
                            console.log(
                                '*ae_func* No browser! Can not use localStorage to save data store object.'
                            );
                        }
                    }
                }
            } else {
                console.log('*ae_func* No results returned.');
                return_this = null;
            }
            return return_this;
        })
        .catch(function (error: any) {
            console.log('*ae_func* No results returned or failed.', error);
        });

    return ae_promises.load__data_store_obj;
}

// Updated 2024-03-27
async function update_ae_obj_id_crud({
    api_cfg,
    object_type,
    object_id,
    object_reload = false,
    field_name,
    new_field_value,
    params = {},
    try_cache = false,
    log_lvl = 0
}: {
    api_cfg: any;
    object_type: string;
    object_id: string;
    object_reload?: boolean;
    field_name: string;
    new_field_value: any;
    params: any | key_val;
    try_cache: boolean;
    log_lvl: number;
}) {
    let patch_result: any = null;

    ae_promises.api_update__ae_obj = api
        .update_ae_obj_id_crud({
            api_cfg: api_cfg,
            obj_type: object_type,
            obj_id: object_id,
            field_name: field_name,
            field_value: new_field_value,
            // fields: data,
            key: api_cfg.api_crud_super_key,
            // jwt: null,
            // params: params,
            // data: patch_data,
            log_lvl: log_lvl
        })
        .then(function (results) {
            console.log('PATCH Promise', results);

            if (results) {
                console.log(
                    `Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}`
                );
                patch_result = 'PATCH complete';
            } else {
                console.log(
                    `Not Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}; Account ID: ${api_cfg.account_id}`
                );
                patch_result = 'PATCH failed';
                return false;
            }
            return true;
        })
        .catch(function (error: any) {
            console.log('Something went wrong patching the record.');
            console.log(error);
            return false;
        })
        .finally(function () {
            console.log('PATCH Promise finally');
        });

    return ae_promises.api_update__ae_obj;
}

// Core - Already imported above
// import { load_ae_obj_id__person } from "$lib/ae_core/core__person";
// import { load_ae_obj_id__user } from "$lib/ae_core/core__user";

// Additional Modules
import { load_ae_obj_id__archive } from '$lib/ae_archives/ae_archives__archive';
import { load_ae_obj_id__archive_content } from '$lib/ae_archives/ae_archives__archive_content';

import { load_ae_obj_id__event } from '$lib/ae_events/ae_events__event';
// import { load_ae_obj_id__event_badge } from "$lib/ae_events/ae_events__event_badge";
import { load_ae_obj_id__event_exhibit } from '$lib/ae_events/ae_events__exhibit';
import { load_ae_obj_id__event_device } from '$lib/ae_events/ae_events__event_device';
// import { load_ae_obj_id__event_exhibit } from "$lib/ae_events/ae_events__event_exhibit";
import { load_ae_obj_id__event_file } from '$lib/ae_events/ae_events__event_file';
import { load_ae_obj_id__event_location } from '$lib/ae_events/ae_events__event_location';
import { load_ae_obj_id__event_presentation } from '$lib/ae_events/ae_events__event_presentation';
import { load_ae_obj_id__event_presenter } from '$lib/ae_events/ae_events__event_presenter';
import { load_ae_obj_id__event_session } from '$lib/ae_events/ae_events__event_session';

import { load_ae_obj_id__journal } from '$lib/ae_journals/ae_journals__journal';
import { load_ae_obj_id__journal_entry } from '$lib/ae_journals/ae_journals__journal_entry';

import { load_ae_obj_id__post } from '$lib/ae_posts/ae_posts__post';
import { load_ae_obj_id__post_comment } from '$lib/ae_posts/ae_posts__post_comment';

// Updated 2025-09-30
async function update_ae_obj_id_crud_v2({
    api_cfg,
    object_type,
    object_id,
    object_reload = false,
    field_name,
    new_field_value,
    params = {},
    try_cache = false,
    log_lvl = 0
}: {
    api_cfg: any;
    object_type: string;
    object_id: string;
    object_reload?: boolean;
    field_name: string;
    new_field_value: any;
    params?: any | key_val;
    try_cache?: boolean;
    log_lvl?: number;
}) {
    if (log_lvl) {
        console.log(
            `*** update_ae_obj_id_crud_v2() *** object_type=${object_type}, object_id=${object_id}, object_reload=${object_reload}, field_name=${field_name}, new_field_value=`,
            new_field_value
        );
    }

    const results = await api.update_ae_obj_id_crud({
        api_cfg: api_cfg,
        obj_type: object_type,
        obj_id: object_id,
        field_name: field_name,
        field_value: new_field_value,
        key: api_cfg.api_crud_super_key,
        log_lvl: log_lvl
    });

    if (results) {
        if (log_lvl) {
            console.log(`Patched - Field Name: ${field_name} with new Field Value: ${new_field_value}`);
        }

        if (object_reload) {
            if (log_lvl) {
                console.log(`Reloading the object after patching...`);
            }
            // Trigger reloads based on object type. These are fire-and-forget or awaited internally by the library functions.
            if (object_type == 'person') load_ae_obj_id__person({ api_cfg, person_id: object_id, log_lvl });
            if (object_type == 'archive') load_ae_obj_id__archive({ api_cfg, archive_id: object_id, log_lvl });
            if (object_type == 'archive_content') load_ae_obj_id__archive_content({ api_cfg, archive_content_id: object_id, log_lvl });
            if (object_type == 'journal') load_ae_obj_id__journal({ api_cfg, journal_id: object_id, log_lvl });
            if (object_type == 'journal_entry') load_ae_obj_id__journal_entry({ api_cfg, journal_entry_id: object_id, log_lvl });
            if (object_type == 'event') load_ae_obj_id__event({ api_cfg, event_id: object_id, log_lvl });
            if (object_type == 'event_exhibit') load_ae_obj_id__event_exhibit({ api_cfg, exhibit_id: object_id, log_lvl });
            if (object_type == 'event_device') load_ae_obj_id__event_device({ api_cfg, event_device_id: object_id, log_lvl });
            if (object_type == 'event_file') load_ae_obj_id__event_file({ api_cfg, event_file_id: object_id, log_lvl });
            if (object_type == 'event_location') load_ae_obj_id__event_location({ api_cfg, event_location_id: object_id, log_lvl });
            if (object_type == 'event_presentation') load_ae_obj_id__event_presentation({ api_cfg, event_presentation_id: object_id, log_lvl });
            if (object_type == 'event_presenter') load_ae_obj_id__event_presenter({ api_cfg, event_presenter_id: object_id, log_lvl });
            if (object_type == 'event_session') load_ae_obj_id__event_session({ api_cfg, event_session_id: object_id, log_lvl });
            if (object_type == 'post') load_ae_obj_id__post({ api_cfg, post_id: object_id, log_lvl });
            if (object_type == 'post_comment') load_ae_obj_id__post_comment({ api_cfg, post_comment_id: object_id, log_lvl });
        }
    } else {
        if (log_lvl) {
            console.log(`PATCH failed for ${object_type} ${object_id}`);
        }
    }

    return results;
}

async function download_export__obj_type({
    api_cfg,
    get_obj_type, // The type of object to return: event_badge, event_presenter, sponsorship, etc.
    for_obj_type, // Usually for an account, event, event_exhibit, or sponsorship_cfg
    for_obj_id, // The ID of the object
    exp_alt = null, // Export name (idaa, other, not 'default')
    file_type = 'CSV', // 'CSV' or 'Excel'
    return_file = true,
    filename = 'no_filename.csv',
    auto_download = false,
    limit = 5000,
    params = {}, // key value object is expected
    log_lvl = 0
}: {
    api_cfg: any;
    get_obj_type: string;
    for_obj_type: string;
    for_obj_id: string;
    exp_alt?: null | string;
    file_type?: string;
    return_file?: boolean;
    filename?: string;
    auto_download?: boolean;
    limit?: number;
    params?: key_val;
    log_lvl?: number;
}) {
    console.log('*** ae_core_functions.js: download_export__obj_type() ***');

    const task_id = for_obj_id;

    const endpoint = `/v2/crud/${get_obj_type}/list`;
    params['for_obj_type'] = for_obj_type;
    params['for_obj_id'] = for_obj_id;

    if (file_type == 'CSV' || file_type == 'Excel') {
        params['file_type'] = file_type;
    }
    params['return_file'] = true;

    params['mdl_alt'] = 'out';

    if (exp_alt) {
        params['exp_alt'] = exp_alt;
    }

    // let clean_filename = filename.replace(/[^a-z0-9]/gi, '_');
    // let clean_filename = filename.replace(/[^a-z0-9\[\]-]/gi, '_');
    const clean_filename = filename.replace(/[^a-zA-Z0-9\[\]-_.]/gi, '_');
    // let clean_filename = filename.replace(/[^a-zA-Z0-9\[\]-\._ ]/gi, '_');

    if (limit >= 0) {
        params['limit'] = limit;
    }

    ae_promises.download__export_file = await api.get_object({
        api_cfg: api_cfg,
        endpoint: endpoint,
        params: params,
        timeout: 90000, // Seems to timeout sometimes with the default of 60 seconds
        return_blob: return_file,
        filename: clean_filename,
        auto_download: auto_download,
        task_id: task_id,
        log_lvl: log_lvl
    });

    console.log('ae_promises.download__export_file:', ae_promises.download__export_file);
    return ae_promises.download__export_file;
}

const export_obj = {
    check_hosted_file_obj_w_hash: check_hosted_file_obj_w_hash,

    load_ae_obj_li__time_zone: load_ae_obj_li__time_zone,

    load_ae_obj_li__country: load_ae_obj_li__country,
    load_ae_obj_li__country_subdivision: load_ae_obj_li__country_subdivision,

    load_ae_obj_id__hosted_file: load_ae_obj_id__hosted_file,
    load_ae_obj_li__hosted_file: load_ae_obj_li__hosted_file,
    delete_ae_obj_id__hosted_file: delete_ae_obj_id__hosted_file,

    db_save_ae_obj_li__ae_obj: db_save_ae_obj_li__ae_obj,

    add_url_params: add_url_params,
    clean_headers: clean_headers,

    load_ae_obj_id__site_domain: load_ae_obj_id__site_domain,
    load_ae_obj_code__data_store: load_ae_obj_code__data_store,

    load_ae_obj_id__activity_log: load_ae_obj_id__activity_log,
    load_ae_obj_li__activity_log: load_ae_obj_li__activity_log,
    create_ae_obj__activity_log: create_ae_obj__activity_log,
    update_ae_obj__activity_log: update_ae_obj__activity_log,

    load_ae_obj_id__person: load_ae_obj_id__person,
    load_ae_obj_li__person: load_ae_obj_li__person,
    create_ae_obj__person: create_ae_obj__person,
    delete_ae_obj_id__person: delete_ae_obj_id__person,
    update_ae_obj__person: update_ae_obj__person,

    auth_ae_obj__username_password: auth_ae_obj__username_password,
    auth_ae_obj__user_id_user_auth_key: auth_ae_obj__user_id_user_auth_key,
    send_email_auth_ae_obj__user_id: send_email_auth_ae_obj__user_id,
    qry_ae_obj_li__user_email: qry_ae_obj_li__user_email,
    auth_ae_obj__user_id_change_password: auth_ae_obj__user_id_change_password,

    update_ae_obj_id_crud: update_ae_obj_id_crud,
    update_ae_obj_id_crud_v2: update_ae_obj_id_crud_v2,
    download_export__obj_type: download_export__obj_type,
    generate_qr_code: generate_qr_code,
    js_generate_qr_code: js_generate_qr_code
};
export const core_func = export_obj;
