<script lang="ts">
	import { marked } from 'marked';
	import type { Message } from '$lib/Types';
	import { afterUpdate } from 'svelte';

	import CopyToClipBoardBtn from '../CopyToClipBoardBtn.svelte';

	export let message: Message;
	let html = '';
	let el: HTMLElement;

	const renderer = new marked.Renderer();

	// Add wrapper to code blocks
	renderer.code = (code, lang) => {
		return `
			<div class="code-block">
				<pre>
					<code class="language-${lang}">${code}</code>
				</pre>
			</div>
		`.replaceAll('\t', '');
	};

	const handleParsed = (err: Error | null, parsedHtml: string) => {
		if (err) {
			console.error(err);
		} else {
			html = parsedHtml;
		}
	};

	const options: marked.MarkedOptions = {
		...marked.getDefaults(),
		gfm: true,
		highlight: (code, lang, callback) => {
			import('highlight.js').then(
				({ default: hljs }) => {
					const language = hljs.getLanguage(lang);
					callback?.(null, hljs.highlightAuto(code, language?.aliases).value);
				},
				(err) => {
					console.error(err);
					callback?.(err);
				}
			);
		},
		renderer
	};

	$: marked(message.content, options, handleParsed);

	afterUpdate(() => {
		if (el) {
			const codeBlocks = el.querySelectorAll('.code-block');

			// Add copy to clipboard button to each code block
			codeBlocks.forEach((block) => {
				if (block.classList.contains('has-copy-btn')) return;

				new CopyToClipBoardBtn({
					target: block,
					props: {
						value: (block as HTMLElement).innerText ?? '',
						classNames: 'absolute top-2 right-2'
					}
				});
				block.classList.add('has-copy-btn');
			});
		}
	});
</script>

{#if message.from === 'assistant'}
	<div class="flex items-start justify-start gap-4 leading-relaxed">
		<img
			alt=""
			src="https://huggingface.co/avatars/2edb18bd0206c16b433841a47f53fa8e.svg"
			class="mt-5 w-3 h-3 flex-none rounded-full shadow-lg"
		/>
		<div
			class="group relative rounded-2xl px-5 py-3.5 border border-gray-100 bg-gradient-to-br from-gray-50 dark:from-gray-800/40 dark:border-gray-800 prose text-gray-600 dark:text-gray-300"
      bind:this={el}
		>
			{@html html}
		</div>
	</div>
{/if}
{#if message.from === 'user'}
	<div class="flex items-start justify-start gap-4">
		<div class="mt-5 w-3 h-3 flex-none rounded-full" />
		<div class="rounded-2xl px-5 py-3.5 text-gray-500 dark:text-gray-400">
			{message.content}
		</div>
	</div>
{/if}
