<template>
	<monaco-editor
		class="script-editor"
		ref="editor"
		v-model="meta.script"
		language="javascript"
		:options="monacoEditorOptions"
		@editorWillMount="editorWillMount"
	/>
</template>

<script>
	import MonacoEditor from "vue-monaco";
	import {monacoEditorOptions} from "../../../utils";

	const typesUrl = [
		"http://yun.duiba.com.cn/editor/zeroing/types/types.v2.d.ts",
		"http://yun.duiba.com.cn/editor/zeroing/types/process-context.v8.d.ts",
	];
	let types;

	const metaDtsTpl =
		`declare function next(type: $OUTPUT_TYPES$, payload?: any);
		declare interface ProcessProps {
$PROPS_TYPES$
		}
		declare interface EnvProps {
$ENV_PROPS$
		}
		`;

	export default {
		name: "ProcessScriptEditor",
		components: {
			MonacoEditor,
		},
		props: ['meta'],
		data() {
			return {
				monacoEditorOptions,
			}
		},
		mounted() {
			this.updateMetaDts();
		},
		watch: {
			meta(v) {
				this.updateMetaDts();
			},
		},
		methods: {
			async editorWillMount(monaco) {
				this.monaco = monaco;
				if (!types) {
					types = (await Promise.all(typesUrl.map(async url => {
						const res = await fetch(url);
						return res.text();
					}))).join("\n");
					this.monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
						target: monaco.languages.typescript.ScriptTarget.ES6,
						allowNonTsExtensions: true,
						allowJs: true
					});
					this.monaco.languages.typescript.javascriptDefaults.addExtraLib(types);
					this.updateMetaDts();
				}
			},
			updateMetaDts() {
				if (!types) {
					return;
				}
				let meta = this.meta;
				let outputTypes = meta.output.map(item => `'${item}'`).join('|');
				let envKeys = this.$store.getters.envKeys;
				let props = [];
				for (let key in meta.props) {
					let propConfig = meta.props[key];
					let propType = 'string';
					switch(propConfig.type){
						case 'boolean':
						case 'number':
							propType = propConfig.type;
							break;
						case 'dynamic':
						case 'map':
							propType = 'any';
							break;
						case 'node':
							propType = 'NodeClass';
							break;
						case 'enum':
							propType = '{' + propConfig.enum.join(',') + '}';
							break;
					}
					props.push(key + ':' + propType + ';');
				}
				let metaDts = metaDtsTpl
					.replace('$OUTPUT_TYPES$', outputTypes)
					.replace('$PROPS_TYPES$', props.join('\n'))
					.replace('$ENV_PROPS$', envKeys.join('\n'))
				//console.log(metaDts);
				this.monaco.languages.typescript.javascriptDefaults.addExtraLib(metaDts, 'meta.d.ts');
			},
		}
	}
</script>

<style scoped>

</style>