<template>
  <div>
    <div v-if="['Grid'].includes(formConfig.currentItem!.component)">
      <div v-for="(item, index) of formConfig.currentItem!['columns']" :key="index">
        <div class="options-box">
          <Input v-model:value="item.span" class="options-value" />
          <a class="options-delete" @click="deleteGridOptions(index)">
            <Icon icon="ant-design:delete-outlined" />
          </a>
        </div>
      </div>
      <a @click="addGridOptions">
        <Icon icon="ant-design:file-add-outlined" />
        添加栅格
      </a>
    </div>
    <div v-else-if="['TreeSelect', 'Cascader'].includes(formConfig.currentItem!.component)">
      <BasicTree
        ref="treeDataRef"
        :treeData="treeDataAndOptions"
        :fieldNames="{ key: 'value', title: 'label' }"
        :clickRowToExpand="false"
        :defaultExpandAll="true"
      >
        <template #title="{ label, value }">
          <div class="options-box">
            <Input
              :value="label"
              @input="updateLabelOrValue('label', label, value, $event.target.value)"
            />
            <Input
              :value="value"
              @blur="updateLabelOrValue('value', label, value, $event.target.value)"
              class="options-value"
            />
            <Tooltip title="添加子级选项" placement="top">
              <a class="options-delete" @click="addTreeNode(value)">
                <Icon icon="ant-design:folder-add-outlined" />
              </a>
            </Tooltip>
            <a class="options-delete" @click="deleteTreeNode(value)">
              <Icon icon="ant-design:delete-outlined" />
            </a>
          </div>
        </template>
      </BasicTree>
      <a @click="addTreeNode(null)">
        <Icon icon="ant-design:file-add-outlined" />
        添加父级选项
      </a>
      <a @click="showModal('import')">
        <Icon icon="ant-design:import-outlined" />
        导入数据
      </a>
      <!-- <a @click="showModal('export')">
        <Icon icon="ant-design:export-outlined" />
        导出数据
      </a> -->
    </div>
    <div v-else-if="['Transfer'].includes(formConfig.currentItem!.component)">
      <div v-for="(item, index) of formConfig.currentItem!.componentProps![key]" :key="index">
        <div class="options-box">
          <Input v-model:value="item.title" />
          <Input v-model:value="item.description" class="options-value" />
          <a
            class="options-delete"
            @click="updateTransferDisabled(index, false)"
            v-if="item.disabled"
          >
            <Icon icon="bi:unlock" />
          </a>
          <a
            class="options-delete"
            @click="updateTransferDisabled(index, true)"
            v-if="!item.disabled"
          >
            <Icon icon="bi:lock" />
          </a>
          <a class="options-delete" @click="deleteOptions(index)">
            <Icon icon="ant-design:delete-outlined" />
          </a>
        </div>
      </div>
      <a @click="addOptions">
        <Icon icon="ant-design:file-add-outlined" />
        添加标题
      </a>
    </div>
    <div v-else>
      <div v-for="(item, index) of formConfig.currentItem!.componentProps![key]" :key="index">
        <div class="options-box">
          <Input v-model:value="item.label" />
          <Input v-model:value="item.value" class="options-value" />
          <a class="options-delete" @click="deleteOptions(index)">
            <Icon icon="ant-design:delete-outlined" />
          </a>
        </div>
      </div>
      <a @click="addOptions">
        <Icon icon="ant-design:file-add-outlined" />
        添加选项
      </a>
    </div>
  </div>
  <Modal
    :title="title"
    :open="visible"
    @ok="handleImportJson"
    @cancel="handleCancel"
    cancelText="关闭"
    :destroyOnClose="true"
    wrapClassName="v-code-modal"
    style="top: 20px"
    :width="850"
  >
    <p class="hint-box">{{ tip }}</p>
    <div class="v-json-box">
      <CodeEditor v-model:value="json" ref="myEditor" :mode="MODE.JSON" />
    </div>
    <template #footer>
      <div v-if="type == 'import'">
        <a-button @click="handleCancel">取消</a-button>
        <Upload
          class="upload-button"
          :beforeUpload="beforeUpload"
          :showUploadList="false"
          accept="application/json"
        >
          <a-button type="primary">导入json文件</a-button>
        </Upload>
        <a-button type="primary" @click="handleImportJson">确定</a-button>
      </div>
      <div v-if="type == 'export'">
        <a-button @click="handleCancel">取消</a-button>
        <a-button
          type="primary"
          class="copy-btn"
          data-clipboard-action="copy"
          :data-clipboard-text="json"
          @click="handleCopyJson"
        >
          复制数据
        </a-button>
        <a-button @click="handleExportJson" type="primary">导出代码</a-button>
      </div>
    </template>
  </Modal>
</template>

<script lang="ts">
  import { defineComponent, reactive, toRefs, ref, unref, watch } from 'vue';
  import { useFormDesignState } from '../../../hooks/useFormDesignState';
  import { BasicTree, TreeItem, TreeActionType } from '@/components/Tree';
  import { remove, formItemsForEach, generateKey } from '../../../utils';
  import { CodeEditor, MODE } from '@/components/CodeEditor';
  import { Upload, Modal, Input, Tooltip } from 'ant-design-vue';
  import { copyText } from '@/utils/copyTextToClipboard';
  import { options_json, treeData_json } from '../../VFormDesign/config/formItemPropsScript';
  import { v4 as uuidv4 } from 'uuid';
  import { cloneDeep } from 'lodash-es';
  import Icon from '@/components/Icon/Icon.vue';
  import message from '../../../utils/message';

  export default defineComponent({
    name: 'FormOptions',
    components: { Input, Icon, BasicTree, CodeEditor, Upload, Modal, Tooltip },
    // props: {},
    setup() {
      const { formConfig } = useFormDesignState();

      let key: string = '';

      // 导入窗口
      const state = reactive({
        title: '',
        visible: false,
        json: {} as any,
        type: '',
        tip: '',
      });
      // 树的值
      const treeDataAndOptions = ref<TreeItem[]>([]);

      watch(
        () => formConfig.value.currentItem.component,
        () => {
          if (formConfig.value.currentItem?.component == 'TreeSelect') {
            // 树形选择
            treeDataAndOptions.value = formConfig.value.currentItem?.componentProps?.treeData;
            key = 'treeData';
          } else if (formConfig.value.currentItem?.component == 'Cascader') {
            // 级联选择
            treeDataAndOptions.value = formConfig.value.currentItem?.componentProps?.options;
            key = 'options';
          } else if (formConfig.value.currentItem?.component == 'Transfer') {
            // 穿梭框
            key = 'dataSource';
          } else {
            // 下拉选择、单选框-组、复选框-组、自动完成、选项卡、卡片组
            key = 'options';
          }
        },
        { deep: true, immediate: true },
      );

      // 获取树
      const treeDataRef = ref<Nullable<TreeActionType>>(null);
      const getTree = (): any => {
        return unref(treeDataRef);
      };
      // 添加树的父节点、子节点
      const addTreeNode = (value) => {
        let length = getLength(1, getTree().getTreeData());
        getTree().insertNodeByKey({
          parentKey: value,
          node: {
            label: `选项${length}`,
            value: `${length}`,
          },
          // 往后插入
          push: 'push',
        });
        refresh();
      };
      // 删除树的节点
      const deleteTreeNode = (value) => {
        getTree().deleteNodeByKey(value);
        refresh();
      };
      // 获取树的节点的不重复的默认值
      const getLength = (length, treeDataOrOptions) => {
        treeDataOrOptions?.forEach((to) => {
          if (to.children) {
            length = getLength(length, to.children);
          }
          if (length == to.value) {
            length++;
            length = getLength(length, treeDataOrOptions);
          }
        });
        return length;
      };
      // 修改树的label或者value
      const updateLabelOrValue = (type, label, value, newLabelOrValue) => {
        if (type == 'label') {
          getTree().updateNodeByKey(value, { label: newLabelOrValue, value: value });
        }
        if (type == 'value') {
          if (checkRepeat(true, getTree().getTreeData(), newLabelOrValue)) {
            getTree().updateNodeByKey(value, { label: label, value: newLabelOrValue });
          } else {
            message.warning('不能赋给重复的值');
          }
        }
        refresh();
      };
      // 修改树的label或者value-检查是否有重复值
      const checkRepeat = (flag, treeData, newValue) => {
        treeData.forEach((tree) => {
          if (tree.value == newValue) {
            flag = false;
          } else if (tree.children) {
            return checkRepeat(flag, tree.children, newValue);
          }
        });
        return flag;
      };
      // 刷新树的值
      const refresh = () => {
        getTree().expandAll(true);
        treeDataAndOptions.value = getTree().getTreeData();
        formConfig.value.currentItem.componentProps[key] = getTree().getTreeData();
      };

      // 树的导入窗口关闭
      const handleCancel = () => {
        state.visible = false;
      };
      // 树的导入窗口开启
      const showModal = (type) => {
        state.visible = true;
        state.type = type;
        if (type == 'import') {
          state.title = '树状结构数据导入';
          state.tip = '导入格式如下:';
          if (key == 'treeData') {
            state.json = treeData_json;
          } else {
            state.json = options_json;
          }
        } else if (type == 'export') {
          state.title = '树状结构数据导出';
          state.tip = '导出代码如下:';
          state.json = getTree().getTreeData();
          if (key == 'treeData') {
            state.json = { treeData: getTree().getTreeData() };
          } else {
            state.json = { options: getTree().getTreeData() };
          }
        }
      };
      // 树的导入JSON
      const handleImportJson = () => {
        try {
          const editorJsonData = JSON.parse(state.json);
          editorJsonData[key] &&
            formItemsForEach(editorJsonData[key], (formItem) => {
              generateKey(formItem);
            });
          // 删除旧的树
          cloneDeep(getTree().getTreeData())?.forEach((item) => {
            deleteTreeNode(item.value);
          });
          // 导入新数据
          editorJsonData[key]?.forEach((item) => {
            getTree().insertNodeByKey({
              parentKey: null,
              node: item,
              push: 'push',
            });
          });
          refresh();
          handleCancel();
          message.success('导入成功');
        } catch {
          message.error('导入失败，数据格式不对');
        }
      };
      // 通过json文件导入
      const beforeUpload = (e: File) => {
        const reader = new FileReader();
        reader.readAsText(e);
        reader.onload = function () {
          state.json = this.result as string;
          handleImportJson();
        };
        return false;
      };
      // 导出json文件
      const handleExportJson = () => {
        let content = 'data:text/csv;charset=utf-8,';
        content += `${JSON.stringify(state.json, null, 2)}`;
        const encodedUri = encodeURI(content);
        const actions = document.createElement('a');
        actions.setAttribute('href', encodedUri);
        actions.setAttribute('download', 'file.json');
        actions.click();
      };
      // 复制数据
      const handleCopyJson = () => {
        const value = `${JSON.stringify(state.json, null, 2)}`;
        if (!value) {
          message.warning('代码为空');
          return;
        }
        copyText(value);
      };

      const addOptions = () => {
        if (!formConfig.value.currentItem?.componentProps?.[key])
          formConfig.value.currentItem!.componentProps![key] = [];
        const len = formConfig.value.currentItem?.componentProps?.[key].length + 1;

        if (['Tabs'].includes(formConfig.value.currentItem!.component)) {
          formConfig.value.currentItem!.componentProps![key].push({
            label: `选项卡${len}`,
            value: '' + len,
            children: [],
          });
        } else if (['CardGroup'].includes(formConfig.value.currentItem!.component)) {
          formConfig.value.currentItem!.componentProps![key].push({
            label: `卡片${len}`,
            value: '' + len,
            field: `use_card_${uuidv4()}`,
            children: [],
          });
        } else if (['Transfer'].includes(formConfig.value.currentItem!.component)) {
          formConfig.value.currentItem!.componentProps![key].push({
            key: `key-${len}`,
            title: `标题${len}`,
            description: `描述${len}`,
            disabled: false,
          });
        } else {
          formConfig.value.currentItem!.componentProps![key].push({
            label: `选项${len}`,
            value: '' + len,
          });
        }
      };
      const deleteOptions = (index: number) => {
        remove(formConfig.value.currentItem?.componentProps?.[key], index);
      };
      const addGridOptions = () => {
        formConfig.value.currentItem?.['columns']?.push({
          span: 12,
          children: [],
        });
      };
      const deleteGridOptions = (index: number) => {
        if (index === 0) return message.warning('请至少保留一个栅格');
        remove(formConfig.value.currentItem!['columns']!, index);
      };
      const updateTransferDisabled = (index: number, flag: boolean) => {
        formConfig.value.currentItem.componentProps[key][index].disabled = flag;
      };
      return {
        ...toRefs(state),
        formConfig,
        addOptions,
        deleteOptions,
        key,
        deleteGridOptions,
        addGridOptions,
        treeDataRef,
        treeDataAndOptions,
        addTreeNode,
        deleteTreeNode,
        updateLabelOrValue,
        updateTransferDisabled,
        handleImportJson,
        handleExportJson,
        handleCopyJson,
        beforeUpload,
        handleCancel,
        showModal,
        MODE,
      };
    },
  });
</script>

<style lang="less" scoped>
  .options-box {
    display: flex;
    align-items: center;
    margin-bottom: 5px;

    .options-value {
      margin: 0 8px;
    }

    .options-delete {
      flex-shrink: 0;
      width: 30px;
      height: 30px;
      border-radius: 50%;
      background: #f5f5f5;
      color: #666;
      line-height: 30px;
      text-align: center;

      &:hover {
        background: #ff4d4f;
      }
    }
  }

  .upload-button {
    margin: 0 10px;
  }

  .copy-btn {
    margin: 0 5px;
  }
</style>
