<script lang="ts" setup>
import { Btn, TextInput } from '@bagelink/vue'
import { computed, nextTick, ref } from 'vue'
import type { BagelInputShellProps } from './bagelInputShell'
import { useBagelInputShell } from './bagelInputShell'

interface Props extends BagelInputShellProps {
	maxLength?: number
	placeholder?: string
	label?: string
	rtl?: boolean
	showFormatting?: boolean
}

const props = withDefaults(defineProps<Props>(), {
	placeholder: 'Enter Text',
	label: 'Body',
	showFormatting: true,
})
const { maxLength, placeholder, label, showFormatting, rtl } = props
const { shellClass, shellStyle } = useBagelInputShell(props)

const text = defineModel<string>('modelValue', { default: '' })

const textareaRef = ref<InstanceType<typeof TextInput>>()
const textareaId = `markdown-editor-${Math.random().toString(36).substring(2, 9)}`

const charCount = computed(() => text.value.length)

function insertToBody(type: 'bold' | 'italic' | 'underline' | 'code' | 'pre' | 'newline') {
	const textarea = textareaRef.value?.$el.querySelector('textarea')
	console.log(textarea)
	const val = text.value
	const start = textarea?.selectionStart ?? val.length
	const end = textarea?.selectionEnd ?? val.length
	const before = val.slice(0, start)
	const after = val.slice(end)
	const selected = val.slice(start, end)
	let insert = ''

	switch (type) {
		case 'bold': insert = `*${selected || 'bold'}*`; break
		case 'italic': insert = `_${selected || 'italic'}_`; break
		case 'underline': insert = `~${selected || 'underline'}~`; break
		case 'code': insert = `\`${selected || 'code'}\``; break
		case 'pre': insert = `\`\`\`${selected || 'pre'}\`\`\``; break
		case 'newline': insert = `\n`; break
		default: insert = ''
	}

	text.value = before + insert + after

	nextTick(() => {
		if (textarea) {
			const pos = before.length + insert.length
			textarea.setSelectionRange(pos, pos)
			textarea.focus()
		}
	})
}
const html = computed((): string => {
	// Temporarily replace all underscores inside handlebar variables
	let txt = text.value.replace(/\{\{([^}]+)\}\}/g, (_, content) => {
		// Replace all underscores within the handlebars content with a placeholder
		const protectedContent = content.replace(/_/g, '#####')
		return `{{${protectedContent}}}`
	})

	// Code blocks
	txt = txt.replace(/```([\s\S]+?)```/g, '<pre>$1</pre>')
	txt = txt.replace(/`([^`]+)`/g, '<code>$1</code>')
	// Bold
	txt = txt.replace(/\*([^*]+)\*/g, '<b>$1</b>')
	// Italic
	txt = txt.replace(/_([^_]+)_/g, '<i>$1</i>')
	// Underline
	txt = txt.replace(/~([^~]+)~/g, '<u>$1</u>')
	// Line breaks
	txt = txt.replace(/\n/g, '<br>')
	// Restore all underscores inside handlebar variables
	txt = txt.replace(/\{\{([^}]+)\}\}/g, (_, content) => {
		// Restore all underscores within the handlebars content
		const restoredContent = content.replace(/#####/g, '_')
		return `{{${restoredContent}}}`
	})

	return txt
})

// Expose parsing function for parent components
defineExpose({	html })
</script>

<template>
	<div class="markdown-editor">
		<div class="bagel-input mb-0" :class="[shellClass, { 'has-value': charCount > 0 }]" :style="shellStyle">
			<div v-if="maxLength" class="txt10 opacity-6 -mb-1 w100p txt-end">
				{{ charCount }} / {{ maxLength }}
			</div>
			<label v-if="label" class="label" :for="textareaId">{{ label }}</label>
			<TextInput
				:id="textareaId"
				ref="textareaRef"
				v-model="text"
				:dir="rtl ? 'rtl' : 'ltr'"
				autoheight
				:placeholder="placeholder"
				:maxlength="maxLength"
				class="m-0"
			/>
		</div>

		<div v-if="showFormatting" class="flex justify-content-end -mt-025 -mb-05 ltr">
			<Btn thin icon-size="0.9" flat icon="format_bold" @click="insertToBody('bold')" />
			<Btn thin icon-size="0.9" flat icon="format_italic" @click="insertToBody('italic')" />
			<Btn thin icon-size="0.9" flat icon="format_underlined" @click="insertToBody('underline')" />
			<Btn thin icon-size="0.9" flat icon="code" @click="insertToBody('code')" />
			<Btn thin icon-size="0.9" flat icon="notes" @click="insertToBody('pre')" />
			<Btn thin icon-size="0.9" flat icon="keyboard_return" @click="insertToBody('newline')" />
		</div>
	</div>
</template>

<style scoped>

.markdown-editor {
width: 100%;
}

</style>
