<template>
  <div class="advance-wrapper">
    <div style="width: 150px">
      <Tabs v-model="activeKey" tab-position="left" :tabBarStyle="{ width: '100%' }" @change="onTabChange">
        <TabPane v-for="func in newFunctions" :key="func.id">
          <template #tab>
            <div style="width: 100px; text-align: left">
              <Ellipsis>{{ func.name }}</Ellipsis>
            </div>
          </template>
        </TabPane>
      </Tabs>
    </div>
    <div style="flex: 1">
      <Row :gutter="30">
        <Col :span="15">
          <MonacoEditor :ref="`monacoEditor${current.id}`" v-model="current.json" theme="vs-dark" style="height: 400px" />
          <div class="editor-btn">
            <Space>
              <Button type="primary" :loading="loading" @click="handleExecute(current)"> 执行 </Button>
              <Button type="default" @click="handleClear()"> 清空 </Button>
            </Space>
          </div>
        </Col>
        <Col :span="9">
          <h6>执行结果：</h6>
          <span class="execute-result">
            {{ executeResult }}
          </span>
        </Col>
      </Row>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, computed, watch } from 'vue';
  import { useInstanceStore } from '@jdlinker/func';
  import { execute } from '../../../../../../api/device/instance';
  import { onlyMessage } from '@jdlinker/utils';
  // @ts-ignore
  import { Tabs, TabPane, Space, Button, Ellipsis, Col, Row, MonacoEditor } from 'linker-ui-components';

  const instanceStore = useInstanceStore();

  const activeKey = ref('');
  const loading = ref<boolean>(false);
  // 物模型数据
  const metadata = computed(() => JSON.parse(instanceStore.detail.metadata));
  const current = ref<any>({});
  const executeResult = ref<string>('');

  const newFunctions = ref<any[]>([]);

  /**
   * 根据数据类型, 赋初始值
   * @param type
   * @param json
   */
  const setInitValue = (type: string, json?: any) => {
    let initVal: any = '';
    if (['int', 'long', 'float', 'double'].includes(type)) {
      initVal = 0;
    } else if (['string', 'date', 'enum', 'password', 'geoPoint'].includes(type)) {
      initVal = '';
    } else if (['boolean'].includes(type)) {
      initVal = false;
    } else if (['array'].includes(type)) {
      initVal = [];
    } else if (['object'].includes(type)) {
      initVal = {};
      if (json) {
        const childObj = json['properties'][0];
        initVal[childObj.id] = setInitValue(childObj.valueType.type);
      }
    }
    return initVal;
  };

  // 设备功能数据处理
  watch(
    () => metadata.value.functions,
    (newVal) => {
      const result: any = [];
      newVal?.forEach((func: any) => {
        const obj = {};
        const jsonData = func.inputs || func.properties;
        for (const jsonItem of jsonData) {
          const type = jsonItem.valueType ? jsonItem.valueType.type : '-';
          obj[jsonItem.id] = setInitValue(type, jsonItem['json']);
        }

        result.push({
          ...func,
          json: JSON.stringify(obj),
        });
      });
      newFunctions.value = result;
      current.value = result?.[0];
      activeKey.value = result?.[0]?.id;
    },
    {
      immediate: true,
      deep: true
    }
  );

  const onTabChange = (_key: string) => {
    const _item = newFunctions.value.find((item: any) => item.id === _key);
    current.value = { ..._item };
  };

  /**
   * 执行
   */
  const handleExecute = async (func: any) => {
    loading.value = true;
    const resp: any = await execute(instanceStore.current.id, func.id, JSON.parse(func.json))
      .catch(() => {
        loading.value = false;
      })
      .finally(() => {
        loading.value = false;
      });
    if (resp.success) {
      executeResult.value = resp?.result instanceof Array ? resp?.result?.[0] : resp.result;
      onlyMessage('操作成功');
    }
  };
  /**
   * 清空
   */
  const handleClear = () => {
    current.json = '';
    executeResult.value = '';
  };
</script>

<style lang="less" scoped>
  .advance-wrapper {
    display: flex;
    gap: 12px;
    .editor-btn {
      display: flex;
      justify-content: flex-end;
      margin-top: 10px;
    }
    .execute-result {
      display: inline-block;
      border: 1px solid #d9d9d9;
      border-radius: 2px;
      padding: 4px 11px;
      min-height: 140px;
      width: 100%;
      max-height: 450px;
      overflow: auto;
    }
  }
</style>
