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

import { db_save_ae_obj_li__ae_obj } from '$lib/ae_core/core__idb_dexie';
import { db_events } from '$lib/ae_events/db_events';

import { load_ae_obj_li__event_device } from './ae_events__event_device';
import { load_ae_obj_li__event_location } from './ae_events__event_location';
import { load_ae_obj_li__event_session } from './ae_events__event_session';
import { load_ae_obj_li__event_badge_template } from '$lib/ae_events/ae_events__event_badge_template';

const ae_promises: key_val = {};

// Updated 2025-05-22
export async function load_ae_obj_id__event({
	api_cfg,
	event_id,
	inc_device_li = false,
	inc_file_li = false,
	inc_location_li = false,
	inc_presentation_li = false,
	inc_presenter_li = false,
	inc_session_li = false,
	inc_badge_li = false,
	inc_template_li = false, // badge templates
	try_cache = true,
	log_lvl = 0
}: {
	api_cfg: any;
	event_id: string;
	inc_device_li?: boolean;
	inc_file_li?: boolean;
	inc_location_li?: boolean;
	inc_presentation_li?: boolean;
	inc_presenter_li?: boolean;
	inc_session_li?: boolean;
	inc_badge_li?: boolean;
	inc_template_li?: boolean;
	try_cache?: boolean;
	log_lvl?: number;
}) {
	if (log_lvl) {
		console.log(`*** load_ae_obj_id__event() *** event_id=${event_id}`);
	}

	const params = {};

	ae_promises.load__event_obj = await api
		.get_ae_obj_id_crud({
			api_cfg: api_cfg,
			obj_type: 'event',
			obj_id: event_id,
			use_alt_table: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
			use_alt_base: false, // NOTE: This will use the base_name_alt value instead of the base_name value in the API config.
			params: params,
			log_lvl: log_lvl
		})
		.then(async function (event_obj_get_result) {
			if (event_obj_get_result) {
				if (try_cache) {
					// Process the results first
					const processed_obj_li = await process_ae_obj__event_props({
						obj_li: [event_obj_get_result],
						log_lvl: log_lvl
					});
					if (log_lvl) {
						console.log('Processed object list:', processed_obj_li);
					}
					// Save the updated results list to the database
					if (log_lvl) {
						console.log('Saving to DB...');
					}
					await db_save_ae_obj_li__ae_obj({
						db_instance: db_events,
						table_name: 'event',
						obj_li: processed_obj_li,
						properties_to_save: properties_to_save,
						log_lvl: log_lvl
					});
					if (log_lvl) {
						console.log('DB save completed.');
					}
				}
				return event_obj_get_result;
			} else {
				console.log('No results returned.');
				return null;
			}
		})
		.catch(function (error: any) {
			console.log('No results returned or failed.', error);
		});

	if (log_lvl) {
		console.log('ae_promises.load__event_obj:', ae_promises.load__event_obj);
	}

	if (inc_device_li) {
		// Load the devices for the event
		if (log_lvl) {
			console.log(`Need to load the device list for the event now`);
		}
		const load_event_device_obj_li = load_ae_obj_li__event_device({
			api_cfg: api_cfg,
			for_obj_type: 'event',
			for_obj_id: event_id,
			params: { qry__enabled: 'enabled', qry__limit: 49 },
			try_cache: try_cache,
			log_lvl: log_lvl
		}).then((event_device_obj_li) => {
			if (log_lvl) {
				console.log(`event_device_obj_li = `, event_device_obj_li);
			}
			return event_device_obj_li;
		});

		if (log_lvl) {
			console.log(`load_event_device_obj_li = `, load_event_device_obj_li);
		}
		ae_promises.load__event_obj.event_device_obj_li = load_event_device_obj_li;
	}

	if (inc_location_li) {
		// Load the locations for the event
		if (log_lvl) {
			console.log(`Need to load the location list for the event now`);
		}
		const load_event_location_obj_li = load_ae_obj_li__event_location({
			api_cfg: api_cfg,
			for_obj_type: 'event',
			for_obj_id: event_id,
			enabled: 'enabled',
			limit: 19,
			log_lvl: log_lvl
		}).then((event_location_obj_li) => {
			if (log_lvl) {
				console.log(`event_location_obj_li = `, event_location_obj_li);
			}
			return event_location_obj_li;
		});

		if (log_lvl) {
			console.log(`load_event_location_obj_li = `, load_event_location_obj_li);
		}
		ae_promises.load__event_obj.event_location_obj_li = load_event_location_obj_li;
	}

	if (inc_session_li) {
		// Load the sessions for the events
		if (log_lvl) {
			console.log(`Need to load the session list for the event now`);
		}
		const load_event_session_obj_li = load_ae_obj_li__event_session({
			api_cfg: api_cfg,
			for_obj_type: 'event',
			for_obj_id: event_id,
			enabled: 'enabled',
			limit: 249,
			try_cache: try_cache,
			log_lvl: log_lvl
		}).then((event_session_obj_li) => {
			if (log_lvl) {
				console.log(`event_session_obj_li = `, event_session_obj_li);
			}
			return event_session_obj_li;
		});

		if (log_lvl) {
			console.log(`load_event_session_obj_li = `, load_event_session_obj_li);
		}
		ae_promises.load__event_obj.event_session_obj_li = load_event_session_obj_li;
	}

	if (inc_template_li) {
		// Load the badge templates for the event
		log_lvl = 2;
		if (log_lvl) {
			console.log(`Need to load the badge template list for the event now`);
		}
		const load_event_badge_template_obj_li = load_ae_obj_li__event_badge_template({
			api_cfg: api_cfg,
			// for_obj_type: 'event',
			// for_obj_id: event_id,
			event_id: event_id,
			enabled: 'enabled',
			limit: 19,
			try_cache: try_cache,
			log_lvl: log_lvl
		}).then((event_badge_template_obj_li) => {
			if (log_lvl) {
				console.log(`event_badge_template_obj_li = `, event_badge_template_obj_li);
			}
			return event_badge_template_obj_li;
		});
		if (log_lvl) {
			console.log(`load_event_badge_template_obj_li = `, load_event_badge_template_obj_li);
		}
		ae_promises.load__event_obj.event_badge_template_obj_li = load_event_badge_template_obj_li;
	}

	return ae_promises.load__event_obj;
}

// Updated 2025-05-22
export async function load_ae_obj_li__event({
	api_cfg,
	for_obj_type = 'account',
	for_obj_id,
	qry_conference = true,
	qry_str = null,
	inc_device_li = false,
	inc_file_li = false,
	inc_location_li = false,
	inc_presentation_li = false,
	inc_presenter_li = false,
	inc_session_li = false,
	enabled = 'enabled',
	hidden = 'not_hidden',
	limit = 99,
	offset = 0,
	order_by_li = { start_datetime: 'DESC', name: 'ASC', updated_on: 'DESC', created_on: 'DESC' },
	params_json = null,
	params = {},
	try_cache = true,
	log_lvl = 0
}: {
	api_cfg: any;
	for_obj_type: string;
	for_obj_id: string;
	qry_conference?: null | boolean;
	qry_str?: null | string;
	inc_device_li?: boolean;
	inc_file_li?: boolean;
	inc_location_li?: boolean;
	inc_presentation_li?: boolean;
	inc_presenter_li?: boolean;
	inc_session_li?: boolean;
	enabled?: 'enabled' | 'all' | 'not_enabled' | undefined;
	hidden?: 'hidden' | 'all' | 'not_hidden' | undefined;
	limit?: number;
	offset?: number;
	order_by_li?: key_val;
	params_json?: null | key_val;
	params?: key_val;
	try_cache?: boolean;
	log_lvl?: number;
}) {
	if (log_lvl) {
		console.log(
			`*** load_ae_obj_li__event() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id} qry_conference=${qry_conference}`
		);
	}

	// There is probably a better way to handle this. I don't want to just start a new object if it is not passed. However, the qry_conference and qry_str are sort of a special case. -2024-10-01
	if (!params_json) {
		params_json = {};
	}

	if (qry_conference) {
		if (!params_json['and_qry']) {
			params_json['and_qry'] = {};
		}

		params_json['and_qry']['conference'] = qry_conference;
	} else if (qry_conference === false) {
		if (!params_json['and_qry']) {
			params_json['and_qry'] = {};
		}

		if (log_lvl) {
			console.log('qry_conference is false!');
		}
		params_json['and_qry']['conference'] = qry_conference;
	}

	if (qry_str) {
		if (!params_json['ft_qry']) {
			params_json['ft_qry'] = {};
		}

		params_json['ft_qry'] = {};
		params_json['ft_qry']['default_qry_str'] = qry_str;
		params_json['ft_qry']['location_address_json_ext'] = qry_str;
		params_json['ft_qry']['contact_li_json_ext'] = qry_str;
	}

	// console.log('params_json:', params_json);

	ae_promises.load__event_obj_li = await api
		.get_ae_obj_li_for_obj_id_crud_v2({
			api_cfg: api_cfg,
			obj_type: 'event',
			for_obj_type: for_obj_type,
			for_obj_id: for_obj_id,
			use_alt_tbl: true, // NOTE: This will use the table_name_alt value instead of the table_name value in the API config.
			// use_alt_mdl: false, // NOTE: This will use the base_name_alt value instead of the base_name value
			enabled: enabled,
			hidden: hidden,
			order_by_li: order_by_li,
			limit: limit,
			offset: offset,
			params_json: params_json,
			params: params,
			log_lvl: log_lvl
		})
		.then(async function (event_obj_li_get_result) {
			if (event_obj_li_get_result) {
				if (try_cache) {
					// Process the results first
					const processed_obj_li = await process_ae_obj__event_props({
						obj_li: event_obj_li_get_result,
						log_lvl: log_lvl
					});
					if (log_lvl) {
						console.log('Processed object list:', processed_obj_li);
					}
					// Save the updated results list to the database
					if (log_lvl) {
						console.log('Saving to DB...');
					}
					await db_save_ae_obj_li__ae_obj({
						db_instance: db_events,
						table_name: 'event',
						obj_li: processed_obj_li,
						properties_to_save: properties_to_save,
						log_lvl: log_lvl
					});
					if (log_lvl) {
						console.log('DB save completed.');
					}
				}
				return event_obj_li_get_result;
			} else {
				return [];
			}
		})
		.catch(function (error: any) {
			console.log('No results returned or failed.', error);
		});

	if (log_lvl) {
		console.log('ae_promises.load__event_obj_li:', ae_promises.load__event_obj_li);
	}

	if (inc_device_li) {
		// Load the devices for the events
		if (log_lvl) {
			console.log(`Need to load the device list for each event now`);
		}
		for (let i = 0; i < ae_promises.load__event_obj_li.length; i++) {
			const event_obj = ae_promises.load__event_obj_li[i];
			const event_id = event_obj.event_id_random;

			const load_event_device_obj_li = load_ae_obj_li__event_device({
				api_cfg: api_cfg,
				for_obj_type: 'event',
				for_obj_id: event_id,
				params: { qry__enabled: 'enabled', qry__limit: 49 },
				try_cache: try_cache,
				log_lvl: log_lvl
			}).then((event_device_obj_li) => {
				if (log_lvl) {
					console.log(`event_device_obj_li = `, event_device_obj_li);
				}

				return event_device_obj_li;
			});

			if (log_lvl) {
				console.log(`load_event_device_obj_li = `, load_event_device_obj_li);
			}

			if (load_event_device_obj_li) {
				ae_promises.load__event_obj_li[i].event_device_obj_li = load_event_device_obj_li;
			}
		}
	}

	if (inc_location_li) {
		// Load the locations for the events
		if (log_lvl) {
			console.log(`Need to load the location list for each event now`);
		}
		for (let i = 0; i < ae_promises.load__event_obj_li.length; i++) {
			const event_obj = ae_promises.load__event_obj_li[i];
			const event_id = event_obj.event_id_random;

			const load_event_location_obj_li = load_ae_obj_li__event_location({
				api_cfg: api_cfg,
				for_obj_type: 'event',
				for_obj_id: event_id,
				enabled: 'enabled',
				limit: 19,
				try_cache: try_cache,
				log_lvl: log_lvl
			}).then((event_location_obj_li) => {
				if (log_lvl) {
					console.log(`event_location_obj_li = `, event_location_obj_li);
				}

				return event_location_obj_li;
			});

			if (log_lvl) {
				console.log(`load_event_location_obj_li = `, load_event_location_obj_li);
			}

			if (load_event_location_obj_li) {
				ae_promises.load__event_obj_li[i].event_location_obj_li = load_event_location_obj_li;
			}
		}
	}

	if (inc_session_li) {
		// Load the sessions for the events
		if (log_lvl) {
			console.log(`Need to load the session list for each event now`);
		}
		for (let i = 0; i < ae_promises.load__event_obj_li.length; i++) {
			const event_obj = ae_promises.load__event_obj_li[i];
			const event_id = event_obj.event_id_random;

			const load_event_session_obj_li = load_ae_obj_li__event_session({
				api_cfg: api_cfg,
				for_obj_type: 'event',
				for_obj_id: event_id,
				enabled: enabled,
				hidden: hidden,
				limit: limit,
				offset: offset,
				order_by_li: order_by_li,
				params: params,
				try_cache: try_cache,
				log_lvl: log_lvl
			}).then((event_session_obj_li) => {
				if (log_lvl) {
					console.log(`event_session_obj_li = `, event_session_obj_li);
				}

				return event_session_obj_li;
			});

			if (log_lvl) {
				console.log(`load_event_session_obj_li = `, load_event_session_obj_li);
			}

			if (load_event_session_obj_li) {
				ae_promises.load__event_obj_li[i].event_session_obj_li = load_event_session_obj_li;
			}
		}
	}

	return ae_promises.load__event_obj_li;
}

// The qry_ae_obj_li__event() is essentially a wrapper for the load_ae_obj_li__event() function. This should process the query strings and related before calling the load_ae_obj_li__event() function.
// Updated 2024-10-01
export async function qry_ae_obj_li__event({
	api_cfg,
	for_obj_type = 'account',
	for_obj_id,
	qry_conference = true,
	qry_physical = null,
	qry_virtual = null,
	qry_type = null,
	qry_str = null,
	inc_file_li = false,
	inc_location_li = false,
	inc_presentation_li = false,
	inc_presenter_li = false,
	inc_session_li = false,
	enabled = 'enabled', // all, disabled, enabled
	hidden = 'not_hidden', // all, hidden, not_hidden
	limit = 99,
	offset = 0,
	order_by_li = { start_datetime: 'DESC', name: 'ASC', updated_on: 'DESC', created_on: 'DESC' },
	params = {},
	try_cache = true,
	log_lvl = 0
}: {
	api_cfg: any;
	for_obj_type: string;
	for_obj_id: string;
	qry_conference?: null | boolean;
	qry_physical?: null | boolean;
	qry_virtual?: null | boolean;
	qry_type?: null | string;
	qry_str?: null | string;
	inc_file_li?: boolean;
	inc_location_li?: boolean;
	inc_presentation_li?: boolean;
	inc_presenter_li?: boolean;
	inc_session_li?: boolean;
	enabled?: 'enabled' | 'all' | 'not_enabled' | undefined;
	hidden?: 'hidden' | 'all' | 'not_hidden' | undefined;
	limit?: number;
	offset?: number;
	order_by_li?: key_val;
	params?: key_val;
	try_cache?: boolean;
	log_lvl?: number;
}) {
	if (log_lvl) {
		console.log(
			`*** qry_ae_obj_li__event() *** for_obj_type=${for_obj_type} for_obj_id=${for_obj_id}`
		);
	}

	// Build the params_json object. This needs to be documented better! -2024-10-01
	const params_json: key_val = {};

	params_json['and_qry'] = {};

	// This is handled in the actual load_ae_obj_li__event() function. For now...?
	// if (qry_conference) {
	//     params_json['and_qry']['conference'] = qry_conference;
	// } else if (qry_conference === false) {
	//     console.log('qry_conference is false!');
	//     params_json['and_qry']['conference'] = qry_conference;
	// }

	if (qry_physical && qry_virtual) {
		// Ignore both if both are set to true.
	} else if (qry_physical || qry_virtual) {
		if (qry_physical) {
			params_json['and_qry']['physical'] = qry_physical;
		}
		if (qry_virtual) {
			params_json['and_qry']['virtual'] = qry_virtual;
		}
	}

	if (qry_type) {
		params_json['and_qry']['type'] = qry_type;
	}

	if (qry_str) {
		params_json['ft_qry'] = {};
		params_json['ft_qry']['default_qry_str'] = qry_str;
		params_json['ft_qry']['location_address_json_ext'] = qry_str;
		params_json['ft_qry']['contact_li_json_ext'] = qry_str;
	}

	if (log_lvl) {
		console.log('params_json:', params_json);
	}

	ae_promises.qry__event_obj_li = await load_ae_obj_li__event({
		api_cfg: api_cfg,
		for_obj_type: for_obj_type,
		for_obj_id: for_obj_id,
		qry_conference: qry_conference,
		qry_str: qry_str,
		inc_file_li: inc_file_li,
		inc_location_li: inc_location_li,
		inc_presentation_li: inc_presentation_li,
		inc_presenter_li: inc_presenter_li,
		inc_session_li: inc_session_li,
		enabled: enabled,
		hidden: hidden,
		limit: limit,
		offset: offset,
		order_by_li: order_by_li,
		params_json: params_json,
		params: params,
		try_cache: try_cache,
		log_lvl: log_lvl
	});

	return ae_promises.qry__event_obj_li;
}

// Updated 2025-07-11
export async function create_ae_obj__event({
	api_cfg,
	account_id,
	data_kv,
	params = {},
	try_cache = true,
	log_lvl = 0
}: {
	api_cfg: any;
	account_id: string;
	data_kv: key_val;
	params?: key_val;
	try_cache?: boolean;
	log_lvl?: number;
}) {
	if (log_lvl) {
		console.log(`*** create_ae_obj__event() *** account_id=${account_id}`);
	}

	if (!account_id) {
		console.log(`ERROR: Events - Event - account_id required to create`);
		return false;
	}

	ae_promises.create__event = await api
		.create_ae_obj_crud({
			api_cfg: api_cfg,
			obj_type: 'event',
			fields: {
				account_id_random: account_id,
				...data_kv
			},
			key: api_cfg.api_crud_super_key,
			params: params,
			return_obj: true,
			log_lvl: log_lvl
		})
		.then(async function (event_obj_create_result) {
			if (event_obj_create_result) {
				if (try_cache) {
					// Process the results first
					const processed_obj_li = await process_ae_obj__event_props({
						obj_li: [event_obj_create_result],
						log_lvl: log_lvl
					});
					if (log_lvl) {
						console.log('Processed object list:', processed_obj_li);
					}
					// Save the updated results list to the database
					if (log_lvl) {
						console.log('Saving to DB...');
					}
					db_save_ae_obj_li__ae_obj({
						db_instance: db_events,
						table_name: 'event',
						obj_li: processed_obj_li,
						properties_to_save: properties_to_save,
						log_lvl: log_lvl
					});
					if (log_lvl) {
						console.log('DB save completed.');
					}
				}
				return event_obj_create_result;
			} else {
				return null;
			}
		})
		.catch(function (error: any) {
			console.log('No results returned or failed.', error);
		})
		.finally(function () {});

	if (log_lvl) {
		console.log('ae_promises.create__event:', ae_promises.create__event);
	}
	return ae_promises.create__event;
}

// Updated 2024-11-08
export async function delete_ae_obj_id__event({
	api_cfg,
	event_id,
	method = 'delete', // 'delete', 'disable', 'hide'
	params = {},
	try_cache = true,
	log_lvl = 0
}: {
	api_cfg: any;
	event_id: string;
	method?: string;
	params?: key_val;
	try_cache?: boolean;
	log_lvl?: number;
}) {
	if (log_lvl) {
		console.log(`*** delete_ae_obj_id__event() *** event_id=${event_id}`);
	}

	ae_promises.delete__event_obj = await api
		.delete_ae_obj_id_crud({
			api_cfg: api_cfg,
			obj_type: 'event',
			obj_id: event_id,
			key: api_cfg.api_crud_super_key,
			params: params,
			method: method,
			log_lvl: log_lvl
		})
		.catch(function (error: any) {
			console.log('No results returned or failed.', error);
		})
		.finally(function () {
			if (try_cache) {
				if (log_lvl) {
					console.log(`Attempting to remove IDB entry for event_id=${event_id}`);
				}
				db_events.event.delete(event_id); // Delete from the DB no matter what.
			}
		});

	if (log_lvl) {
		console.log('ae_promises.delete__event_obj:', ae_promises.delete__event_obj);
	}

	return ae_promises.delete__event_obj;
}

// Updated 2024-09-25
export async function update_ae_obj__event({
	api_cfg,
	event_id,
	data_kv,
	params = {},
	try_cache = true,
	log_lvl = 0
}: {
	api_cfg: any;
	event_id: string;
	data_kv: key_val;
	params?: key_val;
	try_cache?: boolean;
	log_lvl?: number;
}) {
	if (log_lvl) {
		console.log(`*** update_ae_obj__event() *** event_id=${event_id}`, data_kv);
	}
	// ae_promises.update__event_obj = 'test';
	ae_promises.update__event_obj = await api
		.update_ae_obj_id_crud({
			api_cfg: api_cfg,
			obj_type: 'event',
			obj_id: event_id,
			fields: data_kv,
			key: api_cfg.api_crud_super_key,
			params: params,
			return_obj: true,
			log_lvl: log_lvl
		})
		.then(async function (event_obj_update_result) {
			if (event_obj_update_result) {
				if (try_cache) {
					// Process the results first
					const processed_obj_li = await process_ae_obj__event_props({
						obj_li: [event_obj_update_result],
						log_lvl: log_lvl
					});
					if (log_lvl) {
						console.log('Processed object list:', processed_obj_li);
					}
					// Save the updated results list to the database
					if (log_lvl) {
						console.log('Saving to DB...');
					}
					db_save_ae_obj_li__ae_obj({
						db_instance: db_events,
						table_name: 'event',
						obj_li: processed_obj_li,
						properties_to_save: properties_to_save,
						log_lvl: log_lvl
					});
					if (log_lvl) {
						console.log('DB save completed.');
					}
				}
				return event_obj_update_result;
			} else {
				return null;
			}
		})
		.catch(function (error: any) {
			console.log('No results returned or failed.', error);
		})
		.finally(function () {});

	if (log_lvl) {
		console.log('ae_promises.update__event_obj:', ae_promises.update__event_obj);
	}
	return ae_promises.update__event_obj;
}

// This function will loop through the event_obj_li and save each one to the DB.
// Updated 2025-05-09
export async function db_save_ae_obj_li__event({
	obj_type,
	obj_li,
	log_lvl = 0
}: {
	obj_type: string;
	obj_li: any;
	log_lvl?: number;
}) {
	if (log_lvl) {
		console.log(`*** db_save_ae_obj_li__event() *** obj_type=${obj_type}`, obj_li);
	}

	if (obj_li && obj_li.length) {
		const obj_li_id: string[] = [];

		for (const obj of obj_li) {
			if (log_lvl) {
				console.log(`Processing ae_obj ${obj_type}:`, obj);
			}

			const obj_record = {
				id: obj.event_id_random,
				event_id: obj.event_id_random,
				event_id_random: obj.event_id_random,

				code: obj.event_code,

				account_id: obj.account_id_random,
				account_id_random: obj.account_id_random,

				conference: obj.conference,
				type: obj.type,
				name: obj.name,
				summary: obj.summary,
				description: obj.description,

				start_datetime: obj.start_datetime,
				end_datetime: obj.end_datetime,
				timezone: obj.timezone,
				location_address_json: obj.location_address_json,
				location_text: obj.location_text,

				attend_json: obj.attend_json,
				attend_text: obj.attend_text,

				status: obj.status, // draft, active, inactive, archived, unknown; currently only used with IDAA
				// review: obj.review,
				// approve: obj.approve,
				// ready: obj.ready,
				// ready_on: obj.ready_on,
				// archive: obj.archive,
				// archive_on: obj.archive_on,

				mod_abstracts_json: obj.mod_abstracts_json,
				mod_badges_json: obj.mod_badges_json,
				mod_exhibits_json: obj.mod_exhibits_json,
				mod_meetings_json: obj.mod_meetings_json,
				mod_pres_mgmt_json: obj.mod_pres_mgmt_json,
				cfg_json: obj.cfg_json,

				enable: obj.enable,
				hide: obj.hide,
				priority: obj.priority,
				sort: obj.sort,
				group: obj.group,
				notes: obj.notes,
				created_on: obj.created_on,
				updated_on: obj.updated_on,

				// IDAA Recovery Meetings:
				// Currently only really used for IDAA
				contact_li_json: obj.contact_li_json,
				external_person_id: obj.external_person_id,

				physical: obj.physical,
				virtual: obj.virtual,

				recurring: obj.recurring,
				recurring_pattern: obj.recurring_pattern,
				recurring_start_time: obj.recurring_start_time,
				recurring_end_time: obj.recurring_end_time,
				recurring_text: obj.recurring_text,

				weekday_sunday: obj.weekday_sunday,
				weekday_monday: obj.weekday_monday,
				weekday_tuesday: obj.weekday_tuesday,
				weekday_wednesday: obj.weekday_wednesday,
				weekday_thursday: obj.weekday_thursday,
				weekday_friday: obj.weekday_friday,
				weekday_saturday: obj.weekday_saturday,

				attend_url: obj.attend_url,
				attend_url_text: obj.attend_url_text,
				attend_url_code: obj.attend_url_code,
				attend_url_passcode: obj.attend_url_passcode,
				attend_phone: obj.attend_phone,
				attend_phone_passcode: obj.attend_phone_passcode,

				// From SQL view
				file_count: obj.file_count,
				file_count_all: obj.file_count_all,
				internal_use_count: obj.internal_use_count,
				event_file_id_li_json: obj.event_file_id_li_json
			};

			let id_random = null;

			try {
				id_random = await db_events.event.update(obj_record.id, obj_record);
			} catch (error) {
				console.error(`Error: Failed to update ${obj_record.id}: ${error}`);
			}

			if (!id_random) {
				if (log_lvl) {
					console.log(`Failed to update record with ID: ${obj_record.id}. Trying put...`);
				}
				try {
					id_random = await db_events.event.put(obj_record);
				} catch (error) {
					console.error(`Error: Failed to put ${obj.event_id_random}: ${error}`);
				}
			} else {
				if (log_lvl) {
					console.log(`Updated record with ID: ${obj_record.id}`);
				}
			}

			if (!id_random) {
				console.error(`Failed to save record with ID: ${obj_record.id}`);
			} else {
				if (log_lvl) {
					console.log(`Saved record with ID: ${obj_record.id}`);
				}
				obj_li_id.push(obj_record.id);
			}
		}
		return obj_li_id;
	}
}

// This function will process the event config, specifically for presentation management.
export function sync_config__event_pres_mgmt({
	pres_mgmt_cfg_remote, // This is the remote config that will be compared.
	pres_mgmt_cfg_local, // This is the local config that will be updated.
	log_lvl = 0
}: {
	pres_mgmt_cfg_remote: key_val;
	pres_mgmt_cfg_local: key_val;
	log_lvl?: number;
}) {
	log_lvl = 1;
	if (log_lvl) {
		console.log(
			`*** sync_config__event_pres_mgmt() *** pres_mgmt_cfg_remote:`,
			pres_mgmt_cfg_remote
		);
	}

	// Deal with things that can not be overridden first:
	// Labels:
	pres_mgmt_cfg_local.label__person_external_id =
		pres_mgmt_cfg_remote?.label__person_external_id ?? 'External ID';
	pres_mgmt_cfg_local.label__presenter_external_id =
		pres_mgmt_cfg_remote?.label__presenter_external_id ?? 'External ID';

	pres_mgmt_cfg_local.label__session_poc_type =
		pres_mgmt_cfg_remote?.label__session_poc_type ?? 'poc';
	pres_mgmt_cfg_local.label__session_poc_name =
		pres_mgmt_cfg_remote?.label__session_poc_name_short ?? 'POC';
	pres_mgmt_cfg_local.label__session_poc_name =
		pres_mgmt_cfg_remote?.label__session_poc_name ?? 'Point of Contact';

	// Hide content:

	pres_mgmt_cfg_local.hide__session_poc = pres_mgmt_cfg_remote?.hide__session_poc ?? false;

	// pres_mgmt_cfg_local.hide__report_kv = pres_mgmt_cfg_remote?.hide__report_kv ?? null;

	// pres_mgmt_cfg_local.limit__navigation = pres_mgmt_cfg_remote?.limit__navigation ?? false;
	// pres_mgmt_cfg_local.limit__options = pres_mgmt_cfg_remote?.limit__options ?? false;

	// Required fields or options (agreements):
	pres_mgmt_cfg_local.require__presenter_agree =
		pres_mgmt_cfg_remote?.require__presenter_agree ?? false; // In use
	pres_mgmt_cfg_local.require__session_agree =
		pres_mgmt_cfg_remote?.require__session_agree ?? false; // New and in progress

	// Show content:
	// pres_mgmt_cfg_local.show__navigation = pres_mgmt_cfg_remote?.show__navigation ?? false;

	pres_mgmt_cfg_local.show__copy_access_link =
		pres_mgmt_cfg_remote?.show__copy_access_link ?? false;
	pres_mgmt_cfg_local.show__email_access_link =
		pres_mgmt_cfg_remote?.show__email_access_link ?? false;

	pres_mgmt_cfg_local.file_purpose_option_kv = pres_mgmt_cfg_remote?.file_purpose_option_kv ?? null;

	// Deal with things that can be overridden:

	// Locking the config is targeted at the trusted staff level and below. It is more or less ignored at the global manager and super levels. It may be enforced at the staff admin level?
	// pres_mgmt_cfg_local.lock_config = pres_mgmt_cfg_remote?.lock_config ? true : false; // This disables the sync local config button and options.
	if (pres_mgmt_cfg_local.lock_config) {
		console.log(`The config should be locked! Forcing the sync!`);
		// This is to forcibly sync the local config with the remote config.
		pres_mgmt_cfg_local.sync_local_config = true;
	} else {
		// Do not override the preference for syncing the local config with the remote config.
		console.log(
			`The config is not locked. Currently set to sync? ${pres_mgmt_cfg_local.sync_local_config}`
		);

		// Check if the sync_local_config is undefined versus just false.
		// if (pres_mgmt_cfg_local?.sync_local_config) {
		//     pres_mgmt_cfg_local.sync_local_config = true;
		// } else {
		//     pres_mgmt_cfg_local.sync_local_config = pres_mgmt_cfg_remote?.sync_local_config ?? false;
		// }
	}

	if (pres_mgmt_cfg_local?.sync_local_config) {
		if (log_lvl) {
			console.log(`Syncing the local config with the remote config!!!`);
		}
		// Hide content:
		pres_mgmt_cfg_local.hide__location_code = pres_mgmt_cfg_remote?.hide__location_code ?? false;

		pres_mgmt_cfg_local.hide__presentation_code =
			pres_mgmt_cfg_remote?.hide__presentation_code ?? false;
		pres_mgmt_cfg_local.hide__presentation_datetime =
			pres_mgmt_cfg_remote?.hide__presentation_datetime ?? false;
		pres_mgmt_cfg_local.show_content__presentation_description =
			pres_mgmt_cfg_remote?.show_content__presentation_description ?? false;

		pres_mgmt_cfg_local.hide__presenter_code = pres_mgmt_cfg_remote?.hide__presenter_code ?? false;
		pres_mgmt_cfg_local.hide__presenter_biography =
			pres_mgmt_cfg_remote?.hide__presenter_biography ?? false;

		pres_mgmt_cfg_local.hide__session_code = pres_mgmt_cfg_remote?.hide__session_code ?? false;
		pres_mgmt_cfg_local.hide__session_description =
			pres_mgmt_cfg_remote?.hide__session_description ?? false;
		pres_mgmt_cfg_local.hide__session_location =
			pres_mgmt_cfg_remote?.hide__session_location ?? false;
		pres_mgmt_cfg_local.hide__session_msg = pres_mgmt_cfg_remote?.hide__session_msg ?? false;

		// pres_mgmt_cfg_local.hide__session_li_poc_field = pres_mgmt_cfg_remote?.hide__session_li_poc_field ?? false; // This should still allow the POC name to be shown.
		pres_mgmt_cfg_local.hide__session_poc_profile =
			pres_mgmt_cfg_remote?.hide__session_poc_profile ?? false; // This should still allow the POC name to be shown.
		pres_mgmt_cfg_local.hide__session_poc_biography =
			pres_mgmt_cfg_remote?.hide__session_poc_biography ?? false; // New and in progress
		pres_mgmt_cfg_local.hide__session_poc_profile_pic =
			pres_mgmt_cfg_remote?.hide__session_poc_profile_pic ?? false; // New and in progress

		// pres_mgmt_cfg_local.show__copy_access_link = pres_mgmt_cfg_remote?.show__copy_access_link ?? false;
		// pres_mgmt_cfg_local.show__email_access_link = pres_mgmt_cfg_remote?.show__email_access_link ?? false;
		// pres_mgmt_cfg_local.show__launcher_link = pres_mgmt_cfg_remote?.show__launcher_link ?? false;
		// pres_mgmt_cfg_local.show__launcher_link_legacy = pres_mgmt_cfg_remote?.show__launcher_link_legacy ?? false;

		pres_mgmt_cfg_local.hide_launcher_link = pres_mgmt_cfg_remote?.hide_launcher_link ?? false;
		pres_mgmt_cfg_local.hide_launcher_link_legacy =
			pres_mgmt_cfg_remote?.hide_launcher_link_legacy ?? false;
	}

	if (log_lvl) {
		console.log(`pres_mgmt_cfg_local:`, pres_mgmt_cfg_local);
	}
	return pres_mgmt_cfg_local;
}

// Updated 2025-05-09
export const properties_to_save = [
	'id',
	'event_id',
	'event_id_random',

	'code',

	'account_id',
	'account_id_random',

	'conference',
	'type',
	'name',
	'summary',
	'description',

	'start_datetime',
	'end_datetime',
	'timezone',

	'location_address_json',
	'location_text',

	'attend_json',
	'attend_text',

	'status', // draft, active, inactive, archived, unknown; currently only used with IDAA
	// review
	// approve
	// ready
	// ready_on
	// archive
	// archive_on

	'mod_abstracts_json',
	'mod_badges_json',
	'mod_exhibits_json',
	'mod_meetings_json',
	'mod_pres_mgmt_json',
	'cfg_json',

	'enable',
	'hide',
	'priority',
	'sort',
	'group',
	'notes',
	'created_on',
	'updated_on',

	// IDAA Recovery Meetings:
	// Currently only really used for IDAA
	'contact_li_json',
	'external_person_id',

	'physical',
	'virtual',

	'recurring',
	'recurring_pattern',
	'recurring_start_time',
	'recurring_end_time',
	'recurring_text',

	'weekday_sunday',
	'weekday_monday',
	'weekday_tuesday',
	'weekday_wednesday',
	'weekday_thursday',
	'weekday_friday',
	'weekday_saturday',

	'attend_url',
	'attend_url_text',
	'attend_url_code',
	'attend_url_passcode',
	'attend_phone',
	'attend_phone_passcode',

	// Generated fields for sorting locally only
	'tmp_sort_1',
	'tmp_sort_2',
	// 'tmp_sort_a',
	// 'tmp_sort_b',

	// From SQL view
	'file_count',
	'file_count_all',
	'internal_use_count',
	'event_file_id_li_json'
	// 'event_session_count',
	// 'event_presenter_count',
	// 'event_file_count',

	// A key value list of the others
	// 'event_other_kv',
	// 'event_other_li',
];

/**
 * NON-EXPORTED LOCAL HELPER
 * Processes a list of Aether objects by applying common and specific transformations.
 */
async function _process_generic_props<T extends Record<string, any>>({
	obj_li,
	obj_type,
	log_lvl = 0,
	specific_processor
}: {
	obj_li: T[];
	obj_type: string;
	log_lvl?: number;
	specific_processor?: (obj: T) => Promise<T> | T;
}): Promise<T[]> {
	if (log_lvl > 0) {
		console.log(
			`*** _process_generic_props: Processing ${obj_li.length} objects of type "${obj_type}" ***`
		);
	}

	if (!obj_li || obj_li.length === 0) {
		if (log_lvl > 0) console.log('No objects to process.');
		return [];
	}

	const processed_obj_li: T[] = [];

	for (const original_obj of obj_li) {
		let processed_obj = { ...original_obj };

		// --- Common Transformations ---

		// 1. Standardize ID and other '_random' fields
		// The API often returns fields like 'person_id_random', which need to be aliased to 'person_id'.
		for (const key in processed_obj) {
			if (key.endsWith('_random')) {
				const newKey = key.slice(0, -7); // Remove '_random' suffix
				processed_obj[newKey] = processed_obj[key];
			}
		}
		// Ensure 'id' is set from '[obj_type]_id_random'
		const randomIdKey = `${obj_type}_id_random`;
		if (processed_obj[randomIdKey]) {
			(processed_obj as any).id = processed_obj[randomIdKey];
		}

		// 2. Create common computed properties for client-side sorting.
		const group = processed_obj.group ?? '0';
		const priority = processed_obj.priority ? 1 : 0;
		const sort = processed_obj.sort ?? '0';
		const updated = processed_obj.updated_on ?? processed_obj.created_on;
		const name = processed_obj.name ?? '';

		(processed_obj as any).tmp_sort_1 = `${group}_${priority}_${sort}_${updated}`;
		(processed_obj as any).tmp_sort_2 = `${group}_${priority}_${sort}_${name}_${updated}`;

		// --- Specific Transformations ---
		if (specific_processor) {
			processed_obj = await Promise.resolve(specific_processor(processed_obj));
		}

		processed_obj_li.push(processed_obj as T);
	}

	return processed_obj_li;
}

// Updated 2025-11-13
export async function process_ae_obj__event_props({
	obj_li,
	log_lvl = 0
}: {
	obj_li: any[];
	log_lvl?: number;
}) {
	return _process_generic_props({
		obj_li,
		obj_type: 'event',
		log_lvl,
		specific_processor: (obj) => {
			// Handle event-specific property aliases
			if (obj.event_code) {
				obj.code = obj.event_code;
			}
			return obj;
		}
	});
}
