<template>
  <a-card
    title='插件脚本'
  >
    <div ref="editorRef"></div>
  </a-card>
  <a-card

  >
    <template #title>
      <a-space>
        <span>模拟类型</span>
        <a-select allowClear v-model:value="state.decode" style="width: 170px;" >
          <a-select-option v-for="(item, index) in codeList" :key="index" :value="item.key" >
            {{item.name}}
          </a-select-option>
        </a-select>
      </a-space>
    </template>
    <template #extra >
      <a-space>
        <a-button @click="debugPlugin" >调试</a-button>
        <a-button type="primary" @click="savePlugin" >保存</a-button>
      </a-space>
    </template>
    <a-row>
      <a-col :span="12" >
        <a-textarea
          v-model:value="state.input"
          :placeholder="placeholder"
          :auto-size="{ minRows: 8 }"
        />
      </a-col>
      <a-col :span="12" >
        <a-textarea
          v-model:value="state.result"
          :auto-size="{ minRows: 8 }"
        />
      </a-col>
    </a-row>
  </a-card>
</template>
<script lang='ts' setup >
import { basicSetup } from 'codemirror'
import { EditorView } from '@codemirror/view'
import { EditorState } from '@codemirror/state'
import { javascript } from '@codemirror/lang-javascript'
import { ref, onMounted, reactive } from 'vue'
import { ModelCmdController, ModelController } from '@/controller'
import { useRoute } from 'vue-router'
import { computed } from '@vue/reactivity'

const placeholder = computed(() => {
  return state.decode
    ? "输入JSON字符串，如:{'msg_type':'commands','command_name':'SET_ALARM','service_id':'smokerdector','paras':{'value':'1'}}"
    : '输入HEX字符，如二进制[0x00, 0x50, 0x00, 0x5a]对应的模拟输入数据为0050005a'
})

const codeList = [
  { name: '编码', key: true },
  { name: '解码', key: false }
]

const route = useRoute()

const modelId = route.query.id as string

const codemirrorRef = ref()

const state = reactive({
  decode: false,
  input: '',
  pluginId: '',
  modelPluginBody: '',
  pluginBody: 'function encode(payload, topic) {\n  var jsonObj = {};   return JSON.stringify(jsonObj);\n }\n function decode(json) {\n var payload = [];\n return payload;\n }',
  result: ''
})

const debugPlugin = async () => {
  const { data } = await ModelController.debugPlugin({
    pluginBody: state.pluginBody,
    input: state.input,
    decode: state.decode
  })
  console.log(data)
}

const savePlugin = async () => {
  const requestFn = state.pluginId ? ModelController.updatePlugin : ModelController.postPlugin
  const codeValue = codemirrorRef.value.state.doc.toJSON().join('\n')
  console.log(codeValue)

  await requestFn({
    modelPluginType: 'JS',
    modelPluginBody: codeValue,
    modelId,
    id: state.pluginId
  })
}

const getPlugin = async () => {
  const { data } = await ModelController.getPlugin({ modelId })
  console.log('gePlusins:', data != null)

  state.modelPluginBody = data != null
    ? data.modelPluginBody
    : `/**
  * 设备上报数据到物联网平台时调用此接口进行解码, 将设备的原始数据解码为符合产品模型定义的JSON格式数据。
  * 该接口名称和入参已经定义好，开发者只需要实现具体接口即可。
  * @param byte[] payload   设备上报的原始码流
  * @return string json     符合产品模型定义的JSON格式字符串
  */
function decode(payload, topic) {
  let jsonObj = {};
  return JSON.stringify(jsonObj);
}

/**
 * 物联网平台下发指令时，调用此接口进行编码, 将产品模型定义的JSON格式数据编码为设备的原始码流。
 * 该接口名称和入参格式已经定义好，开发者只需要实现具体接口即可。
 * @param string json      符合产品模型定义的JSON格式字符串
 * @return byte[] payload  编码后的原始码流
 */
function encode(json) {
    let payload = [];
    return payload;
}`
  state.pluginId = data != null ? data.id : ''
  createView()
}

const editorRef = ref()

onMounted(() => {
  getPlugin()
})

const createView = () => {
  const editorState = EditorState.create({
    doc: state.modelPluginBody,
    extensions: [basicSetup, javascript()]
  })

  codemirrorRef.value = new EditorView({
    state: editorState,
    parent: editorRef.value
  })
}

</script>
<style lang='less' scoped >
</style>
