<script lang="ts">
	// *** Import Svelte specific
	import { goto } from '$app/navigation';
	// import { tick } from 'svelte';

	import { marked } from 'marked';
	import { Modal } from 'flowbite-svelte';
	import {
		ArrowDown01,
		ArrowDown10,
		ArrowDownUp,
		BookHeart,
		Bot,
		BotMessageSquare,
		BriefcaseBusiness,
		CalendarClock,
		CalendarOff,
		Clock,
		CodeXml,
		Copy,
		Eye,
		EyeOff,
		Flag,
		FlagOff,
		FileDown,
		FilePenLine,
		FileText,
		FileX,
		Fingerprint,
		Globe,
		Group,
		Hash,
		History,
		Loader,
		LockKeyhole,
		LockKeyholeOpen,
		MessageSquareWarning,
		Menu,
		Minus,
		NotebookPen,
		NotebookText,
		NotepadTextDashed,
		Pencil,
		PenLine,
		Plus,
		RemoveFormatting,
		Save,
		Search,
		Settings,
		Shapes,
		Share2,
		ShieldCheck,
		ShieldMinus,
		Siren,
		Skull,
		SquareLibrary,
		Tags,
		Trash2,
		TypeOutline,
		X
	} from '@lucide/svelte';

	// Import OpenAI, but use it with local LLM server (ollama)
	import OpenAI from 'openai';
	// import { Configuration, OpenAIApi } from 'openai';

	let llm_api_token =
		'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVhYjI2MzdlLThiMjktNGM2Zi05MzVhLWFkYjU1MDkwMGU5MCJ9.4y5AStXZJAVnWRlgG3lVV0-xKIfMzqdNRuInGwT0ThQ';

	// let llm_api_base_url = 'http://localhost:3000/api';
	let llm_api_base_url = 'https://ai.dgrzone.com/api';
	// api_model = 'DgrZone DeepSeek (8b quick)';
	let llm_api_model = $journals_loc?.llm__api_model; // 'dgrzone-deepseek-8b-quick';

	// const configuration = new Configuration({
	//     apiKey: llm_api_token,
	// });

	// const openai = new OpenAI({
	//     apiKey: llm_api_token,
	//     baseURL: llm_api_base_url,
	// });

	// import E_app_codemirror from '$lib/e_app_codemirror.svelte';
	// import E_app_codemirror_v4 from '$lib/e_app_codemirror_v4.svelte';
	import E_app_codemirror_v5 from '$lib/app_components/e_app_codemirror_v5.svelte';
	// import {javascript} from "@codemirror/lang-javascript";
	// import {markdown} from "@codemirror/lang-markdown";

	// *** Import Aether specific variables and functions
	import type { key_val } from '$lib/stores/ae_stores';
	import { ae_util } from '$lib/ae_utils/ae_utils';
	// import { core_func } from '$lib/ae_core/ae_core_functions';
	// import { api } from '$lib/api';
	import {
		ae_snip,
		ae_loc,
		ae_sess,
		ae_api,
		ae_trig,
		slct,
		slct_trigger
	} from '$lib/stores/ae_stores';
	import {
		journals_loc,
		journals_sess,
		journals_slct,
		journals_trig,
		journals_prom
	} from '$lib/ae_journals/ae_journals_stores';
	import { journals_func } from '$lib/ae_journals/ae_journals_functions';
	import Comp_journal_entry_file_li from './ae_comp__journal_entry_obj_file_li.svelte';
	// import Comp_hosted_files_upload from '$lib/ae_core/ae_comp__hosted_files_upload.svelte';
	// import Element_manage_hosted_file_li_wrap from '$lib/element_manage_hosted_file_li_all.svelte';
	import Comp_hosted_files_download_button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';

	interface Props {
		log_lvl?: number;
		lq__journal_obj: any;
		lq__journal_obj_li: any;
		lq__journal_entry_obj: any;
	}

	let { log_lvl = 0, lq__journal_obj, lq__journal_obj_li, lq__journal_entry_obj }: Props = $props();

	if (log_lvl) {
		console.log(
			`ae_comp__journal_entry_obj_id_view.svelte`,
			lq__journal_obj,
			lq__journal_obj_li,
			lq__journal_entry_obj
		);
	}

	let ae_promises: key_val = $state({});
	// let ae_tmp: key_val = {};
	// let ae_trigger: any = null;
	// let ae_triggers: key_val = {};

	let show_menu: boolean = $state(false);

	// let orig_entry_obj: key_val = $state({});
	let orig_entry_obj: key_val | null = $state({});
	let tmp_entry_obj_changed: boolean = $state(false);
	let tmp_entry_obj: key_val | null = $state({});
	let updated_obj: boolean = $state(true); // Start with true to force population of orig and tmp values.
	let updated_idb: boolean = $state(true); // Updated in a separate browser session

	// let tmp_entry_obj: key_val = { ...$lq__journal_entry_obj };

	// let tmp_entry_obj = $derived(async () => {
	//         [$lq__journal_entry_obj],
	//         ([$lq__journal_entry_obj]) => {
	//             return $lq__journal_entry_obj;
	//         }
	//     }
	// );

	// let codemirror_extensions = [
	// 	basicSetup,
	//     keymap.of([indentWithTab]),
	//     javascript()
	// ]

	// // "Start document"
	// const codemirror_editorview = new EditorView({
	//   doc: $lq__journal_entry_obj?.content ?? 'yyyy',
	//   parent: document.getElementById('journal_entry_codemirror') as HTMLElement,
	//   extensions: [codemirror_extensions]
	// })

	let journal_key = $derived(() => {
		return $lq__journal_obj?.combined_passcode || $lq__journal_obj?.passcode || 'temp-secret-key';
	});
	// let journal_key = $state($lq__journal_obj?.combined_passcode || $lq__journal_obj?.passcode || 'temp-secret-key');

	let content = ''; // "This is my test content to encrypt and decrypt.";
	let encrypted_base64_string: string = $state('');
	let encryption_iv: null | Uint8Array<ArrayBuffer> = $state(null);
	let decrypted_content: string = $state('');
	let trigger_decrypt: boolean = $state(false);
	let decrypted_history: string = $state('');

	if (!$journals_loc?.entry?.decrypt_kv) {
		$journals_loc.entry.decrypt_kv = {};
		$journals_loc.entry.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id] = null;
	}

	function not_obj(obj) {
		if (obj == null) {
			// null or undefined
			return true;
		}
		if (typeof obj !== 'object') {
			return true;
		}
		return Object.keys(obj).length === 0;
	}

	$effect(async () => {
		if ($lq__journal_entry_obj && $lq__journal_entry_obj?.updated_on) {
			console.log(`TEST: Journal Entry updated datetime changed`, $lq__journal_entry_obj);

			// updated_obj = false;
			orig_entry_obj = { ...$lq__journal_entry_obj };
			tmp_entry_obj = { ...$lq__journal_entry_obj };

			// if ($journals_loc?.entry?.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id]) {
			//     if (!tmp_entry_obj?.content && tmp_entry_obj?.content_encrypted) {
			//         console.log('TEST: Decrypting the content...');

			//         tmp_entry_obj.content = await ae_util.decrypt_wrapper(tmp_entry_obj?.content_encrypted, journal_key);
			//         tmp_entry_obj.content_md_html = handle_marked(tmp_entry_obj?.content);

			//         orig_entry_obj.content = await ae_util.decrypt_wrapper(orig_entry_obj?.content_encrypted, journal_key);
			//         orig_entry_obj.content_md_html = handle_marked(orig_entry_obj?.content);
			//     }
			//     if (!tmp_entry_obj?.history && tmp_entry_obj?.history_encrypted) {
			//         console.log('TEST: Decrypting the history...');

			//         tmp_entry_obj.history = await ae_util.decrypt_wrapper(tmp_entry_obj?.history_encrypted, journal_key);
			//         tmp_entry_obj.history_md_html = handle_marked(tmp_entry_obj?.history);

			//         orig_entry_obj.history = await ae_util.decrypt_wrapper(orig_entry_obj?.history_encrypted, journal_key);
			//         orig_entry_obj.history_md_html = handle_marked(orig_entry_obj?.history);
			//     }
			// }

			tmp_entry_obj_changed = false;
			// updated_obj = false;
			updated_idb = false;
		} else if (updated_obj && (await $lq__journal_entry_obj)) {
			console.log(`TEST: Journal Entry updated and changed`, $lq__journal_entry_obj);
			updated_obj = false;
			orig_entry_obj = { ...$lq__journal_entry_obj };
			tmp_entry_obj = { ...$lq__journal_entry_obj };
			if ($journals_loc?.entry?.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id]) {
				let decrypt_key = $lq__journal_obj.combined_passcode;

				if (!tmp_entry_obj?.content && tmp_entry_obj?.content_encrypted) {
					console.log('TEST: Decrypting the content...');

					tmp_entry_obj.content = await ae_util.decrypt_wrapper(
						tmp_entry_obj?.content_encrypted,
						decrypt_key
					);
					tmp_entry_obj.content_md_html = handle_marked(tmp_entry_obj?.content);

					orig_entry_obj.content = await ae_util.decrypt_wrapper(
						orig_entry_obj?.content_encrypted,
						decrypt_key
					);
					orig_entry_obj.content_md_html = handle_marked(orig_entry_obj?.content);
				}
				if (!tmp_entry_obj?.history && tmp_entry_obj?.history_encrypted) {
					console.log('TEST: Decrypting the history...');

					tmp_entry_obj.history = await ae_util.decrypt_wrapper(
						tmp_entry_obj?.history_encrypted,
						decrypt_key
					);
					tmp_entry_obj.history_md_html = handle_marked(tmp_entry_obj?.history);

					orig_entry_obj.history = await ae_util.decrypt_wrapper(
						orig_entry_obj?.history_encrypted,
						decrypt_key
					);
					orig_entry_obj.history_md_html = handle_marked(orig_entry_obj?.history);
				}
			}

			tmp_entry_obj_changed = false;
			// updated_obj = false;
			updated_idb = false;
		} else if (
			!updated_obj &&
			JSON.stringify(orig_entry_obj) !== JSON.stringify($lq__journal_entry_obj)
		) {
			console.log('TEST: IDB has changed and not flagged as updated_obj!!!');
			updated_idb = true;
			// orig_entry_obj = { ...$lq__journal_entry_obj };
		}
	});

	$effect(() => {
		if (
			!not_obj(tmp_entry_obj) &&
			!not_obj(orig_entry_obj) &&
			JSON.stringify(tmp_entry_obj) != JSON.stringify(orig_entry_obj)
		) {
			console.log(
				'TEST: tmp_entry_obj and orig_entry_obj available; marking tmp_entry_obj as changed'
			);
			// tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify($lq__journal_entry_obj);
			// tmp_entry_obj_changed = JSON.stringify(tmp_entry_obj) != JSON.stringify(orig_entry_obj);
			// if (!tmp_entry_obj?.private ) {
			//     tmp_entry_obj_changed = true;
			// } else
			// if (tmp_entry_obj?.private && tmp_entry_obj?.content) {
			//     tmp_entry_obj_changed = false;
			// } else {
			//     tmp_entry_obj_changed = true;
			// }
			tmp_entry_obj_changed = true;
		} else {
			// console.log('TEST: tmp_entry_obj == orig_entry_obj');
			tmp_entry_obj_changed = false;
		}
	});

	// Better decrypted content and history handling
	$effect(() => {
		if (
			$lq__journal_entry_obj?.content_encrypted &&
			$journals_sess?.journal_kv[$lq__journal_obj?.journal_id]?.journal_passcode_verified &&
			!$journals_sess?.journal_kv[$lq__journal_obj?.journal_id]?.journal_passcode_decrypted
		) {
			if ($journals_sess.journal_kv[$lq__journal_obj?.journal_id]?.typed_journal_passcode?.length) {
				journal_key = ae_util.derive_key_from_passcode(
					$journals_sess.journal_kv[$lq__journal_obj?.journal_id]?.typed_journal_passcode
				);
			} else {
				journal_key = $lq__journal_obj?.private_passcode;
			}

			if (journal_key == null) {
				console.log('TEST: No journal key available to decrypt the content.');
				return;
			}

			let content_decrypted = null;

			$journals_sess.journal_kv[$lq__journal_obj?.journal_id].journal_passcode_decrypted =
				'processing';

			content_decrypted = ae_util.decrypt_wrapper(
				$lq__journal_entry_obj?.content_encrypted,
				journal_key
			);
			console.log('TEST: Decrypted content:', content_decrypted);

			$journals_sess.journal_kv[$lq__journal_obj?.journal_id].journal_passcode_decrypted = true;

			// $journals_slct.journal_entry_obj.content_decrypted = content_decrypted;
			tmp_entry_obj.content = content_decrypted;
			tmp_entry_obj.content_md_html = handle_marked(content_decrypted);
		}
	});

	// // Old decrypted content and history handling
	// $effect(() => {
	//     if ($journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified && tmp_entry_obj?.content_encrypted && !tmp_entry_obj.content) {
	//         console.log('TEST: Decrypting the content before displaying it...');
	//         tmp_entry_obj.content = ae_util.decrypt_wrapper(tmp_entry_obj?.content_encrypted, journal_key);
	//         tmp_entry_obj.content_md_html = handle_marked(tmp_entry_obj?.content);
	//     }

	//     if ($journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified && tmp_entry_obj?.history_encrypted && !tmp_entry_obj.history) {
	//         console.log('TEST: Decrypting the history before displaying it...');
	//         tmp_entry_obj.history = ae_util.decrypt_wrapper(tmp_entry_obj?.history_encrypted, journal_key);
	//         tmp_entry_obj.history_md_html = handle_marked(tmp_entry_obj?.history);
	//     }
	// });

	// const test_html = marked.parse('# Marked in Node.js\n\nRendered by **marked**.');

	async function update_journal_entry() {
		if (!$ae_loc.trusted_access) {
			alert('You do not have permission to update this journal entry.');
			return;
		}

		// log_lvl = 1;

		// append slct_hosted_file_kv to data_json.hosted_file_kv
		// if (!tmp_entry_obj.data_json.hosted_file_kv) {
		//     tmp_entry_obj.data_json.hosted_file_kv = {};
		// }
		// tmp_entry_obj.data_json.hosted_file_kv = $journals_loc.entry.hosted_file_kv;

		let data_kv: key_val = {
			alert: tmp_entry_obj?.alert,
			personal: tmp_entry_obj?.personal,
			private: tmp_entry_obj?.private,
			professional: tmp_entry_obj?.professional,
			public: tmp_entry_obj?.public,
			template: tmp_entry_obj?.template,

			hide: tmp_entry_obj?.hide,
			priority: tmp_entry_obj?.priority,
			enable: tmp_entry_obj?.enable,

			// alert_msg: $lq__journal_entry_obj?.alert_msg ? false : true
			alert_msg: tmp_entry_obj?.alert_msg,
			category_code: tmp_entry_obj?.category_code,
			summary: tmp_entry_obj?.summary,
			content: tmp_entry_obj?.content,
			content_encrypted: null, // This should only be generated below.
			history: tmp_entry_obj?.history,
			history_encrypted: null, // This should only be generated below.

			data_json: tmp_entry_obj?.data_json,

			sort: tmp_entry_obj?.sort,
			group: tmp_entry_obj?.group,
			archive_on: tmp_entry_obj?.archive_on,
			name: tmp_entry_obj?.name,
			tags: tmp_entry_obj?.tags
		};

		if (tmp_entry_obj?.content || tmp_entry_obj?.content_encrypted) {
			let decrypt_key = $lq__journal_obj.combined_passcode;

			// If private, it needs to be (re-)encrypted.
			if (!tmp_entry_obj?.private) {
				console.log('TEST: Public or non-private entry; handling cut tags if needed...');

				// let left_over_string = '';
				// let cut_out_string = '';

				if (tmp_entry_obj.content) {
					// left_over_string, cut_out_string = handle_cut_string(tmp_entry_obj?.content);
					// data_kv.content = left_over_string;
					data_kv.content = tmp_entry_obj?.content;
				} else if (tmp_entry_obj.content_encrypted) {
					// We need to decrypt the content first, then handle the cut tags.
					let decrypted_content = await ae_util.decrypt_wrapper(
						tmp_entry_obj?.content_encrypted,
						decrypt_key
					);
					data_kv.content = decrypted_content;
				} else {
					data_kv.content = '';
				}

				let { left_over_string, cut_out_string } = handle_cut_string(data_kv.content);
				data_kv.content = left_over_string;

				// console.log('TEST: data_kv.content:', data_kv.content);

				data_kv.content_encrypted = null;

				// if (tmp_entry_obj?.history_encrypted) {
				//     console.log('TEST: Decrypting the history before saving it...');
				//     decrypted_history = await handle_decrypt_string(tmp_entry_obj?.history_encrypted, decrypt_key);
				// } else {
				//     decrypted_history = tmp_entry_obj?.history;
				// }

				if (cut_out_string) {
					// console.log(`${ae_util.iso_datetime_formatter(new Date().toISOString(), 'datetime_iso_12_no_seconds')}`);
					let cut_prefix = `# Cut on ${ae_util.iso_datetime_formatter(new Date().toISOString(), 'datetime_iso_12_no_seconds')}\n`;
					// let cut_prefix = `# Cut on ${new Date().toISOString()}\n`;
					// let current_timestamp = new Date().toISOString();
					// cut_out_string = `## Cut on ${current_timestamp}\n` + cut_out_string;
					cut_out_string = cut_prefix + cut_out_string;
					// console.log(`TEST: Cut out string with prefix: "${cut_out_string}"`);
				}

				if (tmp_entry_obj?.history?.length && cut_out_string) {
					// console.log(`HERE 1`);
					data_kv.history = tmp_entry_obj?.history + '\n' + cut_out_string + '\n';
				} else if (cut_out_string) {
					// console.log(`HERE 2`);
					data_kv.history = cut_out_string + '\n';
				}

				console.log('TEST: data_kv.history:', data_kv.history);

				data_kv.history_encrypted = null;
			} else if (tmp_entry_obj?.private) {
				let { left_over_string, cut_out_string } = handle_cut_string(tmp_entry_obj?.content);
				// Need to decrypt the current content and current history. Assume the history has not been decrypted yet.

				let content_enc_combined_data = await ae_util.encrypt_wrapper(
					left_over_string,
					decrypt_key
				);
				if (log_lvl) {
					console.log('TEST: Encrypted string:', content_enc_combined_data);
				}
				// return content_enc_combined_data;

				// let content_enc_combined_data = await handle_encrypt_string(left_over_string, decrypt_key)
				data_kv.content_encrypted = content_enc_combined_data;
				data_kv.content = null;
				tmp_entry_obj.content = null;
				// decrypted_content = '';

				if (log_lvl) {
					console.log('TEST: Decrypting the history before saving it...');
				}
				if (tmp_entry_obj?.history_encrypted) {
					decrypted_history = await ae_util.decrypt_wrapper(
						tmp_entry_obj?.history_encrypted,
						decrypt_key
					);
					tmp_entry_obj.history = decrypted_history;
				}

				if (cut_out_string) {
					let cut_prefix = `# Cut on ${ae_util.iso_datetime_formatter(new Date().toISOString(), 'datetime_iso_12_no_seconds')}\n`;
					cut_out_string = cut_prefix + cut_out_string;
					console.log(`TEST: Cut out string with prefix: "${cut_out_string}"`);
				}

				if (tmp_entry_obj?.history?.length && cut_out_string) {
					console.log(`HERE 1`);
					data_kv.history = tmp_entry_obj?.history + '\n' + cut_out_string + '\n';
				} else {
					console.log(`HERE 2`);
					data_kv.history = cut_out_string + '\n';
				}
				console.log('TEST: data_kv.history:', data_kv.history);

				if (log_lvl) {
					console.log('TEST: Encrypting the history before saving it...');
				}
				let history_enc_combined_data = await ae_util.encrypt_wrapper(data_kv.history, decrypt_key);

				data_kv.history_encrypted = history_enc_combined_data;
				data_kv.history = null;
				tmp_entry_obj.history;
				decrypted_history = '';
			}
		}

		// // Check if the content contains a set of special "cut" XML tags. Anything inside the tags will be moved (appended) to the history field. Anything outside the tags should stay. The content may need to be merged back together if something was cut out of the middle. If no closing tag is found, then cut everything to the end of the content. Be sure to prefix the new history content with a timestamp header in Markdown.
		// // Example: Hello <cut>Old</cut> World!
		// // Example header: # Cut on 2024-11-06T12:34:56Z
		// if (tmp_entry_obj?.content) {
		//     const cutTag = '<cut>';
		//     const cutEndTag = '</cut>';
		//     const cutIndex = tmp_entry_obj.content.indexOf(cutTag);
		//     const cutEndIndex = tmp_entry_obj.content.indexOf(cutEndTag);

		//     if (cutIndex !== -1) {
		//         let current_timestamp = new Date().toISOString();
		//         if (cutEndIndex !== -1) {
		//             // Cut everything between the cut tags
		//             const cutContent = tmp_entry_obj.content.substring(cutIndex + cutTag.length, cutEndIndex);
		//             data_kv.history = data_kv.history + '\n\n' + `# Cut on ${current_timestamp}\n` + cutContent;
		//             data_kv.content = tmp_entry_obj.content.replace(cutTag + cutContent + cutEndTag, '');
		//         } else {
		//             // Cut everything after the cut tag
		//             const cutContent = tmp_entry_obj.content.substring(cutIndex + cutTag.length);
		//             data_kv.history = data_kv.history + '\n\n' + `# Cut on ${current_timestamp}\n` + cutContent;
		//             data_kv.content = tmp_entry_obj.content.substring(0, cutIndex);
		//         }
		//     }
		// }
		// // We also need to support a Markdown variant of the cut tag: ~~cut cut~~.
		// // Example: Hello ~~CUT: Old :CUT~~ World!
		// // Example: Hello ~~:: Old ::~~ World!
		// if (tmp_entry_obj?.content) {
		//     const cutTag = '~~::';
		//     const cutEndTag = '::~~';
		//     const cutIndex = tmp_entry_obj.content.indexOf(cutTag);
		//     const cutEndIndex = tmp_entry_obj.content.indexOf(cutEndTag);

		//     if (cutIndex !== -1) {
		//         let current_timestamp = new Date().toISOString();
		//         if (cutEndIndex !== -1) {
		//             // Cut everything between the cut tags
		//             const cutContent = tmp_entry_obj.content.substring(cutIndex + cutTag.length, cutEndIndex);
		//             data_kv.history = data_kv.history + '\n\n' + `# Cut on ${current_timestamp}\n` + cutContent;
		//             data_kv.content = tmp_entry_obj.content.replace(cutTag + cutContent + cutEndTag, '');
		//         } else {
		//             // Cut everything after the cut tag
		//             const cutContent = tmp_entry_obj.content.substring(cutIndex + cutTag.length);
		//             data_kv.history = data_kv.history + '\n\n' + `# Cut on ${current_timestamp}\n` + cutContent;
		//             data_kv.content = tmp_entry_obj.content.substring(0, cutIndex);
		//         }
		//     }
		// }

		// Call API to save the content
		try {
			const response = await journals_func.update_ae_obj__journal_entry({
				api_cfg: $ae_api,
				journal_entry_id: $lq__journal_entry_obj?.journal_entry_id,
				data_kv: data_kv,
				log_lvl: 1
			});
			console.log('Journal entry updated successfully:', response);
			// tick();
			updated_obj = true;

			// tick();

			// orig_entry_obj = { ...await $lq__journal_entry_obj };
			// tmp_entry_obj = { ...await $lq__journal_entry_obj };
			// if ($journals_loc?.entry?.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id]) {
			//     if (!tmp_entry_obj?.content && tmp_entry_obj?.content_encrypted) {
			//         console.log('TEST: Decrypting the content...');

			//         tmp_entry_obj.content = await ae_util.decrypt_wrapper(tmp_entry_obj?.content_encrypted, journal_key);
			//         tmp_entry_obj.content_md_html = handle_marked(tmp_entry_obj?.content);

			//         orig_entry_obj.content = await ae_util.decrypt_wrapper(orig_entry_obj?.content_encrypted, journal_key);
			//         orig_entry_obj.content_md_html = handle_marked(orig_entry_obj?.content);
			//     }
			//     if (!tmp_entry_obj?.history && tmp_entry_obj?.history_encrypted) {
			//         console.log('TEST: Decrypting the history...');

			//         tmp_entry_obj.history = await ae_util.decrypt_wrapper(tmp_entry_obj?.history_encrypted, journal_key);
			//         tmp_entry_obj.history_md_html = handle_marked(tmp_entry_obj?.history);

			//         orig_entry_obj.history = await ae_util.decrypt_wrapper(orig_entry_obj?.history_encrypted, journal_key);
			//         orig_entry_obj.history_md_html = handle_marked(orig_entry_obj?.history);
			//     }
			// }
			// console.log('TEST: tmp_entry_obj:', tmp_entry_obj);

			// updated_obj = true;
			// updated_idb = false;

			// journals_func.update_ae_obj__journal_entry({
			//     api_cfg: $ae_api,
			//     journal_entry_id: $lq__journal_entry_obj?.journal_entry_id,
			//     data_kv: data_kv,
			//     log_lvl: 1,
			// })
			// .then((response) => {
			//     console.log('HERE: response', response);
			//     updated_obj = true;
			//     updated_idb = false;
			//     console.log('Journal entry updated successfully!');
			// })
			// tick();
		} catch (error) {
			console.error('Error updating journal entry:', error);
			alert('Failed to update journal entry.');
		}
	}

	async function change_journal_id() {
		if (!$ae_loc.trusted_access) {
			alert('You do not have permission to update this journal entry.');
			return;
		}

		let data_kv = {
			journal_id_random: tmp_entry_obj?.journal_id
		};

		// Call API to save the content
		try {
			await journals_func.update_ae_obj__journal_entry({
				api_cfg: $ae_api,
				journal_entry_id: $lq__journal_entry_obj?.journal_entry_id,
				data_kv: data_kv,
				log_lvl: log_lvl
			});
			updated_obj = true;
			updated_idb = false;
			console.log('Journal entry updated successfully!');
		} catch (error) {
			console.error('Error updating journal entry:', error);
			alert('Failed to update journal entry.');
		}
		$journals_slct.journal_id = tmp_entry_obj?.journal_id;
		goto(`/journals/${tmp_entry_obj?.journal_id}`);
	}

	// async function generate_iv() {
	//     const data = new Uint8Array(16);
	//     crypto.getRandomValues(data);
	//     return data;
	// }

	// async function encrypt_content(content, keyData) {
	//     const iv = await generate_iv();
	//     const keyBytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(keyData));
	//     const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, ['encrypt']);
	//     const encodedContent = await crypto.subtle.encrypt({ name: 'AES-CBC', iv }, key, new TextEncoder().encode(content));
	//     const base64 = btoa(String.fromCharCode(...new Uint8Array(encodedContent)));
	//     console.log('Base64 Encoded Content:', base64);
	//     return { base64, iv };
	// }

	// async function decrypt_content(base64Content, iv, keyData) {
	//     const keyBytes = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(keyData));
	//     const key = await crypto.subtle.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, ['decrypt']);
	//     const encryptedContent = Uint8Array.from(atob(base64Content), c => c.charCodeAt(0));
	//     const decryptedContent = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, key, encryptedContent);
	//     const decodedContent = new TextDecoder().decode(decryptedContent);
	//     console.log('Decrypted Content:', decodedContent);
	//     return decodedContent;
	// }

	// // Example usage
	// (async () => {
	//     const keyData = "my-secret-key";
	//     const content = "This is my test content to encrypt and decrypt.";

	//     const { base64, iv } = await ae_util.encrypt_content(content, keyData);
	//     await ae_util.decrypt_content(base64, iv, keyData);
	// })();

	// let journal_key: string = $state( 'my-secret-key-111');
	// let journal_key: string = $state($lq__journal_obj?.passcode);
	// let journal_key: string = $state($lq__journal_obj?.passcode);

	// console.log('TEST: journal_key', journal_key);

	// $effect(() => {
	//     // A journal should always at least have a general passcode that can be used. If the private code is also found, then we should use the combined value as the key.
	//     if ($journals_sess.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified) {
	//         // For private
	//         journal_key = $lq__journal_obj?.combined_passcode;
	//     } else if ($lq__journal_obj?.passcode) {
	//         journal_key = $lq__journal_obj?.passcode;
	//     } else {
	//         'temp-secret-key';
	//     }
	//     console.log('TEST: journal_key', journal_key);

	//     // if ($lq__journal_obj?.passcode) {
	//     //     console.log('TEST: lq__journal_obj?.passcode', $lq__journal_obj?.passcode);
	//     //     journal_key = $lq__journal_obj?.passcode;
	//     // }
	// });

	// $effect(async () => {
	//     if (tmp_entry_obj?.content_encrypted && trigger_decrypt) {
	//         trigger_decrypt = false;

	//         handle_decrypt_content();

	//     }

	//     // if (tmp_entry_obj?.content) {
	//     //     content = tmp_entry_obj?.content;

	//     //     let encrypted_base64 = await ae_util.encrypt_content(content, journal_key);
	//     //     encrypted_base64_string = encrypted_base64.base64;
	//     //     encryption_iv = encrypted_base64.iv;

	//     //     let decrypted = await ae_util.decrypt_content(encrypted_base64_string, encryption_iv, journal_key);
	//     //     decrypted_content = decrypted;
	//     //     if (log_lvl) {
	//     //         console.log('Decrypted content:', decrypted_content);
	//     //     }
	//     // }
	//     // console.log('Encrypted content:', base64);
	//     // console.log('IV:', iv);
	// });

	// async function handle_decrypt_content() {
	//     log_lvl = 1;
	//     if (log_lvl) {
	//         console.log('TEST: handle_decrypt_content');
	//     }
	//     let combined_data = tmp_entry_obj?.content_encrypted;
	//     let [encryption_iv_hex, encrypted_base64_string] = combined_data.split(':');
	//     encryption_iv = new Uint8Array(encryption_iv_hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
	//     if (log_lvl) {
	//         console.log(`IV: ${encryption_iv}; Encrypted: ${encrypted_base64_string}`);
	//     }

	//     let decrypted: string|null = null;
	//     try {
	//         decrypted = await ae_util.decrypt_content(encrypted_base64_string, encryption_iv, journal_key);
	//     } catch (error) {
	//         console.error('Error decrypting content:', error);
	//         alert('Failed to decrypt content. Please check the passcode.');
	//         return;
	//     }
	//     // let decrypted = await ae_util.decrypt_content(encrypted_base64_string, encryption_iv, journal_key);
	//     // decrypted_content = 'XXX '+decrypted+' XXX';

	//     if (!decrypted) {
	//         alert('Failed to decrypt content. Please check the passcode.');
	//         return;
	//     }
	//     decrypted_content = decrypted;
	//     if (log_lvl) {
	//         console.log('Decrypted content:', decrypted_content);
	//     }
	//     tmp_entry_obj.content = decrypted_content;
	//     // orig_entry_obj.content = decrypted_content;
	//     // tmp_entry_obj_changed = false;

	//     // tmp_entry_obj.content_encrypted = null;
	// }

	async function handle_decrypt_string(encrypted_string: string, passcode: string) {
		// log_lvl = 1;

		if (log_lvl) {
			console.log(`TEST: handle_decrypt_string: ${passcode}`, encrypted_string);
		}
		if (!encrypted_string) {
			console.log('TEST: No encrypted string provided');
			return '';
		}
		if (!passcode) {
			console.log('TEST: No journal key provided');
			return false;
		}

		let decrypted_string_2 = await ae_util.decrypt_wrapper(encrypted_string, passcode);
		if (log_lvl) {
			console.log('TEST: Decrypted string:', decrypted_string_2);
		}

		return decrypted_string_2;

		// let combined_data = encrypted_string;
		// let [encryption_iv_hex, encrypted_base64_string] = combined_data.split(':');
		// encryption_iv = new Uint8Array(encryption_iv_hex.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
		// if (log_lvl) {
		//     console.log(`IV: ${encryption_iv}; Encrypted: ${encrypted_base64_string}`);
		// }

		// // Decrypt the string using the journal key
		// let decrypted_string = '';
		// try {
		//     decrypted_string = await ae_util.decrypt_content(encrypted_base64_string, encryption_iv, passcode);
		// } catch (error) {
		//     console.error('Error decrypting string:', error);
		//     alert('Failed to decrypt string. Please check the passcode.');
		//     return;
		// }
		// if (log_lvl) {
		//     console.log('Decrypted string:', decrypted_string);
		// }
		// return decrypted_string;
	}

	// return new_string and cut_string
	function handle_cut_string(
		old_string: string,
		start_tag: string = '<cut>',
		end_tag: string = '</cut>'
	) {
		// Check if the string contains a set of special "cut" XML tags or Markdown. Anything inside the tags or Markdown will be moved (appended) to the history field. Anything outside the tags should stay. The string may need to be merged back together if something was cut out of the middle. If no closing tag is found, then cut everything to the end of the string. Be sure to prefix the new history sting with a timestamp header in Markdown.
		// Example: Hello <cut>Old</cut> World!
		// Example header: # Cut on 2024-11-06T12:34:56Z
		// We also need to support a Markdown variant of the cut tag: ~~cut cut~~.
		// Example: Hello ~~CUT: Old :CUT~~ World!
		// Example: Hello ~~:: Old ::~~ World!

		let left_over_string = old_string; // Will be for the updated content field
		let cut_out_string = ''; // Will be for the history field

		if (old_string) {
			let start_tag = '<cut>';
			let end_tag = '</cut>';
			let cut_index = old_string.indexOf(start_tag);
			let cut_end_index = old_string.indexOf(end_tag);
			// let cut_prefix = `# Cut on ${new Date().toISOString()}\n`;

			if (cut_index !== -1) {
				if (cut_end_index !== -1 && cut_end_index > cut_index) {
					// Cut everything between the cut tags
					cut_out_string = old_string.substring(cut_index + start_tag.length, cut_end_index).trim();
					left_over_string = (
						old_string.substring(0, cut_index) +
						' ' +
						old_string.substring(cut_end_index + end_tag.length)
					).trim();
				} else {
					// Cut everything after the cut tag
					cut_out_string = old_string.substring(cut_index + start_tag.length).trim();
					left_over_string = old_string.substring(0, cut_index).trim();
				}
			}
			// console.log(`Cut out string: "${cut_out_string}"`);
		}
		return { left_over_string, cut_out_string };
	}

	function handle_marked(text_string: string) {
		if (!text_string) {
			if (log_lvl) {
				console.log('No text string provided');
			}
			return '';
		}
		// let cleaned_string = text_string.replace(/<[^>]*>/g, ''); // Remove HTML tags
		let cleaned_string = text_string.replace(/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/, '');
		// let marked_string = marked.parse(text_string);
		let marked_string = marked.parse(cleaned_string, {
			// gfm: true,
			// breaks: true,
			// headerIds: false,
			// mangle: false,
			// xhtml: true,
		});
		return marked_string;
	}

	let slct_hosted_file_kv: key_val = $state({});
	let slct_hosted_file_id: any = $state(null);
	let slct_hosted_file_obj: any = $state(null);
	$effect(() => {
		if (slct_hosted_file_id && slct_hosted_file_obj) {
			console.log(`*** handle_hosted_file_selected() *** ${slct_hosted_file_id}`);
			// We need to update the journal_entry_obj with the new file (for now just the first one).

			update_journal_entry();

			slct_hosted_file_id = null;
			slct_hosted_file_obj = null;
		}
	});
</script>

<section
	class="
        svelte_component ae_section ae_view journal_entry_obj view__journal_entry_obj
        flex flex-col gap-1 grow items-center justify-start
        w-full h-full
        p-1 m-1
        "
	bind:clientHeight={$ae_loc.iframe_height_modal_body}
>
	{#if $lq__journal_entry_obj}
		<header
			class="
        ae_header journal_entry__header
        flex flex-row flex-wrap gap-2
        items-center justify-between
        w-full
        bg-gray-100 dark:bg-gray-800
        p-1 rounded-lg shadow-md
        "
		>
			<div class="grow flex flex-row flex-wrap gap-2 items-center justify-start">
				<!-- Toggle edit for journal entry -->
				<button
					type="button"
					onclick={() => {
						// Ask if they would like to save changes before toggling edit mode off.
						if (
							$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] == 'current'
						) {
							if (
								tmp_entry_obj_changed &&
								confirm(
									'Would you like to save changes to this journal entry before exiting edit mode? Your changes will be lost if the page is refreshed.'
								)
							) {
								update_journal_entry();
							}
							$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = false;
						} else {
							$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = 'current';
						}

						// if ($ae_loc.trusted_access && !$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]) {
						//     trigger_decrypt = true;
						// }
					}}
					class="
            btn btn-sm
            preset-tonal-success hover:preset-filled-warning-500
            transition-all
            "
					title="Toggle edit mode for this journal entry"
				>
					{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] == 'current'}
						<!-- <Pencil strokeWidth="2.5" color="blue" /> -->
						<!-- <Hash strokeWidth="2.5" color="green" /> -->
						<!-- <Hash strokeWidth="1" color="red" /> -->

						<NotebookText strokeWidth="2.5" color="green" />
						<!-- <Hash strokeWidth="2.5" color="red" /> -->
						<PenLine strokeWidth="2.5" color="red" />
					{:else}
						<!-- <Pencil strokeWidth="1" color="gray" /> -->
						<!-- <PenLine strokeWidth="1" color="green" /> -->

						{#if $lq__journal_entry_obj?.name}
							<NotebookText
								strokeWidth="2.5"
								class="text-neutral-800/60 dark:text-neutral-200/60"
							/>
						{:else}
							<CalendarClock
								strokeWidth="2.5"
								class="text-neutral-800/60 dark:text-neutral-200/60"
							/>
						{/if}

						<Hash strokeWidth="2.5" color="green" />
					{/if}
				</button>

				<h2 class="journal_entry__name text-md grow">
					<!-- <span class="fas fa-spinner fa-spin"></span> -->
					<!-- <span class="journal_entry__name inline-block"> -->
					<!-- Allow for toggle between view and edit of journal entry. -->
					{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] == 'current'}
						<span class="flex flex-row gap-1 items-center justify-start">
							<!-- <Hash strokeWidth="2.5" color="red" /> -->
							<input
								type="text"
								bind:value={tmp_entry_obj.name}
								class="input input-bordered min-w-60 w-full text-gray-800 dark:text-gray-200"
								placeholder="Journal Entry Name"
								title="Edit the name of this journal entry"
							/>
						</span>
					{:else}
						<span>
							{#if $lq__journal_entry_obj?.name}
								<!-- <NotebookText class="mx-1 inline-block text-neutral-800/60 dark:text-neutral-200/60"/> -->
								{@html $lq__journal_entry_obj?.name}
							{:else}
								<!-- <CalendarClock class="mx-1 inline-block text-neutral-800/60 dark:text-neutral-200/60"/> -->
								{ae_util.iso_datetime_formatter(
									$lq__journal_entry_obj?.created_on,
									'datetime_iso_12_no_seconds'
								)}
							{/if}
						</span>
					{/if}
					<!-- </span> -->
				</h2>
			</div>

			<div class="flex flex-row flex-wrap gap-2 items-center justify-end">
				<div class="flex flex-row flex-wrap gap-1 items-center justify-end">
					<!-- Tags for journal entry. Comma delimited list. -->
					{#if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] == 'current'}
						<div
							class="tags flex flex-row gap-1 items-center justify-start border-l border-gray-200 rounded-lg"
						>
							<span class="text-sm text-gray-500">
								<Tags class="mx-1 inline-block" />
								<!-- <span class="hidden sm:inline">Tags:</span> -->
							</span>

							<input
								type="text"
								bind:value={tmp_entry_obj.tags}
								class="input input-bordered inline-block text-sm text-gray-800 dark:text-gray-200"
								placeholder="Tags (comma delimited)"
								title="Edit the tags for this journal entry"
							/>
						</div>
					{:else if $lq__journal_entry_obj.tags && $lq__journal_entry_obj.tags.length}
						<div
							class="tags flex flex-wrap gap-1 items-center justify-start border border-gray-200 rounded-lg"
						>
							<span class="text-sm text-gray-500">
								<Tags class="mx-1 inline-block" />
								<span class="hidden md:inline">Tags</span>
							</span>
							<!-- <Tags class="m-1 inline-block" />
                    <span class="text-sm text-gray-500 hidden md:inline">Tags</span> -->

							{#each $lq__journal_entry_obj.tags.split(',') as tag}
								<span
									class="btn btn-sm preset-tonal-tertiary hover:preset-tonal-tertiary border border-tertiary-500 transition py-1 px-2"
									title={`Tag: ${tag.trim()}`}
								>
									{tag.trim()}
								</span>
							{/each}
						</div>
					{/if}

					<!-- Currently selected category for Entry; text only -->
					{#if $lq__journal_entry_obj.category_code}
						<div
							class="category flex flex-row gap-1 items-center justify-start border-l border-gray-200 rounded-lg"
						>
							<span class="text-sm text-gray-500">
								<Shapes class="mx-1 inline-block" />
								<!-- <span class="hidden sm:inline">Category:</span> -->
							</span>
							<span
								class="btn btn-sm preset-tonal-tertiary hover:preset-tonal-tertiary border border-tertiary-500 transition py-1 px-2"
								title={`Category: ${$lq__journal_entry_obj.category_code}`}
							>
								{$lq__journal_entry_obj.category_code}
							</span>
						</div>
					{/if}

					<span
						class="
            flex flex-row flex-wrap gap-1 items-center justify-center
            "
					>
						<!-- Entry alert status -->
						<button
							type="button"
							class:hidden={$lq__journal_obj?.cfg_json?.hide_btn_alert}
							onclick={() => {
								tmp_entry_obj.alert = !$lq__journal_entry_obj?.alert;
								update_journal_entry();
							}}
							class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
							title="Toggle alert status of this journal entry"
						>
							{#if $lq__journal_entry_obj?.alert}
								<Siren strokeWidth="2.5" color="red" />
							{:else}
								<MessageSquareWarning strokeWidth="1" color="gray" />
							{/if}
						</button>

						<!-- Entry alert message -->
						<button
							type="button"
							onclick={() => {
								// tmp_entry_obj.alert_msg = !$lq__journal_entry_obj?.alert_msg;
								update_journal_entry();
							}}
							class:hidden={!$lq__journal_entry_obj?.alert}
							class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
							title="Toggle alert message of this journal entry"
						>
							{#if $lq__journal_entry_obj?.alert_msg}
								<Skull strokeWidth="2.5" color="red" />
							{:else}
								<MessageSquareWarning strokeWidth="1" color="gray" />
							{/if}
						</button>

						<span class="flex flex-row flex-wrap gap-0.5 items-center justify-center">
							<!-- Only show this private toggle if not private or in edit mode. -->
							<button
								type="button"
								class:hidden={$lq__journal_obj?.cfg_json?.hide_btn_private ||
									(tmp_entry_obj?.private && !$ae_loc.edit_mode)}
								onclick={() => {
									// Allow for toggle between private (encrypted) and not,
									// and if private, allow for decryption.
									if (!$lq__journal_entry_obj?.private && tmp_entry_obj?.content) {
										// Handle converting to private (encrypted) content
										if (
											confirm('Are you sure you want to encrypt and resave this journal entry?')
										) {
											// Setting private to true will cause the update_journal_entry() function to encrypt the content.
											tmp_entry_obj.private = true;
											update_journal_entry();
										} else {
											return false;
										}
									} else if ($lq__journal_entry_obj?.private && tmp_entry_obj?.content_encrypted) {
										// Handle converting to not private (decrypted) content
										if (
											confirm(
												'Are you sure you want to decrypt and resave this journal entry unencrypted?'
											)
										) {
											// tmp_entry_obj.private = !$lq__journal_entry_obj?.private;
											// update_journal_entry();

											// Setting private to false will cause the update_journal_entry() function to decrypt the content. This will also copy it to tmp_entry_obj.content.
											tmp_entry_obj.private = false;
											// tmp_entry_obj.
											// handle_decrypt_content();
											update_journal_entry();
										} else {
											return false;
										}
									}
								}}
								class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
								title="Toggle private visibility of this journal entry"
							>
								{#if $lq__journal_entry_obj?.private}
									<Fingerprint strokeWidth="2.5" color="green" />
									<!-- Private (Encrypted) -->
								{:else}
									<Fingerprint strokeWidth="1" color="gray" />
									<!-- Not Private -->
								{/if}
							</button>

							<!-- Only show this encryption toggle if entry is private. -->
							<button
								type="button"
								onclick={async () => {
									console.log(tmp_entry_obj?.private);
									console.log($lq__journal_obj?.combined_passcode);
									console.log(tmp_entry_obj?.content_encrypted);
									if (
										tmp_entry_obj?.private &&
										$lq__journal_obj?.combined_passcode &&
										tmp_entry_obj?.content_encrypted
									) {
										if (!tmp_entry_obj?.content) {
											console.log(
												`TEST: key = ${$lq__journal_obj.passcode}:${$lq__journal_obj.private_passcode} OR ${$lq__journal_obj.combined_passcode} OR ${journal_key}`
											);

											// let decrypt_key = 'temp-secret-key';
											// let decrypt_key = 'sti-journals-2025:centauri';
											let decrypt_key = $lq__journal_obj?.combined_passcode;
											// let decrypt_key = `${$lq__journal_obj.passcode}:`;
											// let decrypt_key = `${$lq__journal_obj.private_passcode}`;

											console.log(
												`TEST: Decrypting the content... ${$lq__journal_obj?.combined_passcode}`
											);
											// WARNING: await is important here
											tmp_entry_obj.content = await ae_util.decrypt_wrapper(
												tmp_entry_obj?.content_encrypted,
												$lq__journal_obj?.combined_passcode
											);

											console.log('TEST: Content Markdown render to HTML:', tmp_entry_obj?.content);
											tmp_entry_obj.content_md_html = await handle_marked(tmp_entry_obj?.content);

											console.log(
												`TEST: Decrypting the history... ${$lq__journal_obj?.combined_passcode}`
											);
											// WARNING: await is important here
											tmp_entry_obj.history = await ae_util.decrypt_wrapper(
												tmp_entry_obj?.history_encrypted,
												$lq__journal_obj?.combined_passcode
											);

											console.log('TEST: History Markdown render to HTML:', tmp_entry_obj?.history);
											tmp_entry_obj.history_md_html = await handle_marked(tmp_entry_obj?.history);

											// TO DO: Use this to toggle and trigger the decryption of the content/history :TO DO
											$journals_sess.entry.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id] =
												true;
											// TO DO: Use this to toggle and trigger the decryption of the content/history :TO DO
										} else {
											console.log(`TEST: Not decrypting the content...`);
											// Clear out the decrypted content and history to prevent it from being seen.
											tmp_entry_obj.content = null;
											tmp_entry_obj.content_md_html = null;
											tmp_entry_obj.history = null;
											tmp_entry_obj.history_md_html = null;

											// TO DO: Use this to toggle and trigger the clearing of the decrypted content/history :TO DO
											$journals_sess.entry.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id] =
												false;
											// TO DO: Use this to toggle and trigger the clearing of the decrypted content/history :TO DO
										}
									}
									console.log('TEST: tmp_entry_obj:', tmp_entry_obj);
								}}
								class:hidden={!$lq__journal_entry_obj?.private || !tmp_entry_obj?.content_encrypted}
								class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
								title="Toggle viewing/editing of private encrypted content"
							>
								{#if $lq__journal_entry_obj?.private && tmp_entry_obj?.content}
									<LockKeyholeOpen strokeWidth="2.5" color="red" />
								{:else if $lq__journal_entry_obj?.private && tmp_entry_obj?.content_encrypted}
									<LockKeyhole strokeWidth="2.5" color="green" />
									<!-- <Fingerprint strokeWidth="2.5" color="green" /> -->
									<!-- {:else if $lq__journal_entry_obj?.private}
                    <Fingerprint strokeWidth="2.5" color="green" />
                {:else}
                    <Fingerprint strokeWidth="1" color="gray" /> -->
								{/if}
							</button>
						</span>

						<!-- Entry allowed to be public -->
						<button
							type="button"
							class:hidden={$lq__journal_obj?.cfg_json?.hide_btn_public}
							onclick={() => {
								tmp_entry_obj.public = !$lq__journal_entry_obj?.public;
								update_journal_entry();
							}}
							class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
							title="Toggle public visibility of this journal entry"
						>
							{#if $lq__journal_entry_obj?.public}
								<Globe strokeWidth="2.5" color="green" />
							{:else}
								<Globe strokeWidth="1" color="gray" />
							{/if}
						</button>

						<!-- Entry marked as personal -->
						<button
							type="button"
							class:hidden={$lq__journal_obj?.cfg_json?.hide_btn_personal}
							onclick={() => {
								tmp_entry_obj.personal = !$lq__journal_entry_obj?.personal;
								update_journal_entry();
							}}
							class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
							title="Toggle personal visibility of this journal entry"
						>
							{#if $lq__journal_entry_obj?.personal}
								<BookHeart strokeWidth="2.5" color="green" />
							{:else}
								<BookHeart strokeWidth="1" color="gray" />
							{/if}
						</button>

						<!-- Entry marked as professional -->
						<button
							type="button"
							class:hidden={$lq__journal_obj?.cfg_json?.hide_btn_professional}
							onclick={() => {
								tmp_entry_obj.professional = !$lq__journal_entry_obj?.professional;
								update_journal_entry();
							}}
							class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
							title="Toggle professional visibility of this journal entry"
						>
							{#if $lq__journal_entry_obj?.professional}
								<BriefcaseBusiness strokeWidth="2.5" color="green" />
							{:else}
								<BriefcaseBusiness strokeWidth="1" color="gray" />
							{/if}
						</button>
					</span>
				</div>

				<!-- <section class="relative"> -->
				<section class="relative transition-all">
					<!-- Menu Button -->
					<button
						type="button"
						onclick={() => (show_menu = !show_menu)}
						class="btn variant-outline-secondary hover:preset-filled-secondary-500 py-1 px-2 w-24 *:hover:inline transition-all"
						title="Toggle menu"
					>
						<Menu size="1.5em" class="inline-block" />
						<span class="hidden md:inline">Menu</span>
					</button>

					<!-- Menu -->
					<!-- {#if show_menu} -->
					<div
						class="
                absolute top-12 right-0
                p-4 z-50 w-80
                space-y-0.5
                bg-white dark:bg-gray-800
                border border-gray-500
                shadow-xl rounded-lg
                min-w-72
                max-w-fit
                "
						class:hidden={!show_menu}
					>
						<!-- <div class="flex flex-row flex-wrap gap-1 items-center justify-end"> -->

						<!-- Category code for journal entry -->
						<!-- Give list of categories to base the new entry on -->
						<div
							class="
                        flex flex-row items-center justify-evenly gap-2 w-full
                        "
						>
							<span class="text-sm text-gray-500 hidden sm:inline"> Category: </span>
							<select
								class="novi_btn btn btn-secondary btn-sm
                        preset-tonal-primary
                        hover:preset-filled-primary-500
                        transition
                        text-sm
                        w-full
                        "
								bind:value={tmp_entry_obj.category_code}
								onchange={(event) => {
									tmp_entry_obj.category_code = event.target.value;
									console.log('Selected category:', tmp_entry_obj.category_code);

									update_journal_entry();
								}}
								title="Select a category for the new journal entry"
							>
								<option value="">Select Category</option>
								{#each $lq__journal_obj?.cfg_json.category_li as category}
									<option
										value={category.code}
										selected={$lq__journal_entry_obj.category_code == category.code}
										title={`Category: ${category.name}`}
									>
										{category.name}
									</option>
								{/each}
							</select>
						</div>

						<!-- Should tags be here as well? -->

						<!-- </div> -->

						<!-- Journal Entry Options: alert, private, public, personal, professional, template -->
						<div
							class="
                    flex flex-row flex-wrap gap-0.5 items-center justify-evenly
                    "
						>
							<span class="text-sm text-gray-500">
								<Settings strokeWidth="1" class="mx-1 inline-block" />
								Flags:
							</span>

							<!-- Entry alert status -->
							<!-- class:hidden={$lq__journal_obj?.cfg_json?.hide_btn_alert} -->
							<button
								type="button"
								onclick={() => {
									tmp_entry_obj.alert = !$lq__journal_entry_obj?.alert;
									update_journal_entry();
								}}
								class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
								title="Toggle alert status of this journal entry"
							>
								{#if $lq__journal_entry_obj?.alert}
									<Siren strokeWidth="2.5" color="red" />
								{:else}
									<MessageSquareWarning strokeWidth="1" color="gray" />
								{/if}
							</button>

							<!-- Entry marked as private -->
							<!-- ($lq__journal_obj?.cfg_json?.hide_btn_private) ||  -->
							<button
								type="button"
								class:hidden={tmp_entry_obj?.private && !$ae_loc.edit_mode}
								onclick={() => {
									// Allow for toggle between private (encrypted) and not,
									// and if private, allow for decryption.
									if (!$lq__journal_entry_obj?.private && tmp_entry_obj?.content) {
										// Handle converting to private (encrypted) content
										if (
											confirm('Are you sure you want to encrypt and resave this journal entry?')
										) {
											// Setting private to true will cause the update_journal_entry() function to encrypt the content.
											tmp_entry_obj.private = true;
											update_journal_entry();
										} else {
											return false;
										}
									} else if ($lq__journal_entry_obj?.private && tmp_entry_obj?.content_encrypted) {
										// Handle converting to not private (decrypted) content
										if (
											confirm(
												'Are you sure you want to decrypt and resave this journal entry unencrypted?'
											)
										) {
											// tmp_entry_obj.private = !$lq__journal_entry_obj?.private;
											// update_journal_entry();

											// Setting private to false will cause the update_journal_entry() function to decrypt the content. This will also copy it to tmp_entry_obj.content.
											tmp_entry_obj.private = false;
											// tmp_entry_obj.
											// handle_decrypt_content();
											update_journal_entry();
										} else {
											return false;
										}
									}
								}}
								class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
								title="Toggle private visibility of this journal entry"
							>
								{#if $lq__journal_entry_obj?.private}
									<Fingerprint strokeWidth="2.5" color="green" />
									<!-- Private (Encrypted) -->
								{:else}
									<Fingerprint strokeWidth="1" color="gray" />
									<!-- Not Private -->
								{/if}
							</button>

							<!-- Entry allowed to be public -->
							<!-- class:hidden={$lq__journal_obj.cfg_json?.hide_btn_public} -->
							<button
								type="button"
								onclick={() => {
									tmp_entry_obj.public = !$lq__journal_entry_obj?.public;
									update_journal_entry();
								}}
								class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
								title="Toggle public visibility of this journal entry"
							>
								{#if $lq__journal_entry_obj?.public}
									<Globe strokeWidth="2.5" color="green" />
								{:else}
									<Globe strokeWidth="1" color="gray" />
								{/if}
							</button>

							<!-- Entry marked as personal -->
							<!-- class:hidden={$lq__journal_obj.cfg_json?.hide_btn_personal} -->
							<button
								type="button"
								onclick={() => {
									tmp_entry_obj.personal = !$lq__journal_entry_obj?.personal;
									update_journal_entry();
								}}
								class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
								title="Toggle personal visibility of this journal entry"
							>
								{#if $lq__journal_entry_obj?.personal}
									<BookHeart strokeWidth="2.5" color="green" />
								{:else}
									<BookHeart strokeWidth="1" color="gray" />
								{/if}
							</button>

							<!-- Entry marked as professional -->
							<!-- class:hidden={$lq__journal_obj.cfg_json?.hide_btn_professional} -->
							<button
								type="button"
								onclick={() => {
									tmp_entry_obj.professional = !$lq__journal_entry_obj?.professional;
									update_journal_entry();
								}}
								class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
								title="Toggle professional visibility of this journal entry"
							>
								{#if $lq__journal_entry_obj?.professional}
									<BriefcaseBusiness strokeWidth="2.5" color="green" />
								{:else}
									<BriefcaseBusiness strokeWidth="1" color="gray" />
								{/if}
							</button>

							<!-- Toggle if entry should be used as a template entry (cloneable). Only visible in edit_mode. -->
							<button
								type="button"
								class:hidden={$lq__journal_obj?.cfg_json?.hide_btn_template || !$ae_loc.edit_mode}
								onclick={() => {
									tmp_entry_obj.template = !$lq__journal_entry_obj?.template;
									update_journal_entry();
								}}
								class="btn-icon btn-icon-sm preset-tonal-secondary hover:preset-filled-secondary-500 transition"
								title="Toggle if used as journal entry template"
							>
								{#if $lq__journal_entry_obj?.template}
									<NotepadTextDashed strokeWidth="2.5" color="green" />
								{:else}
									<NotepadTextDashed strokeWidth="1" color="gray" />
								{/if}
							</button>
						</div>

						<!-- Copy and Clone Buttons -->
						<div>
							<!-- Button to copy the Markdown version -->
							<button
								type="button"
								onclick={() => {
									navigator.clipboard
										.writeText(tmp_entry_obj.content)
										.then(() => {
											alert('Markdown content copied to clipboard!');
										})
										.catch((error) => {
											console.error('Failed to copy content:', error);
											alert('Failed to copy content.');
										});
								}}
								class="btn btn-sm w-full mb-2 p-1 preset-tonal-secondary *:hover:inline lg:text-xs"
								title="Copy the markdown content"
							>
								<Copy size="1em" />
								<RemoveFormatting size="2em" />
								<span class="hidden md:inline"> Copy Plaintext Markdown </span>
							</button>
							<!-- Button to copy the HTML version -->
							<button
								type="button"
								onclick={() => {
									// Copy the HTML content to clipboard
									const htmlContent = $lq__journal_entry_obj?.content_md_html || '';
									navigator.clipboard
										.writeText(htmlContent)
										.then(() => {
											alert('HTML content copied to clipboard!');
										})
										.catch((error) => {
											console.error('Failed to copy HTML content:', error);
											alert('Failed to copy HTML content.');
										});
								}}
								class="btn btn-sm w-full mb-2 p-1 preset-tonal-secondary *:hover:inline lg:text-xs"
								title="Copy the HTML content"
							>
								<Copy size="1em" />
								<CodeXml size="2em" />
								<span class="hidden md:inline"> Copy HTML </span>
							</button>

							<!-- Button to copy the rich text (rendered HTML) version -->
							<button
								type="button"
								onclick={async () => {
									const element = document.getElementById(
										`rendered_journal_entry_content_${$lq__journal_entry_obj?.journal_entry_id}`
									);
									if (!element) {
										console.error('Element not found: rendered_journal_entry_content');
										alert('Failed to copy rich content.');
										return;
									}

									try {
										// Get the rendered HTML content
										const htmlContent = element.innerHTML;

										// Use the Clipboard API to write the HTML content as rich text
										await navigator.clipboard.write([
											new ClipboardItem({
												'text/html': new Blob([htmlContent], { type: 'text/html' })
											})
										]);

										alert('Rendered rich content copied to clipboard!');
									} catch (error) {
										console.error('Failed to copy rich content:', error);
										alert('Failed to copy rich content.');
									}
								}}
								class="btn btn-sm w-full mb-2 p-1 preset-tonal-secondary *:hover:inline lg:text-xs"
								title="Copy the rich text (rendered HTML) content"
							>
								<Copy size="1em" />
								<TypeOutline size="2em" />
								<span class="hidden md:inline"> Copy Rich Text </span>
							</button>

							<!-- Clone entry -->
							<button
								type="button"
								onclick={() => {
									// Clone the journal entry
									// We only want to clone certain fields from the original journal entry object to avoid conflicts.
									let data_kv = {
										code: $lq__journal_entry_obj?.code,
										category_code: $lq__journal_entry_obj?.category_code,
										name: $lq__journal_entry_obj?.name,
										short_name: $lq__journal_entry_obj?.short_name,
										content: $lq__journal_entry_obj?.content,
										description: $lq__journal_entry_obj?.description,
										tags: $lq__journal_entry_obj?.tags
									};

									journals_func
										.create_ae_obj__journal_entry({
											api_cfg: $ae_api,
											journal_id: $lq__journal_entry_obj?.journal_id,
											data_kv: data_kv,
											log_lvl: log_lvl
										})
										.then((result) => {
											alert('Journal entry cloned successfully!');
											goto(
												`/journals/${result.journal_id_random}/entry/${result.journal_entry_id_random}`
											);
										})
										.catch((error) => {
											console.error('Error cloning journal entry:', error);
											alert('Failed to clone journal entry.');
										});
								}}
								class="btn btn-sm w-full mb-2 p-1 preset-tonal-secondary hover:preset-filled-secondary-500 *:hover:inline lg:text-xs"
								title="Clone this journal entry"
							>
								<!-- class="btn btn-sm variant-soft-surface hover:variant-filled-warning transition py-1 px-2" -->
								<!-- <Copy strokeWidth="1" /> -->
								<Copy size="2em" />
								<span class="hidden md:inline"> Clone Entry </span>
							</button>
						</div>

						<!-- Journal Entry history information and options -->
						<!-- If there is history, then we want a toggle button to show and hide the history. -->
						{#if $lq__journal_entry_obj?.history || $lq__journal_entry_obj?.history_encrypted}
							<div
								class="
                    flex flex-row-reverse flex-wrap gap-1 items-center justify-center
                    "
							>
								<button
									type="button"
									onclick={async () => {
										if (!$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]) {
											$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] =
												'history';
											$journals_sess.show__content__journal_entry_history = 'view';
										} else if (
											$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] ==
											'current'
										) {
											$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] =
												'history';
											$journals_sess.show__content__journal_entry_history = 'view';
										} else if (
											$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] ==
											'history'
										) {
											$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = false;
										} else {
											$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = false;
										}

										// if ($journals_sess.show__content__journal_entry_history == 'view') {
										//     $journals_sess.show__content__journal_entry_history = 'hide';
										// } else if ($journals_sess.show__content__journal_entry_history == 'edit') {
										//     $journals_sess.show__content__journal_entry_history = 'hide';
										// } else if ($journals_sess.show__content__journal_entry_history == 'hide') {
										//     $journals_sess.show__content__journal_entry_history = 'view';
										// } else if (!$journals_sess.show__content__journal_entry_history) {
										//     $journals_sess.show__content__journal_entry_history = 'view';
										// }

										// !tmp_entry_obj?.history &&
										if (tmp_entry_obj?.history_encrypted) {
											decrypted_history = await ae_util.decrypt_wrapper(
												tmp_entry_obj?.history_encrypted,
												journal_key
											);
											// decrypted_history = await handle_decrypt_string(tmp_entry_obj.history_encrypted, journal_key);
											console.log('Decrypted history:', decrypted_history);
											tmp_entry_obj.history = decrypted_history;
										}
									}}
									class:preset-filled-secondary-500={$journals_loc.entry.edit_kv[
										$lq__journal_entry_obj?.journal_entry_id
									] == 'history'}
									class:preset-tonal-secondary={$journals_loc.entry.edit_kv[
										$lq__journal_entry_obj?.journal_entry_id
									] != 'history'}
									class="btn btn-sm hover:preset-filled-secondary-500 *:hover:inline lg:text-xs w-full"
									title="Toggle history of this journal entry"
								>
									{#if !$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] || $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] == 'current'}
										<History strokeWidth="1" color="gray" />
									{:else if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] == 'history'}
										<History strokeWidth="2.5" color="red" />
									{/if}
									<!-- <History strokeWidth="2.5" color="blue" /> -->
									<span class="hidden sm:inline text-sm"> Review History</span>
								</button>

								<button
									type="button"
									class:hidden={!(
										$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] ==
										'history'
									)}
									onclick={async () => {
										if (
											!$journals_sess?.show__content__journal_entry_history ||
											$journals_sess.show__content__journal_entry_history == 'view'
										) {
											$journals_sess.show__content__journal_entry_history = 'edit';
										} else if ($journals_sess.show__content__journal_entry_history == 'edit') {
											$journals_sess.show__content__journal_entry_history = 'view';
										}
										console.log(
											'History edit mode:',
											$journals_sess.show__content__journal_entry_history
										);

										if (tmp_entry_obj?.history_encrypted) {
											let history_cleaned: null | string = null;
											let history_md_html: null | string = null;

											decrypted_history = await ae_util.decrypt_wrapper(
												tmp_entry_obj?.history_encrypted,
												journal_key
											);

											// decrypted_history = await handle_decrypt_string(tmp_entry_obj.history_encrypted, journal_key);
											console.log('Decrypted history:', decrypted_history);
											tmp_entry_obj.history = decrypted_history;

											history_cleaned = decrypted_history.replace(
												/^[\u200B\u200C\u200D\u200E\u200F\uFEFF]/,
												''
											);
											history_md_html = (await marked.parse(history_cleaned ?? '')) ?? null;
											tmp_entry_obj.history_md_html = history_md_html;
											// console.log('History cleaned:', history_cleaned);
											console.log('History md html:', history_md_html);
										}
									}}
									class="btn btn-sm preset-tonal-secondary hover:preset-filled-secondary-500 *:hover:inline lg:text-xs"
									title="Toggle edit mode for history of this journal entry"
								>
									{#if !$journals_sess?.show__content__journal_entry_history || $journals_sess?.show__content__journal_entry_history == 'view'}
										<Pencil strokeWidth="2.5" color="blue" class="inline-block" />
									{:else if $journals_sess?.show__content__journal_entry_history == 'edit'}
										<PenLine strokeWidth="2.5" color="red" class="inline-block" />
									{/if}
									<span class="hidden sm:inline">
										{#if !$journals_sess?.show__content__journal_entry_history || $journals_sess?.show__content__journal_entry_history == 'view'}
											Edit?
										{:else if $journals_sess.show__content__journal_entry_history == 'edit'}
											View?
										{/if}
									</span>
								</button>
							</div>
						{/if}

						<!-- Button to call OpenAI API endpoint to summarize the content. -->
						<div
							class="
                flex flex-row-reverse flex-wrap gap-1 items-center justify-center
                "
						>
							<button
								type="button"
								onclick={async () => {
									const ai_client = new OpenAI({
										apiKey: $journals_loc?.llm__api_token,
										baseURL: $journals_loc?.llm__api_base_url,
										dangerouslyAllowBrowser: $journals_loc?.llm__api_dangerous_browser
									});

									// let resp__models = ai_client.models.list();
									// console.log('AI API Response (models)', resp__models);

									// let msg_role_system_content = $journals_loc?.entry?.llm__system_prompt || 'You are a helpful assistant that helps people find information.';
									// let msg_role_user_content = 'Why is the sky blue?';
									let msg_role_user_content = tmp_entry_obj?.content;

									try {
										ae_promises = ai_client.chat.completions
											.create({
												model: $journals_loc?.llm__api_model,
												messages: [
													{
														role: 'system',
														content:
															$journals_loc?.entry?.llm__system_prompt ||
															'You are a helpful assistant that helps people find information.'
													},
													{ role: 'user', content: msg_role_user_content }
												]
												// max_tokens: 512,
												// temperature: 0.7,
												// stream: true,
											})
											.then((resp__chat) => {
												console.log('AI API Response (chat)', resp__chat);
												console.log('AI API Response (chat)', resp__chat);

												console.log('resp msg 0 = ', resp__chat?.choices?.[0]?.message?.content);

												$journals_sess.entry.ai_summary =
													resp__chat?.choices?.[0]?.message?.content || 'No summary available';

												$journals_sess.entry.show__ai_summary = true;
												return;
											});
									} catch (err) {
										console.error('Error from chat completion:', err);
										alert('Error from chat completion: ' + (err?.message || err));
									}
								}}
								class="
                        btn btn-sm
                        preset-outlined-warning-200-800
                    "
								title="Generate AI summary of this journal entry"
							>
								{#await ae_promises}
									<Loader class="inline-block mr-1 animate-spin" />
									<span class="text-sm">Summarizing...</span>
								{:then}
									<BotMessageSquare class="inline-block mr-1" />
									<span class="text-sm">Summarize</span>
								{:catch error}
									<span class="text-sm">Error</span>
								{/await}
							</button>

							{#if !$journals_sess?.entry?.show__ai_summary && $journals_sess?.entry?.ai_summary}
								<button
									type="button"
									onclick={() => {
										$journals_sess.entry.show__ai_summary = true;
									}}
									class="
                        btn btn-sm
                        preset-outlined-warning-200-800

                        "
									title="Show AI summary of this journal entry"
								>
									<Bot class="inline-block mr-1" />
									<span class="text-sm"> Show</span>
								</button>
							{:else if !$journals_sess?.entry?.show__ai_summary && $lq__journal_entry_obj?.summary}
								<button
									type="button"
									onclick={() => {
										$journals_sess.entry.ai_summary = $lq__journal_entry_obj?.summary;
										$journals_sess.entry.show__ai_summary = true;
									}}
									class="
                        btn btn-sm
                        preset-outlined-warning-200-800
                        transition-all
                        "
									title="Show saved summary of this journal entry"
								>
									<FileText strokeWidth="1" class="inline-block mr-1" />
									Use Saved Summary
								</button>
							{/if}
						</div>

						<div class="divider my-2"></div>

						<!-- Core Object Properties -->
						<div>
							<!-- Set/unset priority (boolean) -->
							<button
								type="button"
								onclick={() => {
									tmp_entry_obj.priority = !$lq__journal_entry_obj?.priority;
									update_journal_entry();
								}}
								class="btn w-full mb-2 preset-tonal-tertiary transition hover:preset-filled-tertiary-500"
								title="Toggle priority of this journal entry"
							>
								{#if $lq__journal_entry_obj?.priority}
									<Flag strokeWidth="2.5" color="green" class="inline-block" />
								{:else}
									<FlagOff strokeWidth="1" color="gray" class="inline-block" />
								{/if}
								<span class="hidden lg:inline"> Priority </span>
							</button>

							<!-- Set sort order (number) -->
							<span
								class:hidden={!$ae_loc.edit_mode}
								class="w-full mb-2 flex flex-row flex-wrap items-center justify-center border border-gray-300 rounded-lg"
							>
								<button
									type="button"
									onclick={() => {
										console.log('Incrementing sort order');
										tmp_entry_obj.sort = $lq__journal_entry_obj?.sort
											? $lq__journal_entry_obj?.sort + 1
											: 1;
										console.log('Incremented sort order:', tmp_entry_obj.sort);
										update_journal_entry();
									}}
									class="btn-icon-sm preset-tonal-tertiary transition hover:preset-filled-tertiary-500"
									title="Increment sort order of this journal entry"
								>
									<Plus strokeWidth="2.5" color="blue" />
								</button>
								<span class="mx-1">
									{#if $lq__journal_entry_obj?.sort}
										{$lq__journal_entry_obj.sort}
									{:else}
										<!-- <ArrowDown01 /> -->
										<ArrowDown10 />
									{/if}
								</span>
								<button
									type="button"
									onclick={() => {
										console.log('Decrementing sort order');
										tmp_entry_obj.sort = $lq__journal_entry_obj?.sort
											? $lq__journal_entry_obj?.sort - 1
											: 0;
										console.log('Decremented sort order:', tmp_entry_obj.sort);
										update_journal_entry();
									}}
									class="btn-icon-sm preset-tonal-tertiary transition hover:preset-filled-tertiary-500"
									title="Decrement sort order of this journal entry"
								>
									<Minus strokeWidth="2.5" color="blue" />
								</button>
							</span>

							<!-- Set group (string) -->
							<input
								type="text"
								bind:value={tmp_entry_obj.group}
								placeholder="Group"
								onchange={() => {
									update_journal_entry();
								}}
								class:hidden={!$ae_loc.edit_mode}
								class="input input-sm input-bordered w-full mb-2"
								title="Set group (for sorting) of this journal entry"
							/>

							<!-- Set archive datetime (string) -->
							<span
								class="w-full mb-2 flex flex-row flex-wrap items-center justify-center border border-gray-200 rounded-lg"
							>
								<input
									type="datetime-local"
									bind:value={tmp_entry_obj.archive_on}
									placeholder="Archive On"
									onchange={() => {
										update_journal_entry();
									}}
									class:hidden={!$ae_loc.edit_mode}
									class="input input-sm input-bordered w-auto border-none"
									title="Set archive on datetime for archiving this journal entry"
								/>

								{#if $lq__journal_entry_obj?.archive_on}
									<!-- Button to clear the datetime -->
									<button
										type="button"
										onclick={() => {
											tmp_entry_obj.archive_on = null;
											update_journal_entry();
										}}
										class:hidden={!$ae_loc.edit_mode}
										class="btn btn-icon btn-icon-sm preset-tonal-warning hover:preset-filled-warning-500 transition *:hover:inline"
										title="Clear the archive on datetime for this journal entry"
									>
										<X strokeWidth="2.5" color="red" />
										<!-- <span class="hidden">Clear Archive</span> -->
									</button>
								{:else}
									<!-- Button to set the datetime to now -->
									<button
										type="button"
										onclick={() => {
											// tmp_entry_obj.archive_on = new Date().toISOString();
											// console.log('Archive on datetime set to now:', tmp_entry_obj.archive_on);
											tmp_entry_obj = {
												...tmp_entry_obj,
												archive_on: new Date().toISOString()
											};
											console.log('Archive on datetime set to now:', tmp_entry_obj.archive_on);
											update_journal_entry();
										}}
										class:hidden={!$ae_loc.edit_mode}
										class="btn btn-icon btn-icon-sm preset-tonal-warning hover:preset-filled-warning-500 transition *:hover:inline"
										title="Set the archive on datetime for this journal entry"
									>
										<Clock strokeWidth="2.5" color="blue" />
										<!-- <span class="hidden">Set Archive</span> -->
									</button>
								{/if}
							</span>

							<!-- Set/unset hide (boolean) -->
							<button
								type="button"
								onclick={() => {
									tmp_entry_obj.hide = !$lq__journal_entry_obj?.hide;
									update_journal_entry();
								}}
								class="btn btn-sm md:btn-md w-full mb-2 preset-tonal-warning hover:preset-filled-warning-500 transition"
								title="Toggle visibility of this journal entry"
							>
								{#if $lq__journal_entry_obj?.hide}
									<EyeOff strokeWidth="1" color="red" class="inline-block" />
									<span class="hidden md:inline">Hidden</span>
								{:else}
									<Eye strokeWidth="2.5" color="green" class="inline-block" />
									<span class="hidden md:inline">Visible</span>
								{/if}
							</button>

							<!-- Set/unset enable (boolean) -->
							<button
								type="button"
								onclick={() => {
									tmp_entry_obj.enable = !$lq__journal_entry_obj?.enable;
									update_journal_entry();
								}}
								class:hidden={!$ae_loc.administrator_access || !$ae_loc.edit_mode}
								class="btn btn-sm md:btn-md w-full mb-2 preset-tonal-error hover:preset-filled-error-500 transition"
								title="Toggle enable status of this journal entry"
							>
								{#if $lq__journal_entry_obj?.enable}
									<ShieldCheck strokeWidth="2.5" color="green" class="inline-block" />
									<span class="hidden md:inline">Enabled</span>
								{:else}
									<ShieldMinus strokeWidth="1" color="red" class="inline-block" />
									<span class="hidden md:inline">Disabled</span>
								{/if}
							</button>

							<!-- Delete journal entry -->
							<button
								type="button"
								onclick={() => {
									if (confirm(`Are you sure you want to delete this journal entry?`)) {
										let delete_method = 'disable';
										if ($ae_loc.administrator_access && $ae_loc.edit_mode) {
											delete_method = 'delete';
										}
										journals_func
											.delete_ae_obj_id__journal_entry({
												api_cfg: $ae_api,
												journal_entry_id: $lq__journal_entry_obj?.journal_entry_id,
												method: delete_method, // 'delete', 'disable', 'hide'
												log_lvl: log_lvl
											})
											.then(() => {
												// Optionally, you can provide feedback to the user
												alert('Journal entry deleted successfully!');
											})
											.catch((error) => {
												console.error('Error deleting journal entry:', error);
												alert('Failed to delete journal entry.');
											})
											.finally(() => {
												goto(`/journals/${$journals_slct.journal_id}`);
												// $journals_slct.journal_id = null;
												// $journals_slct.journal_obj = null;
											});
									}
								}}
								class:hidden={!$ae_loc.edit_mode}
								class="btn btn-sm md:btn-md w-full mb-2 preset-tonal-error hover:preset-filled-error-500 transition"
								title="Delete this journal entry"
							>
								{#if $ae_loc.administrator_access && $ae_loc.edit_mode}
									<FileX strokeWidth="2.5" color="red" class="inline-block" />
									<span class="hidden md:inline">Delete</span>
								{:else}
									<Trash2 strokeWidth="2.5" color="orange" class="inline-block" />
									<span class="hidden md:inline">Remove</span>
								{/if}
							</button>
						</div>

						<!-- Select option list of Journals to choose from. This is used to assign the Journal Entry to a different Journal ID. -->
						{#if $ae_loc.edit_mode && $lq__journal_obj_li?.length}
							<div
								class="w-full flex flex-row flex-wrap gap-2 items-center justify-start border border-gray-200 rounded-lg"
							>
								<span class="w-full text-center">
									<SquareLibrary size="1em" class="mx-1 inline-block" />
									<span class="text-sm text-gray-500 hidden sm:inline"> Move to Journal: </span>
								</span>

								<select
									class="btn btn-secondary btn-sm
                    preset-tonal-primary
                    hover:preset-filled-primary-500
                    transition
                    text-xs
                    border-none
                    w-full
                    "
									bind:value={tmp_entry_obj.journal_id}
									onchange={(event) => {
										tmp_entry_obj.journal_id = event.target.value;
										console.log('Selected journal:', tmp_entry_obj.journal_id);
										if (confirm(`Are you sure you want to change the journal for this entry?`)) {
											change_journal_id();
										}
									}}
									title="Select a different journal for this entry"
								>
									<option value="">Select Journal</option>
									{#each $lq__journal_obj_li as journal}
										<option value={journal.journal_id} title={`Journal: ${journal.name}`}>
											{journal.name}
										</option>
									{/each}
								</select>
							</div>
						{/if}
					</div>
					<!-- {/if} -->
				</section>
			</div>
		</header>

		<!-- <section
    class="flex flex-row flex-wrap gap-1 items-center justify-between w-full"
    >





</section> -->

		<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
		<!-- ondblclick={() => {
    if ($ae_loc.trusted_access && $ae_loc.edit_mode) {
        // Toggle edit mode
        $journals_loc.entry.edit = !$journals_loc.entry.edit;
        $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
    }
}}
role={$ae_loc.edit_mode ? 'button' : 'article'}
tabindex={$ae_loc.edit_mode ? 0 : -1} -->
		<section
			class="
        grow
        basis-full
        flex flex-col flex-wrap gap-1 items-center justify-center
        h-full min-h-max max-h-full
        w-full max-w-6xl
        relative
        bg-gray-100 dark:bg-gray-800
        p-1 rounded-lg shadow-md
        "
			class:bg-yellow-50={$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] ==
				'current'}
			class:dark:bg-yellow-950={$journals_loc.entry.edit_kv[
				$lq__journal_entry_obj?.journal_entry_id
			] == 'current'}
		>
			{#if $journals_sess?.entry?.ai_summary}
				<button
					type="button"
					onclick={() => {
						$journals_sess.entry.show__ai_summary = !$journals_sess.entry.show__ai_summary;
					}}
					class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500 transition-all absolute top-2 right-2 z-10"
					title="Toggle AI Summary"
				>
					<Bot class="inline-block mr-1" />
					<span class="hidden sm:inline">AI Summary</span>
					{#if $journals_sess?.entry?.ai_summary}
						<span class="badge badge-sm badge-secondary ml-1">
							{$journals_sess?.entry?.ai_summary.split(' ').length} words
						</span>
					{/if}
				</button>
			{:else if !$journals_sess?.entry?.show__ai_summary && $journals_sess?.entry?.ai_summary}
				<button
					type="button"
					onclick={() => {
						const ai_client = new OpenAI({
							apiKey: $journals_loc?.llm__api_token,
							baseURL: $journals_loc?.llm__api_base_url,
							dangerouslyAllowBrowser: $journals_loc?.llm__api_dangerous_browser
						});

						// let resp__models = ai_client.models.list();
						// console.log('AI API Response (models)', resp__models);

						// let msg_role_system_content = $journals_loc?.entry?.llm__system_prompt || 'You are a helpful assistant that helps people find information.';
						// let msg_role_user_content = 'Why is the sky blue?';
						let msg_role_user_content = tmp_entry_obj?.content;

						try {
							ae_promises = ai_client.chat.completions
								.create({
									model: $journals_loc?.llm__api_model,
									messages: [
										{
											role: 'system',
											content:
												$journals_loc?.entry?.llm__system_prompt ||
												'You are a helpful assistant that helps people find information.'
										},
										{ role: 'user', content: msg_role_user_content }
									]
									// max_tokens: 512,
									// temperature: 0.7,
									// stream: true,
								})
								.then((resp__chat) => {
									console.log('AI API Response (chat)', resp__chat);
									console.log('AI API Response (chat)', resp__chat);

									console.log('resp msg 0 = ', resp__chat?.choices?.[0]?.message?.content);

									$journals_sess.entry.ai_summary =
										resp__chat?.choices?.[0]?.message?.content || 'No summary available';

									$journals_sess.entry.show__ai_summary = true;
									return;
								});
						} catch (err) {
							console.error('Error from chat completion:', err);
							alert('Error from chat completion: ' + (err?.message || err));
						}
					}}
					class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500 transition-all absolute top-2 right-2 z-10"
					title="Generate AI summary of this journal entry"
				>
					{#await ae_promises}
						<Loader class="inline-block mr-1 animate-spin" />
						<span class="text-sm">Summarizing...</span>
					{:then}
						<BotMessageSquare class="inline-block mr-1" />
						<span class="text-sm">Summarize</span>
					{:catch error}
						<span class="text-sm">Error</span>
					{/await}
				</button>
			{:else if !$journals_sess?.entry?.show__ai_summary && $lq__journal_entry_obj?.summary}
				<button
					type="button"
					onclick={() => {
						$journals_sess.entry.ai_summary = $lq__journal_entry_obj?.summary;
						$journals_sess.entry.show__ai_summary = true;
					}}
					class="
                    btn btn-sm preset-tonal-primary hover:preset-filled-primary-500 transition-all absolute top-2 right-2 z-10
                    "
					title="Show saved summary of this journal entry"
				>
					<FileText strokeWidth="1" class="inline-block mr-1" />
					Use Saved Summary
				</button>
			{/if}

			{#if !$journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id]}
				{#if $lq__journal_obj?.cfg_json?.pref_viewer == 'codemirror'}
					<E_app_codemirror_v5
						editable={false}
						readonly={true}
						content={tmp_entry_obj?.content ?? ''}
						bind:new_content={tmp_entry_obj.content}
						bind:theme_mode={$ae_loc.theme_mode}
						placeholder="Write using Markdown here..."
						class="
                p-2
                preset-outlined-success-400-600
                hover:preset-tonal-surface
                shadow-lg rounded-lg
                "
					/>
				{:else if $lq__journal_obj?.cfg_json?.pref_viewer == 'plain'}
					<pre
						class="
                grow
                basis-full
                h-full min-h-max max-h-full
                w-full min-w-full max-w-6xl
                p-2
                space-y-1
                font-mono
                text-wrap
                bg-slate-100! text-gray-900!
                dark:bg-slate-900! dark:text-gray-100!
                dark:prose-invert
                shadow-md rounded-lg
                border border-gray-200 dark:border-gray-700
                hover:border-green-500 dark:hover:border-green-500
                ">
                {#if tmp_entry_obj.content}
							{tmp_entry_obj.content}
						{/if}
        </pre>
				{:else}
					<!-- rendered has HTML -->
					<article
						class="
                grow
                basis-full
                h-full min-h-max max-h-full
                w-full min-w-full max-w-6xl
                p-2
                space-y-1
                font-mono
                bg-slate-100! text-gray-900!
                dark:bg-slate-900! dark:text-gray-100!
                dark:prose-invert
                shadow-md rounded-lg
                border border-gray-200 dark:border-gray-700
                hover:border-green-500 dark:hover:border-green-500
                prose
                prose-h1:underline prose-h1:decoration-double
                prose-h2:underline
                prose-h1:text-2xl prose-h2:text-xl prose-h3:text-lg
                prose-h1:m-0 prose-h2:m-0 prose-h3:m-0 prose-h4:m-0 prose-h5:m-0 prose-h6:m-0
                prose-li:m-0 prose-li:p-0 prose-li:line-height-none
                "
						id="rendered_journal_entry_content_{$lq__journal_entry_obj?.journal_entry_id}"
					>
						{#if tmp_entry_obj.content_md_html}
							{@html tmp_entry_obj.content_md_html}
						{:else if tmp_entry_obj?.content_encrypted && tmp_entry_obj?.private}
							<div class="text-sm text-gray-500">
								<div class="">
									<LockKeyhole strokeWidth="1.5" color="green" class="inline-block" /> Encrypted:
								</div>

								<div class="max-w-(--breakpoint-md) overflow-auto wrap break-all">
									{tmp_entry_obj?.content_encrypted}
								</div>
							</div>
						{/if}
						<!-- {#if decrypted_content?.length}
                {@html decrypted_content}
            {:else if $lq__journal_entry_obj?.content_encrypted}
                <span class="text-sm text-gray-500 break-all">
                {@html $lq__journal_entry_obj?.content_encrypted}
                </span>
            {:else}
                {@html $lq__journal_entry_obj?.content_md_html}
            {/if} -->
					</article>
				{/if}
				<!-- {@html async () => {
        const { base64, iv } = await encrypt_content(content, journal_key);
        // console.log('Encrypted content:', base64);
        // console.log('IV:', iv);
        const decryptedContent = await decrypt_content(base64, iv, journal_key);
        // console.log('Decrypted content:', decryptedContent);
        return base64;
    }} -->

				<!-- {@html encrypt_content($lq__journal_entry_obj?.content, journal_key)} -->
				<!-- --{@html encrypted_base64_string}-- -->
				<!-- {@html marked.parse($lq__journal_entry_obj?.content)} -->

				{#if $lq__journal_entry_obj?.data_json?.hosted_file_kv}
					<div class="flex flex-row flex-wrap gap-1 items-center justify-center w-full">
						<span class="">
							<!-- <SquareDownload size="1em" class="mx-1 inline-block"/> -->
							<FileDown size="1em" class="mx-1 inline-block" />
							<span class="text-sm text-gray-500 hidden sm:inline"> Download Files: </span>
						</span>

						{#each Object.entries($lq__journal_entry_obj?.data_json?.hosted_file_kv) as [key, hosted_file_obj]}
							<Comp_hosted_files_download_button
								hosted_file_id={hosted_file_obj?.hosted_file_id_random ?? ''}
								{hosted_file_obj}
								linked_to_type="journal_entry"
								linked_to_id={$lq__journal_entry_obj?.journal_entry_id}
							/>
						{/each}
					</div>
				{/if}
			{:else if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] == 'current'}
				<!-- && !($lq__journal_entry_obj?.content_encrypted && decrypted_content)) -->
				<!-- class="flex flex-row flex-wrap gap-1 items-center justify-center w-full max-w-sm" -->

				{#if !tmp_entry_obj?.content && tmp_entry_obj?.content_encrypted}
					<div
						class="
                grow
                basis-full
                h-full min-h-max max-h-full
                w-full min-w-full max-w-6xl
                p-2
                space-y-1
                bg-red-100 text-gray-900
                dark:bg-red-900 dark:text-gray-100
                shadow-lg rounded-lg
                border border-red-200 dark:border-red-700
                hover:border-red-500 dark:hover:border-red-500
                "
					>
						<div>The entry must be decrypted before it can be edited.</div>
						{#if tmp_entry_obj?.content === false && $journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified}
							<div class="text-sm text-red-500">
								<LockKeyhole strokeWidth="1.5" color="red" class="inline-block" />
								Decryption failed. Check the passcode(s).
							</div>
						{:else if tmp_entry_obj?.content === false}
							<div class="text-sm text-red-500">
								<LockKeyhole strokeWidth="1.5" color="red" class="inline-block" />
								Decryption failed. You may need to enter the Journal's private passcode.
							</div>
						{/if}
						{#if tmp_entry_obj?.content === false && $lq__journal_obj?.id && $journals_sess?.journal_kv[$lq__journal_obj?.id]?.journal_passcode_verified}
							<div class="text-sm text-red-500">
								This might not be encoded with the private passcode or a passcode has changed?
							</div>
						{/if}
						<!-- <span class="text-sm text-gray-500">
                <Lock key={0} strokeWidth="2.5" color="red" />
                <span class="hidden sm:inline">Encrypted</span>
            </span>
            <button
                type="button"
                onclick={() => {
                    if ($ae_loc.trusted_access) {
                        trigger_decrypt = true;
                    }
                }}
                class="btn btn-sm variant-soft-secondary hover:variant-filled-secondary *:hover:inline lg:text-xs"
                title="Decrypt the content of this journal entry"
                >
                <LockOpen key={1} strokeWidth="2.5" color="green" />
                <span class="hidden sm:inline">Decrypt</span>
            </button> -->
					</div>
				{:else}
					<!-- <div
        class="
        grow
        h-full max-h-full
        w-full min-w-full max-w-6xl"
        > -->
					<!-- disabled={tmp_entry_obj?.private && !$journals_loc?.entry?.decrypt_kv[$lq__journal_entry_obj?.journal_entry_id]} -->

					{#if $lq__journal_obj?.cfg_json?.pref_editor == 'codemirror'}
						<!-- bg-slate-100 text-gray-900
            dark:bg-slate-900 dark:text-gray-100
            border border-orange-200 dark:border-orange-700
            hover:border-orange-500 dark:hover:border-orange-500 -->
						<E_app_codemirror_v5
							content={tmp_entry_obj?.content ?? ''}
							bind:new_content={tmp_entry_obj.content}
							bind:theme_mode={$ae_loc.theme_mode}
							placeholder="Write using Markdown here..."
							class="
                    p-2
                    preset-outlined-warning-300-700
                    shadow-lg rounded-lg
                    bg-gray-100 text-gray-950
                    dark:bg-gray-800 dark:text-gray-100
                    "
						/>
					{:else}
						<textarea
							bind:value={tmp_entry_obj.content}
							ondblclick={() => {
								// if ($ae_loc.trusted_access && $ae_loc.edit_mode) {
								//     // Toggle edit mode
								//     $journals_loc.entry.edit = !$journals_loc.entry.edit;
								//     $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] = $journals_loc.entry.edit;
								// }
							}}
							class="
                    grow
                    shrink-0
                    basis-full
                    h-max min-h-max max-h-full
                    w-full min-w-full max-w-6xl
                    p-2
                    space-y-1
                    font-mono
                    bg-slate-100 text-gray-900
                    dark:bg-slate-900 dark:text-gray-100
                    shadow-lg rounded-lg
                    border border-orange-200 dark:border-orange-700
                    hover:border-orange-500 dark:hover:border-orange-500
                    "
							placeholder="Edit journal entry content here..."
						></textarea>
					{/if}

					<!-- Only enable editing if the user has trusted access -->
					<button
						type="button"
						onclick={() => {
							update_journal_entry();
						}}
						disabled={!tmp_entry_obj_changed}
						class:invisible={!tmp_entry_obj_changed}
						class="
                btn btn-sm md:btn-md lg:btn-lg

                min-w-72 w-full lg:min-w-96
                max-w-96

                preset-outlined-warning-900-100
                preset-filled-warning-50-950

                hover:variant-outline-success-900-100
                hover:preset-filled-success-50-950
                "
					>
						<Save strokeWidth="1" class="inline-block" />
						Save Changes
					</button>

					<!-- Do a quick check to see if the updated_on timestamp has changed. Specifically, if the entry was updated since the last time it was loaded. -->
					{#if updated_idb}
						<span class="text-sm text-red-500">
							WARNING: IDB object has been updated since last load.
						</span>
					{/if}
					<!-- Updated: {orig_entry_obj?.updated_on}
        Updated obj? {updated_obj} -->

					<!-- && $lq__journal_entry_obj?.updated_on !== orig_entry_obj?.updated_on -->

					<!-- Using absolute or fixed position -->
					<button
						type="button"
						onclick={() => {
							update_journal_entry();
						}}
						disabled={!tmp_entry_obj_changed}
						class:hidden={!tmp_entry_obj_changed}
						class="
                btn btn-sm md:btn-md lg:btn-lg

                fixed top-96 md:top-72 right-6
                min-w-24 w-full lg:min-w-32
                max-w-40

                preset-outlined-warning-900-100
                preset-filled-warning-50-950

                hover:variant-outline-success-900-100
                hover:preset-filled-success-50-950

                "
					>
						<Save strokeWidth="1" class="inline-block" />
						Save Changes
					</button>

					<!-- </div> -->
				{/if}

				{#if $lq__journal_entry_obj?.journal_entry_id}
					<Comp_journal_entry_file_li
						{log_lvl}
						link_to_type="journal_entry"
						link_to_id={$lq__journal_entry_obj?.journal_entry_id}
						{lq__journal_entry_obj}
					/>

					<!-- Object.keys(hosted_file_kv ?? {}).length -->
					{#if $lq__journal_entry_obj?.data_json?.hosted_file_kv}
						<div class="flex flex-row flex-wrap gap-1 items-center justify-center w-full">
							<span class="">
								<!-- <SquareDownload size="1em" class="mx-1 inline-block"/> -->
								<FileDown size="1em" class="mx-1 inline-block" />
								<span class="text-sm text-gray-500 hidden sm:inline"> Download Files: </span>
							</span>

							{#each Object.entries($lq__journal_entry_obj?.data_json?.hosted_file_kv) as [key, hosted_file_obj]}
								<Comp_hosted_files_download_button
									hosted_file_id={hosted_file_obj?.hosted_file_id_random ?? ''}
									{hosted_file_obj}
									linked_to_type="journal_entry"
									linked_to_id={$lq__journal_entry_obj?.journal_entry_id}
								/>
							{/each}
						</div>
					{/if}
				{:else}
					<section
						class="ae_section journal_entry__hosted_file border border-gray-200 rounded p-2 space-y-2"
					>
						<span class="fas fa-exclamation-triangle text-red-500"></span>
						Save the form first before uploading a file.
					</section>
				{/if}
			{:else if $journals_loc.entry.edit_kv[$lq__journal_entry_obj?.journal_entry_id] == 'history'}
				<div
					class="
            grow
            basis-full
            flex flex-col items-center justify-center
            h-full
            w-full max-w-6xl
            "
				>
					{#if $journals_sess?.show__content__journal_entry_history == 'view'}
						<!-- <article
                class="
                    grow
                    space-y-1
                    h-full min-h-max max-h-full
                    w-full min-w-full max-w-6xl
                    p-2
                    font-mono
                    bg-slate-100! text-gray-900!
                    dark:bg-slate-900! dark:text-gray-100!
                    dark:prose-invert
                    shadow-md rounded-lg
                    border border-gray-200 dark:border-gray-700
                    hover:border-gray-500 dark:hover:border-gray-500
                    prose
                    prose-h1:underline prose-h1:decoration-double
                    prose-h2:underline
                    prose-h1:text-2xl prose-h2:text-xl prose-h3:text-lg
                    prose-h1:m-0 prose-h2:m-0 prose-h3:m-0 prose-h4:m-0 prose-h5:m-0 prose-h6:m-0
                    prose-li:m-0 prose-li:p-0 prose-li:line-height-none
                    "
                >
                {@html tmp_entry_obj?.history_md_html}
            </article> -->

						<E_app_codemirror_v5
							editable={false}
							readonly={true}
							content={tmp_entry_obj?.history ?? ''}
							bind:new_content={tmp_entry_obj.history}
							bind:theme_mode={$ae_loc.theme_mode}
							placeholder="Write using Markdown here..."
							class="
                    p-2
                    preset-outlined-success-400-600
                    hover:preset-tonal-surface
                    shadow-lg rounded-lg
                    "
						/>
					{:else if $journals_sess?.show__content__journal_entry_history == 'edit'}
						<!-- <textarea
                bind:value={tmp_entry_obj.history}
                class="
                    space-y-1
                    grow
                    basis-full
                    h-full min-h-max max-h-full
                    w-full min-w-full max-w-6xl
                    p-2
                    font-mono
                    bg-slate-100 text-gray-900
                    dark:bg-slate-900 dark:text-gray-100
                    shadow-lg rounded-lg
                    border border-orange-200 dark:border-orange-700
                    hover:border-orange-500 dark:hover:border-orange-500
                    "
                placeholder="Edit journal entry content here..."
                ></textarea> -->

						<E_app_codemirror_v5
							content={tmp_entry_obj?.history ?? ''}
							bind:new_content={tmp_entry_obj.history}
							bind:theme_mode={$ae_loc.theme_mode}
							placeholder="Write using Markdown here..."
							class="
                    p-2
                    preset-outlined-warning-300-700
                    shadow-lg rounded-lg
                    bg-gray-100 text-gray-950
                    dark:bg-gray-800 dark:text-gray-100
                    "
						/>
					{/if}
				</div>
			{/if}

			<!-- <div class="max-w-(--breakpoint-md) overflow-auto">
aaaa
{tmp_entry_obj?.content ?? '-- not set --'}
<hr>
{tmp_entry_obj?.content_encrypted ?? '-- not set --'}
zzzz
</div> -->
		</section>

		<!-- <div>
    {@html test_html}
</div> -->

		<!-- {#if $ae_loc.edit_mode && $ae_loc.trusted_access}
<div
    id="journal_entry_codemirror"
    class:hidden={!$ae_loc.edit_mode}
    > -->
		<!-- {cm_view} -->
		<!-- <CodeMirror bind:value class="editor" {...props} /> -->
		<!-- bind:value={cm_view} -->
		<!-- <E_app_codemirror
        classes="editor"
        /> -->
		<!-- bind:content={tmp_entry_obj.content} -->
		<!-- <E_app_codemirror_v5
        content={tmp_entry_obj?.content ?? ''}
        bind:new_content={tmp_entry_obj.content}
        language={markdown()}
        placeholder="Write your JavaScript code here..."
        /> -->

		<!-- <pre>
    {tmp_entry_obj.new_content}
    </pre> -->
		<!-- </div>
{/if} -->

		<section class="ae_meta flex flex-row flex-wrap gap-1 items-center justify-between w-full">
			<span class="flex flex-row items-center justify-center text-sm text-gray-500">
				{#if !$ae_loc.edit_mode}
					<span class="">
						{ae_util.iso_datetime_formatter(
							$lq__journal_entry_obj?.created_on,
							'datetime_iso_12_no_seconds'
						)}
						{$lq__journal_entry_obj?.updated_on
							? ` | Last updated: ${ae_util.iso_datetime_formatter($lq__journal_entry_obj?.updated_on, 'datetime_iso_12_no_seconds')}`
							: ''}
					</span>
				{:else}
					<span class="">
						{ae_util.iso_datetime_formatter($lq__journal_entry_obj?.created_on, 'datetime_iso_tz')}
						{$lq__journal_entry_obj?.updated_on
							? ` | Last updated: ${ae_util.iso_datetime_formatter($lq__journal_entry_obj?.updated_on, 'datetime_iso_tz')}`
							: ''}
					</span>
				{/if}
			</span>
		</section>

		{#if $journals_sess?.entry?.show__ai_summary && $journals_sess?.entry?.ai_summary}
			<Modal
				title="AI Summary"
				bind:open={$journals_sess.entry.show__ai_summary}
				autoclose={false}
				placement="top-center"
				size="md"
				class="top-center bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-200 rounded-lg border-gray-200 dark:border-gray-700 divide-gray-200 dark:divide-gray-700 shadow-md relative mx-auto w-full divide-y"
			>
				<div class="modal-box flex flex-col gap-2 items-center justify-center">
					<div class="flex flex-row flex-wrap gap-1 items-center justify-center w-full mb-2">
						<button
							type="button"
							class="btn btn-sm preset-tonal-success hover:preset-filled-success-500 transition-all"
							onclick={() => {
								tmp_entry_obj.summary = $journals_sess?.entry?.ai_summary || '';
								update_journal_entry();
							}}
							title="Save AI summary as Journal Entry summary"
						>
							<Save strokeWidth="1" class="inline-block mr-1" />
							Save
						</button>

						<button
							type="button"
							onclick={() => {
								$journals_sess.entry.show__ai_summary = !$journals_sess.entry.show__ai_summary;
							}}
							class="btn btn-sm preset-tonal-primary hover:preset-filled-primary-500 transition-all"
							title="Toggle AI Summary"
						>
							<Bot class="inline-block mr-1" />
							<span class="hidden sm:inline">AI Summary</span>
							{#if $journals_sess?.entry?.ai_summary}
								<span class="badge badge-sm badge-secondary ml-1">
									{$journals_sess?.entry?.ai_summary.split(' ').length} words
								</span>
							{/if}
						</button>

						<button
							type="button"
							onclick={async () => {
								const ai_client = new OpenAI({
									apiKey: $journals_loc?.llm__api_token,
									baseURL: $journals_loc?.llm__api_base_url,
									dangerouslyAllowBrowser: $journals_loc?.llm__api_dangerous_browser
								});

								// let resp__models = ai_client.models.list();
								// console.log('AI API Response (models)', resp__models);

								// let msg_role_system_content = $journals_loc?.entry?.llm__system_prompt || 'You are a helpful assistant that helps people find information.';
								// let msg_role_user_content = 'Why is the sky blue?';
								let msg_role_user_content = tmp_entry_obj?.content;

								try {
									ae_promises = ai_client.chat.completions
										.create({
											model: $journals_loc?.llm__api_model,
											messages: [
												{
													role: 'system',
													content:
														$journals_loc?.entry?.llm__system_prompt ||
														'You are a helpful assistant that helps people find information.'
												},
												{ role: 'user', content: msg_role_user_content }
											]
											// max_tokens: 512,
											// temperature: 0.7,
											// stream: true,
										})
										.then((resp__chat) => {
											console.log('AI API Response (chat)', resp__chat);
											console.log('AI API Response (chat)', resp__chat);

											console.log('resp msg 0 = ', resp__chat?.choices?.[0]?.message?.content);

											$journals_sess.entry.ai_summary =
												resp__chat?.choices?.[0]?.message?.content || 'No summary available';

											// $journals_sess.entry.show__ai_summary = true;
											return;
										});
								} catch (err) {
									console.error('Error from chat completion:', err);
									alert('Error from chat completion: ' + (err?.message || err));
								}
							}}
							class="
            btn btn-sm
            preset-outlined-warning-200-800
            transition-all
        "
							title="Generate AI summary of this journal entry"
						>
							{#await ae_promises}
								<Loader class="inline-block mr-1 animate-spin" />
								<span class="text-sm">Summarizing...</span>
							{:then}
								<BotMessageSquare class="inline-block mr-1" />
								<span class="text-sm">Re-Summarize</span>
							{:catch error}
								<span class="text-sm">Error</span>
							{/await}
						</button>

						<!-- Change System Prompt: -->
						<button
							type="button"
							class="btn btn-sm preset-outlined-primary-400-600 hover:preset-filled-secondary-500 transition"
							onclick={() => {
								$journals_sess.entry.hide__ai_summary = !$journals_sess.entry.hide__ai_summary;
							}}
						>
							<FilePenLine strokeWidth="1.5" class="inline-block mr-1" />
							Prompt
						</button>

						<label
							class:hidden={!$journals_sess.entry.hide__ai_summary}
							class="flex flex-col items-start justify-start gap-1 h-24"
						>
							LLM System Prompt for Journal Entry summarization:
							<E_app_codemirror_v5
								editable={true}
								readonly={false}
								content={$journals_loc?.entry?.llm__system_prompt}
								bind:new_content={$journals_loc.entry.llm__system_prompt}
								show_line_numbers={false}
								placeholder="LLM System Prompt"
								class="
                p-1
                preset-outlined-success-400-600
                shadow-lg rounded-lg
                "
								on:change={(e) => {
									$journals_loc.entry.llm__system_prompt = e.detail;
								}}
							/>
						</label>
					</div>

					<!-- <pre class="text-wrap">
    {@html $journals_sess.entry.ai_summary}
    </pre> -->

					<E_app_codemirror_v5
						editable={true}
						readonly={false}
						content={$journals_sess.entry.ai_summary ?? ''}
						bind:new_content={$journals_sess.entry.ai_summary}
						bind:theme_mode={$ae_loc.theme_mode}
						placeholder="Write using Markdown here..."
						class="
            p-2
            preset-outlined-success-400-600
            hover:preset-tonal-surface
            shadow-lg rounded-lg
            "
					/>
				</div>
			</Modal>
		{/if}
	{:else}
		<section class="ae_meta flex flex-row flex-wrap gap-1 items-center justify-center w-full">
			<span class="text-lg text-orange-900 dark:text-orange-100">
				The Journal Entry was not found or is not available to show.
			</span>
		</section>
	{/if}
</section>
