<script setup>
// TODO 重新实现  height, name，支持bash、php、python等

import {onMounted, ref} from "vue";
import {basicSetup, EditorView} from "codemirror"
import {keymap} from "@codemirror/view"
import {yaml} from "@codemirror/lang-yaml"
import {javascript} from "@codemirror/lang-javascript"
import {json} from "@codemirror/lang-json"
import {indentWithTab} from "@codemirror/commands"

const props = defineProps(["name", "type", "id", "readOnly", "width", "height", "focus", "type"])
const emits = defineEmits(["change"])
const valueRef = ref("")

const height = ref(5)
if (props.height > 0) {
	height.value = props.height
}

const editorRef = ref()
const textRef = ref()
onMounted(() => {
	let styleSpec = {}
	let htmlClassName = document.querySelector("html").className
	if (typeof htmlClassName === "string" && htmlClassName.indexOf("dark") >= 0) {
		styleSpec = {
			"span.ͼl, span.ͼg, span.ͼc": {
				color: "var(--p-blue-400)"
			},
			"span.ͼe": {
				color: "var(--p-red-400)"
			},
			"span.ͼb": {
				color: "var(--p-pink-400)"
			},
			".cm-selectionBackground, ::selection": {
				background: "rgba(0, 0, 0, 0.6)"
			},
			".cm-selectionLayer": {
				background: "rgba(0, 0, 0, 0.6)"
			},
			".cm-layer-above": {
				background: "rgba(0, 0, 0, 0.6)"
			},

			"&": {
				color: "var(--p-gray-200)",
				backgroundColor: "#034"
			},
			".cm-content": {
				caretColor: "#0e9"
			},
			"&.cm-focused .cm-cursor": {
				borderLeftColor: "#0e9"
			},
			"&.cm-focused .cm-selectionBackground": {
				backgroundColor: "#074"
			},
			".cm-gutters": {
				backgroundColor: "#045",
				color: "#ddd",
				border: "none"
			}
		}
	}

	const extensions = [
		basicSetup,
		keymap.of([indentWithTab]),
		EditorView.updateListener.of((v) => {
				valueRef.value = v.view.state.doc.toString()
				emits("change", valueRef.value)
			}
		),
		EditorView.lineWrapping,
		EditorView.baseTheme({
			".cm-content": {
				lineHeight: "1.8em"
			},
			...styleSpec
		})
	]

	let readOnly = false
	if (props.readOnly || (typeof props.readOnly === "string")) {
		readOnly = true
		extensions.push(EditorView.editable.of(false))
	}

	switch (props.type) {
		case "text/yaml":
			extensions.push(yaml())
			break
		case "application/json":
			extensions.push(json())
			break
		case "application/javascript":
			extensions.push(javascript())
			break
		case "text/javascript":
			extensions.push(javascript())
			break
	}

	valueRef.value = textRef.value.textContent
	if (!readOnly && valueRef.value.length == 0) {
		valueRef.value = "\n\n\n\n"
	}
	new EditorView({
		doc: valueRef.value,
		extensions: extensions,
		parent: editorRef.value
	})

})

</script>

<template>
	<input :name="name" type="hidden" v-model="valueRef"/>
	<div ref="editorRef"></div>
	<div class="hidden" ref="textRef" :id="id">
		<slot></slot>
	</div>
</template>

<style scoped>

</style>