<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
              v-for="(item, index) in example"
              :key="index"
              :class="['script-name', { 'active-name': activeIndex === index }]"
              @click="activeIndex = index"
            >
              {{ item.title }}
            </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">{{
                      `${element.label}(${
                        element.type === 'button' ? element.key : element.bindField
                      })`
                    }}</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].code" 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}(${element.type === 'button' ? element.key : element.bindField})`
          }}</a-tag>
        </template>
      </Draggable>
      <template #extra>
        <CloseOutlined @click="componentVisible = false" />
      </template>
    </a-drawer>
  </BasicModal>
</template>

<script lang="ts" setup>
  import { ref, inject, reactive } 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 { camelCaseString } from '/@/utils/event/design';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { noHaveTableAndField } from '/@/components/Designer/src/types';

  import { NodeHead } from '/@/components/ModalPanel/index';
  import { cloneDeep } from 'lodash-es';

  defineProps({
    disabled: { type: Boolean, default: false },
  });

  const { t } = useI18n();

  const definedScript = ref(``);
  const emit = defineEmits(['success', 'register']);
  const activeIndex = ref(0);
  const componentVisible = ref<boolean>(false);

  const configTab = ref('widget');
  const tableActiveKey = ref([0]);

  const widgetFormList = ref<any>([]); //整个表单json配置
  const isCustomForm = inject<boolean>('isCustomForm', false);
  const example = reactive([
    {
      title: t('ajax加载服务器数据'),
      code: `formActionType.httpRequest({
      requestType: 'get', //请求方式有: get、post、put、delete
      requestUrl: '/system/dictionary-detail', //请求地址
      params: {
        itemId: '1419276800524423168'
      },//请求参数
      errorMessageMode: 'none' //错误提示方式，默认为none
  })
        // errorMessageMode='message' 错误提示为消息提示
        // errorMessageMode='modal' 显示modal错误弹窗，用于一些比较重要的错误
        // errorMessageMode='none'  一般是调用时明确表示不希望自动弹出错误提示
    `,
    },
    {
      title: t('刷新表格'),
      code: `formActionType.reload()`,
    },
    {
      title: t('弹出对话框'),
      code: `formActionType.showModal({
      title: '我是标题', // 对话框标题
      content: '我是内容', // 对话框内容
      onOk() {
        console.log('onOk') // 点击确定按钮的处理逻辑
      },
      onCancel() {
        console.log('onCancel') // 点击取消按钮的处理逻辑
      },
  });`,
    },
    {
      title: t('显示提示信息'),
      code: `formActionType.showMessage('提示信息')`,
    },
    {
      title: t('if判断'),
      code: `const value = 3
  if(value === 3){ /* 括号内为判断条件 */
    console.log('value为3')
    /* 处理逻辑 */
  }`,
    },
    {
      title: t('循环'),
      code: `for(let i=0; i<3; i++){ /* 括号内为循环条件 */
    console.log('i的值为', i)
    /* 处理逻辑 */
  }`,
    },
    {
      title: t('正则校验'),
      code: `formActionType.regTest({
      regExpression: /^[0-9]/,// 正则表达式
      testValue: 123,// 需要进行校验的值
      successMessage: '校验成功',// 校验成功的提示信息
      errorMessage: '校验失败'// 校验失败的提示信息
  })`,
    },
    {
      title: t('行数据'),
      code: `
      // 选中行的第一行数据
      if(formActionType.selectedRowsData
      &&
      Array.isArray(formActionType.selectedRowsData)&&
      formActionType.selectedRowsData.length>0){
        let item = formActionType.selectedRowsData[0];
        console.log('选中行的第一行数据',item);
      }
      // 选中行的第一行数据字段userName
      if(formActionType.selectedRowsData&&
      Array.isArray(formActionType.selectedRowsData)
      &&formActionType.selectedRowsData.length>0){
        let item = formActionType.selectedRowsData[0];
        console.log('选中行的第一行数据字段userName',item.userName);
      }`,
    },
    {
      title: t('表格弹窗'),
      code: `//curRowData 表格操作列按钮或者弹窗组件所在当前行数据
      formActionType.openModal(curRowData)`,
    },
  ]);

  const getTableComponents = (list, tableName, key?) => {
    list.forEach((item) => {
      if (['tab', 'grid', 'card'].includes(item.type)) {
        for (const child of item.layout!) {
          getTableComponents(child.list, tableName);
        }
      } else if (item.type === 'table-layout') {
        for (const child of item.layout!) {
          for (const list of child.list) {
            getTableComponents(list.children, tableName, key);
          }
        }
      } else if (item.type === 'one-for-one' || item.type === 'form' || item.type === 'sun-form') {
        // widgetFormList.value.push({
        //   label: `${item.label}-${item.key}`,
        //   key: key,
        //   children: [
        //     { label: item.label, bindField: item.key, bindTable: item.bindTable, type: 'form' },
        //   ],
        // });
        // getTableComponents(item.children, `${item.label}-${item.key}`, item.key);
      } else if (!noHaveTableAndField.includes(item.type) || item.type === 'button') {
        const index = widgetFormList.value.findIndex((x) => x.label === tableName);
        const isRange = ['time-range', 'date-range'].includes(item.type);
        let rangeItem: any[] = [];
        if (isRange) {
          //时间范围、日期范围需改为两个字段
          rangeItem = [
            {
              ...item,
              label: t(`{name}开始时间`, { name: item.label }),
              bindField: item.bindStartTime,
            },
            {
              ...item,
              label: t(`{name}结束时间`, { name: item.label }),
              bindField: item.bindEndTime,
            },
          ];
        }
        if (index !== -1) {
          if (isRange) {
            widgetFormList.value[index].children.push(...rangeItem);
          } else {
            widgetFormList.value[index].children.push(item);
          }
        } else {
          const tableChildren = isRange ? [...rangeItem] : [item];
          if (tableName === t('组件列表')) {
            widgetFormList.value.unshift({
              label: tableName,
              key: '1',
              children: tableChildren,
            });
          } else {
            // widgetFormList.value.push({
            //   label: tableName,
            //   key: key,
            //   children: tableChildren,
            // });
          }
        }
      }
    });
  };
  const [registerModal, { closeModal, setModalProps }] = useModalInner(async (data) => {
    if (data.formList.type == 'sun-form') {
      example.splice(1, 1);
    }
    if (data.formList.list.length) {
      widgetFormList.value = [];
      getTableComponents(cloneDeep(data.formList.list), t('组件列表'));
    }
    // if (data.formList.hiddenComponent?.length) {
    //   widgetFormList.value.push({
    //     key: 'hiddenComponent',
    //     label: '隐藏组件',
    //     children: data.formList.hiddenComponent.map((x) => {
    //       return {
    //         label: x.label,
    //         bindField: x.bindField,
    //       };
    //     }),
    //   });
    // }

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

  const dragEnd = ({ item }) => {
    const component = item._underlying_vm_;
    const label = component.label;
    const bindField = component.bindField;
    const bindTable = component.bindTable;
    const transTable = isCustomForm ? bindTable + 'List' : camelCaseString(bindTable) + 'List';
    const transField = isCustomForm ? bindField : camelCaseString(bindField);
    if (component.isSubFormChild || component.isSingleFormChild) {
      definedScript.value = definedScript.value.replace(
        `${label}(${bindField})`,
        `${transTable}[0].${transField}`,
      );
    } else {
      if (component.type === 'button') {
        definedScript.value = definedScript.value.replace(
          `${label}(${component.key})`,
          component.key,
        );
      } else {
        definedScript.value = definedScript.value.replace(
          `${label}(${bindField})`,
          component.type == 'form' ? transField + ',' + transTable : transField,
        );
      }
    }
  };
  const handleSubmit = () => {
    emit('success', definedScript.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>
