<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    :title="t('脚本配置')"
    @ok="handleSubmit"
    @visible-change="visibleChange"
    width="70%"
  >
    <div class="config-box">
      <div>
        <a-tabs
          v-model:activeKey="configTab"
          style="margin-bottom: 8px; background: #fff; height: 100%"
        >
          <a-tab-pane key="widget" :tab="t('脚本示例')">
            <div>
              <div
                v-for="(item, index) in example"
                :key="index"
                :class="['script-name', { 'active-name': activeIndex === index }]"
                @click="handleScriptClick(index)"
              >
                {{ item.name }}
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="component" :tab="t('选择组件')">
            <a-collapse v-model:activeKey="tableActiveKey" expand-icon-position="right">
              <a-collapse-panel
                v-for="(item, index) in widgetFormList"
                :key="index"
                :header="item.label"
              >
                <draggable
                  v-model="item.children"
                  item-key="item.key"
                  :group="{ name: 'script', pull: false, put: false }"
                  @end="dragEnd"
                  :sort="false"
                >
                  <template #item="{ element }">
                    <a-tag color="blue">{{
                      `${item.type == 'main' ? element.options.label : element.label} `
                    }}</a-tag>
                  </template>
                </draggable>
              </a-collapse-panel>
            </a-collapse>
          </a-tab-pane>
        </a-tabs>
      </div>
      <div>
        <div class="box-top">
          <NodeHead nodeName="脚本示例代码" />
        </div>
        <div style="height: calc(100% - 40px)">
          <CodeEditor :value="example[activeIndex].script" language="js" readonly />
        </div>
      </div>
      <div>
        <div class="box-top">
          <NodeHead nodeName="自定义脚本" />
        </div>
        <div style="height: calc(100% - 40px)">
          <CodeEditor v-model:value="definedScript" language="js" :readonly="disabled" />
        </div>
      </div>
    </div>
    <a-drawer
      :title="t('组件列表(可将组件拖入自定义脚本当中)')"
      placement="left"
      :visible="componentVisible"
      :get-container="false"
      :style="{ position: 'absolute' }"
      :mask="false"
      width="50%"
      :closable="false"
    >
      <Draggable
        v-model="widgetFormList"
        :group="{ name: 'script', pull: false, put: false }"
        item-key="key"
        @end="dragEnd"
        :sort="false"
      >
        <template #item="{ element }">
          <a-tag color="blue">{{ `${element.label} ` }}</a-tag>
        </template>
      </Draggable>
      <template #extra>
        <CloseOutlined @click="componentVisible = false" />
      </template>
    </a-drawer>
  </BasicModal>
</template>

<script lang="ts" setup>
  import { ref, onMounted, inject } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { CodeEditor } from '/@/components/CodeEditor';
  import Draggable from 'vuedraggable';
  import { CloseOutlined } from '@ant-design/icons-vue';

  import { useI18n } from '/@/hooks/web/useI18n';

  import { getScriptDemoList, getScriptDemoInfo } from '/@/api/system/script';
  import { ScriptResultModel } from '/@/api/system/script/model';
  import { NodeHead } from '/@/components/ModalPanel/index';
  import { cloneDeep } from 'lodash-es';
  import { getTableComponents } from '../../types/tool';

  interface ExampleModel {
    script?: string;
  }
  type Example = ExampleModel & ScriptResultModel;
  defineProps({
    disabled: { type: Boolean, default: false },
  });
  const widgetForm = inject('widgetForm', ref<any>([]));
  const { t } = useI18n();
  const eventType = ref('');
  const definedScript = ref(``);
  const emit = defineEmits(['success', 'register']);
  const activeIndex = ref(0);
  const componentVisible = ref<boolean>(false);
  const configIndex = ref();
  const configTab = ref('widget');
  const tableActiveKey = ref([0]);
  const example = ref<Example[]>([]);

  const widgetFormList = ref<any>([]); //整个表单json配置

  onMounted(async () => {
    example.value = await getScriptDemoList();
    handleScriptClick(activeIndex.value);
  });

  const [registerModal, { closeModal, setModalProps }] = useModalInner(async (data) => {
    if (widgetForm.value.length) {
      let tempFormList = [];
      getTableComponents(cloneDeep(widgetForm.value), tempFormList);
      widgetFormList.value = [
        {
          label: '组件列表',
          type: 'main',
          children: [],
        },
      ];
      tempFormList.forEach((o: any) => {
        if (['tree', 'list', 'search'].includes(o.type)) {
          widgetFormList.value[0].children.push(o);
          if ('search' == o.type) {
            widgetFormList.value.push({
              label: o.options.label,
              type: 'search',
              children: o.options.schemas,
            });
          }
        }
      });
    }

    eventType.value = data.type;
    //如果已经设置过当前事件代码  则显示已经设置的值 反之  显示默认值
    definedScript.value = data.content;
    configIndex.value = data.index;
    setModalProps({
      fixedHeight: true,
      destroyOnClose: true,
    });
  });

  const handleScriptClick = async (index) => {
    activeIndex.value = index;
    const info = example.value[index];
    if (!!info.script) return;
    if (info.id) {
      const data = await getScriptDemoInfo(info.id);
      info.script = data.scriptContent;
    }
  };

  const dragEnd = ({ item }) => {
    const component = item._underlying_vm_;

    const label = ['tree', 'list', 'search'].includes(component.type)
      ? component.options.label
      : component.label;

    let replaceStr = ['tree', 'list', 'search'].includes(component.type)
      ? component.key
      : component.field;
    definedScript.value = definedScript.value.replace(`${label}`, replaceStr);
  };
  const handleSubmit = () => {
    emit('success', eventType.value, definedScript.value, configIndex.value);
    closeModal();
  };

  const visibleChange = (visible: boolean) => {
    if (!visible) componentVisible.value = false;
  };
</script>

<style lang="less" scoped>
  .config-box {
    display: flex;
    height: 100%;

    > div:nth-child(1) {
      width: 30%;
      border-right: 1px solid #ddd;
    }

    > div:nth-child(2) {
      width: 35%;
      border-right: 1px solid #ddd;
    }

    > div:nth-child(3) {
      width: 35%;
    }

    .box-top {
      display: flex;
      justify-content: space-between;
      height: 30px;
      border-bottom: 1px solid #f0f0f0;
      padding: 25px 20px;
    }

    .script-name {
      cursor: pointer;
      padding: 10px 0 10px 15px;

      &:hover {
        background: #f7fbff;
      }
    }

    .active-name {
      background: #f7fbff;
      border-right: 4px solid #1c8dff;
    }
  }

  :deep(.ant-drawer-title) {
    font-size: 16px;
    height: 20px;
    line-height: 18px;
    padding-left: 6px;
    border-left: 6px solid #5e95ff;
  }

  :deep(.ant-tag) {
    padding: 8px;
    font-size: 13px;
    margin-bottom: 7px;
    cursor: move;
  }

  :deep(.ant-tabs-content) {
    height: 100%;
    overflow: auto;
  }

  :deep(.ant-tabs-nav) {
    width: 100%;
    height: 51px;
    margin-bottom: 0;
  }

  :deep(.ant-collapse) {
    background-color: #f7fbff !important;
  }
</style>
