<script setup lang="ts">
import MarkdownIt from 'markdown-it'
import { BaseMessage, CometChat, MediaMessage, User } from '@cometchat/chat-sdk-javascript'
import DOMPurify from 'dompurify';
import { inject, ref } from 'vue';
import { CometChatTheme, fontHelper } from '@cometchat/uikit-resources';
import BccReplyPreview from "./BccReplyPreview.vue";
import BccImageBubble from './BccImageBubble.vue';
import { offlineStore } from '../offline';

const props = defineProps({
	text: {
		type: String,
		required: true
	},
	metadata: {
		type: Object
	},
	guid: {
		type: String,
		default: ""
	},
	mentionedUsers: {
    type: Array<User>
  },
	message: {
    type: MediaMessage,
    default: null
  },
	placeholderImage: {
    type: String,
    default: null
  },
	src: {
    type: String,
    default: null
  }
})

function toMarkdownHtml(str: string) {
	str = formatMentionsInText(str);

	const md = new MarkdownIt({
		breaks: true,
		typographer: true,
		linkify: true,
		html: true
	});

	str = md.render(str);

	str = DOMPurify.sanitize(str, {
		ALLOWED_TAGS: [
			"a", // links
			"ul", "ol", "li", // lists
			"p", // paragraphs
			"b", "strong", // bold
			"i", "em", // italics
			"u", // underline
			"s", // strikethrough
			"img", // images
			"blockquote", // indented text
			"hr", // horizontal line
			"pre", // constant width text
			"br", // newline 
			"div" // newline on mobile 
		]
	})

	return str
}

function formatMentionsInText(text: string) {
	return text.replace(/<@uid:(.*?)>/g, (_match: string, uid: string) => {
		const user = (props.mentionedUsers || []).find((user) => user.getUid() === uid);
		// Check if a userName exists for the given uid; if not, keep the original match
		if (user) {
			return `**${user.getName()}**`;
		} else {
			return `**@unknown**`;
		}
	});
}

let parentMsgRef = ref<BaseMessage>();
if (props.metadata?.replyToMessageId) {
	let guidString = props.guid?.toString()
	let group = offlineStore.getGroup(guidString)

	//for read only replies
	if (group != null && group?.hasJoined == undefined) {
		let message = offlineStore.getMessage(props.metadata.replyToMessageId).data
		
		if (message !== undefined) {
			if (message.type == CometChat.MESSAGE_TYPE.TEXT) {
				let text = new CometChat.TextMessage(message.receiver, message.data.text, message.receiverType)
				text.setData(message.data)
				parentMsgRef.value = text
			} else {
				let media = new CometChat.MediaMessage(message.receiver, {}, message.type, message.receiverType)
				media.setData(message.data)
				parentMsgRef.value = media
			}
		} else {
			parentMsgRef.value = new CometChat.TextMessage("","Cannot load message","")
		}
	} else {
		CometChat.getMessageDetails(props.metadata.replyToMessageId).then((msg: BaseMessage) => parentMsgRef.value = msg).catch(() => parentMsgRef.value = new CometChat.TextMessage("","Unknown message",""));
	}
};

const { theme } = inject("theme", { theme: ref(new CometChatTheme({})) });
const replyPreviewStyle = {
	previewWrapperPadding: "6px 12px 6px 9px",
	barLeftPosition: "0px",
	titleColor: theme.value.palette.getAccent800(),
	subtitleColor: theme.value.palette.getAccent800(),
	titleFont: fontHelper(theme.value.typography.title2),
};
</script>

<template>
	<div class="bcc-message-wrapper" :class="{'has-text': text, 'has-image': src != null}" >
		<div v-if="metadata?.replyToMessageId" class="bcc-chat-msg-bubble">
			<div class="bcc-chat-msg-bubble--reply">
				<BccReplyPreview
					:replyToMessage="parentMsgRef"
					:previewStyle="replyPreviewStyle"
				/>
			</div>
		</div>
		<div v-if="src != null" class="bcc-chat-img-msg-bubble">
			<BccImageBubble
				:message="message"
				:placeholderImage="placeholderImage" 
				:src="src"
			/>
		</div>
		<div v-if="text && metadata && metadata.translated_message" v-html="toMarkdownHtml(metadata.translated_message)"
			class="bcc-chat-msg-bubble bcc-chat-msg-bubble--translation" />
		<div v-if="text" v-html="toMarkdownHtml(text)" class="bcc-chat-msg-bubble"
			:class="{ 'bcc-chat-msg-bubble--translated': metadata && !!metadata.translated_message }" />
	</div>
</template>

<style lang="scss">
.bcc-chat-img-msg-bubble {
	display: block;
	width: max-content;
	max-width: 100%;
	margin: 0 auto;
	border-radius: 8px;
	padding-bottom: 8px;
	position: relative;

	&:last-child {
		padding-bottom: 0;
	}
}
.bcc-chat-msg-bubble {
	padding: 0 12px 8px;
	width: auto;
	max-width: 500px;
	line-height: 1.2;
	font: 400 14px Archivo, sans-serif, Inter;
	color: var(--cc__text-color);

	&:first-child {
		padding-top: 8px;
	}

	p {
		color: var(--cc__text-color);
		line-height: 1.2;
		word-break: break-word;
		text-align: left;
		white-space: normal;
		margin: 8px 0;
	}

	p:first-child {
		margin-top: 0;
	}

	p:last-child {
		margin-bottom: 0;
	}

	h1 {
		font-size: 1.6em;
		font-weight: 800;
	}

	h2 {
		font-size: 1.4em;
		font-weight: 700;
	}

	h3 {
		font-size: 1.2em;
		font-weight: 600;
	}

	h4 {
		font-size: 1em;
		font-weight: 500;
	}

	a {
		color: var(--cc__link-color);
		text-decoration: underline;
		font-weight: 500;
	}

	ul {
		padding-left: 16px;
		list-style: disc;
		margin: 8px 0;
	}

	ol {
		padding-left: 16px;
		list-style: decimal;
		margin: 8px 0;
	}

	&--translated {
		border-top: 1px solid;
		opacity: 0.8;

		&:before {
			content: 'original: ';
			opacity: 0.8;
			margin-bottom: 8px;
			font-size: 12px;
			display: block;
		}
	}

	&--reply {
		position: relative;
		z-index: 0;
		margin-top: 3px;
		border-radius: 6px;
		overflow: hidden;
	}

	&--reply::before {
		content: "";
		position: absolute;
		top: 0; 
		left: 0;
		width: 100%; 
		height: 100%;  
		opacity: .5; 
		z-index: -1;
		background-color: var(--cc__background);
	}
}
</style>
