<template>
  <div :class="classStyle" @click.stop="open">
    <slot></slot>
  </div>
  <ModalPanel
    :visible="eventConfig.visible"
    :width="800"
    :title="t('执行事件配置')"
    @submit="submit"
    @close="close"
  >
    <div class="config-box h-full">
      <div class="flex justify-end pr-4 pb-10px"
        ><a-button type="primary" @click="addEvent">添加执行事件</a-button></div
      >
      <div :class="prefixCls" style="max-height: calc(100% - 42px)">
        <a-table
          :key="tableKey"
          size="middle"
          :columns="columns"
          :data-source="eventConfig.processEvent"
          :pagination="false"
          :scroll="{ y: 'calc(100% - 51px) !important' }"
        >
          <template #headerCell="{ column }">
            <div v-if="column.key === 'sort'" class="header-cell__custom-title">
              <svg class="icon" aria-hidden="true">
                <use xlink:href="#icon-fangxiang1" />
              </svg>
            </div>
            <div v-else class="header-cell__custom-title">{{ column.title }}</div>
          </template>
          <template #bodyCell="{ column, record, index }">
            <template v-if="column.key === 'sort'">
              <svg class="icon draggable-icon" aria-hidden="true" style="cursor: move">
                <use xlink:href="#icon-paixu" />
              </svg>
            </template>
            <template v-if="column.key === 'operateType'">
              <a-select v-model:value="record[column.dataIndex]">
                <a-select-option :value="ExecuteType.API">{{ t('执行API') }}</a-select-option>
                <a-select-option :value="ExecuteType.JS">{{ t('执行JS脚本') }}</a-select-option>
                <a-select-option :value="ExecuteType.RULE">{{ t('规则引擎') }}</a-select-option>
                <a-select-option value="ruleProcess">{{ t('规则流程') }}</a-select-option>
                <a-select-option :value="ExecuteType.PUSH_MESSAGE">
                  {{ t('消息模板') }}
                </a-select-option>
              </a-select>
            </template>
            <template v-if="column.key === 'operateConfig'">
              <SelectApi
                v-if="record.operateType == ExecuteType.API"
                v-model:apiConfig="record.operateConfig.apiConfig"
              />
              <a-select
                v-else-if="record.operateType === ExecuteType.RULE"
                v-model:value="record.operateConfig.rule"
                :options="liteFlowOptions"
                placeholder="配置规则"
                :field-names="{ label: 'chainName', value: 'id' }"
              />
              <InputModel
                v-else-if="record.operateType === ExecuteType.JS"
                :value="record.operateConfig.js ? '已配置' : ''"
                :placeholder="t('配置JS脚本')"
                style="width: 100%; min-width: 100px"
                @click="showJsConfig(index, record.operateConfig.js)"
              />
              <SelectRuleProcess
                v-else-if="record.operateType === 'ruleProcess'"
                :ruleConfig="record.ruleConfig"
                @change="
                  (val) => {
                    record.ruleConfig = val;
                  }
                "
              />
              <SelectPushMessage
                v-else-if="record.operateType === ExecuteType.PUSH_MESSAGE"
                style="width: 100%"
                v-model="record.operateConfig.messageConfig"
                :need-hide-components="true"
              />
            </template>
            <template v-if="column.key === 'action'">
              <div class="text-[#ff8080]" @click="deleteEvent(index)">{{ t('删除') }}</div>
            </template>
          </template>
        </a-table>
      </div>
      <ScriptConfig @register="registerModal" @success="submitConfig" />
    </div>
  </ModalPanel>
</template>

<script lang="ts" setup>
  import { reactive, ref, onMounted, nextTick, watch } from 'vue';
  import { ExecuteType } from '/@/enums/desktop';
  import { useI18n } from '/@/hooks/web/useI18n';

  import { getLiteflowList } from '/@/api/liteflow';
  import ScriptConfig from './ScriptConfig.vue';
  import SelectApi from './SelectApi.vue';
  import SelectPushMessage from '/@/views/generator/desktop/components/designer/properties/collapse/SelectPushMessage.vue';
  import { InputModel } from '/@/components/ApiConfig';
  import { ModalPanel } from '/@/components/ModalPanel/index';
  import { useModal } from '/@/components/Modal';
  import { processEventItem } from '/@/model/desktop/designer';
  import { cloneDeep } from 'lodash-es';
  import Sortable from 'sortablejs';
  import { useDesign } from '/@/hooks/web/useDesign';
  import { isNullAndUnDef } from '/@/utils/is';
  import SelectRuleProcess from './SelectRuleProcess.vue';

  const { prefixCls } = useDesign('basic-table');
  const { t } = useI18n();
  const liteFlowOptions = ref();
  const tableKey = ref(0);
  const props = defineProps({
    processEvent: Array<processEventItem>,
    classStyle: String,
    disabled: Boolean,
  });
  const emits = defineEmits(['update:processEvent']);
  const eventConfig: {
    visible: boolean;
    index: number;
    processEvent: Array<processEventItem>;
  } = reactive({
    visible: false,
    index: -1,
    processEvent: [],
  });
  const [registerModal, { openModal }] = useModal();
  onMounted(async () => {
    await getLiteFlowOptions();
  });
  const columns = ref([
    {
      dataIndex: 'sort',
      key: 'sort',
      align: 'center',
      width: '50px',
    },
    {
      title: t('操作类别'),
      dataIndex: 'operateType',
      key: 'operateType',
      width: '35%',
      align: 'center',
    },
    {
      title: t('操作配置'),
      dataIndex: 'operateConfig',
      key: 'operateConfig',
      align: 'center',
    },
    {
      title: t('操作'),
      dataIndex: 'action',
      key: 'action',
      width: '60px',
      align: 'center',
    },
  ]);

  watch(
    () => eventConfig.processEvent,
    (val) => {
      if (val && val.length) {
        nextTick(() => {
          const tbody: any = document.querySelector('.config-box .ant-table-tbody');
          Sortable.create(tbody, {
            handle: '.draggable-icon',
            onEnd: ({ oldIndex, newIndex }) => {
              if (isNullAndUnDef(oldIndex) || isNullAndUnDef(newIndex) || newIndex === oldIndex) {
                return;
              }
              const columns = cloneDeep(eventConfig.processEvent);
              if (oldIndex > newIndex) {
                columns.splice(newIndex - 1, 0, columns[oldIndex - 1]);
                columns.splice(oldIndex, 1);
              } else {
                columns.splice(newIndex, 0, columns[oldIndex - 1]);
                columns.splice(oldIndex - 1, 1);
              }
              eventConfig.processEvent = cloneDeep(columns);
              tableKey.value++;
            },
          });
        });
      }
    },
    {
      deep: true,
      immediate: true,
    },
  );
  async function getLiteFlowOptions() {
    liteFlowOptions.value = (await getLiteflowList()) || [];
  }
  function open() {
    if (props.disabled) return;
    eventConfig.processEvent = cloneDeep(props.processEvent)!;
    if (!eventConfig.processEvent.length) {
      eventConfig.processEvent.push({
        operateType: 1,
        operateConfig: {
          apiConfig: {
            path: '',
          },
        },
      });
    }
    eventConfig.visible = true;
  }
  function addEvent() {
    eventConfig.processEvent.push({
      operateType: ExecuteType.API,
      operateConfig: {
        rule: '',
        js: '',
        apiConfig: {
          id: '',
          name: '',
          method: '',
          path: '',
          requestParamsConfigs: [], //Query Params
          requestHeaderConfigs: [], //Header
          requestBodyConfigs: [], //Body
        },
      },
    });
  }
  function showJsConfig(index, val) {
    eventConfig.index = index;
    openModal(true, {
      content: val,
    });
  }
  function submitConfig(_, value) {
    eventConfig.processEvent[eventConfig.index].operateConfig.js = value;
  }
  function deleteEvent(index) {
    eventConfig.processEvent.splice(index, 1);
  }
  function submit() {
    eventConfig.visible = false;
    emits('update:processEvent', eventConfig.processEvent);
  }
  function close() {
    eventConfig.visible = false;
  }
</script>

<style lang="less" scoped>
  .process-top {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;

    .process-title {
      line-height: 18px;
      padding-left: 6px;
      border-left: 6px solid #5e95ff;
    }
  }

  :deep(.ant-select) {
    width: 100%;
  }

  :deep(.ant-table-cell) {
    padding: 10px !important;
  }

  .icon {
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    fill: currentcolor;
    overflow: hidden;
    display: inline;
  }

  .config-box {
    padding: 16px 0 0;
  }
</style>
