import type { HighlightJS } from './CodeTypes'
import { appendStyle, appendScript } from '@bagelink/vue'
import { ref } from 'vue'

// Extend the Window interface
interface CustomWindow extends Window {
	hljs: HighlightJS
}
declare const window: CustomWindow

export function useHighlight() {
	const hljs = ref<HighlightJS | null>(null)
	const loaded = ref(false)

	const loadHighlight = async () => {
		if (loaded.value) return

		try {
			// Load highlight.js
			await appendScript('https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.0/highlight.min.js', { id: 'hljs-cdn' })
			await appendStyle('https://cdn.jsdelivr.net/npm/highlight.js/styles/atom-one-dark.min.css')

			if (window.hljs) {
				hljs.value = window.hljs
				loaded.value = true
			} else {
				console.error('Failed to load highlight.js')
			}
		} catch (error) {
			console.error('Error loading highlight.js:', error)
		}
	}

	const escapeHtml = (unsafe: string) => {
		return unsafe.replace(/[&<>"']/g, (m) => {
			const replacements: { [key: string]: string } = {
				'&': '&amp;',
				'<': '&lt;',
				'>': '&gt;',
				'"': '&quot;',
				'\'': '&#039;'
			}
			return replacements[m] || ''
		})
	}

	const highlightCode = (code: string, language?: string, autodetect = true, ignoreIllegals = true) => {
		if (!hljs.value) return escapeHtml(code)

		try {
			const lang = language || ''

			if (lang && !autodetect && !hljs.value.getLanguage(lang)) {
				console.warn(`The language "${lang}" is not available.`)
				return escapeHtml(code)
			}

			const result = autodetect
				? hljs.value.highlightAuto(code)
				: hljs.value.highlight(code, { language: lang, ignoreIllegals })

			return result.value || escapeHtml(code)
		} catch (error) {
			console.error('Highlighting error:', error)
			return escapeHtml(code)
		}
	}

	return {
		hljs,
		loaded,
		loadHighlight,
		escapeHtml,
		highlightCode
	}
}
