<template>
  <a-modal
    v-if="visible"
    v-model="visible"
    :footer="null"
    destroy-on-close
    width="90%"
    :class="$style.modal"
  >
    <a-card
      :class="$style.wrapper"
      :title="readOnly ? '列表预览(仅供查看，修改不生效)' : '列表预览'"
    >
      <sd-search-form
        v-show="defaultShowAdvSearch"
        :key="searchFields.length"
        :onl-list-column-defs="onlListColumnDefs"
      />
      <a-tabs :class="{ ['sd-has-table']: true, [$style.hiddenTab]: viewtabs.length === 1 }">
        <a-tab-pane v-for="x in viewtabs" :key="x.label" :tab="x.label">
          <sd-data-table
            :key="columns.length + (scrollX || '')"
            :class="[$style.preview, searchFields.length > 0 ? $style.fuzzyAdvSearch : '']"
            data-url=""
            :columns="columns"
            show-selection
            :search-fields="['title']"
            :process-req="processReq"
            :process-res="processRes"
            :scroll="{ x: scrollX }"
          >
            <!-- 有高级查询，显示高级查询图标 -->
            <template v-if="searchFields.length > 0" slot="headerPrefix">
              <sd-advance-search-btn
                :actived="defaultShowAdvSearch"
                :class="$style.advsearchbtn"
                @click="defaultShowAdvSearch = !defaultShowAdvSearch"
              />
            </template>
          </sd-data-table>
        </a-tab-pane>
      </a-tabs>

      <a-button
        v-if="!readOnly"
        slot="extra"
        icon="save"
        type="link"
        :class="$style.save"
        @click="save"
      >
        保存
      </a-button>
    </a-card>
    <a-card>
      <a-tabs v-model="tabkey">
        <span slot="tabBarExtraContent">
          <a-input-search v-if="tabkey === 1" v-model="searchValue" placeholder="输入字段名过滤" />
        </span>
        <a-tab-pane :key="1" tab="字段设置">
          <sd-table
            :row-selection="{}"
            :columns="configColumns"
            :data-source="searchValue ? onlListColumnDefsFilter : onlListColumnDefs"
            :sortable="searchValue ? false : true"
            size="small"
            :pagination="false"
            row-key="fieldId"
            :scroll="{ y: 450 }"
            @update:data-source="onlListColumnDefs = $event"
          >
            <template slot="fieldName" slot-scope="text, record">
              {{ text }}<a-tag v-if="record.isShowForm === 0">系统</a-tag>
            </template>
            <template
              v-for="col in ['show', 'search', 'sort']"
              :slot="col"
              slot-scope="text, record"
            >
              <a-checkbox
                :key="col"
                :disabled="!record[col + 'Configurable']"
                :checked="record[col] === 1"
                @change="record[col] = $event.target.checked ? 1 : 0"
              />
              <a-checkbox
                v-if="col === 'search' && record.fieldType === 'selectgroup'"
                v-show="record[col] === 1"
                :key="col + 'sub'"
                v-model="record.attrFD.includeSub"
                >含子部门
              </a-checkbox>
            </template>
            <template slot="show" slot-scope="text, record">
              <a-select
                v-model="record.show"
                :dropdown-match-select-width="false"
                :disabled="!record['showConfigurable']"
                :options="[
                  { value: 0, label: '不显示' },
                  { value: 1, label: '显示' },
                  { value: 2, label: '候选列' },
                ]"
              />
            </template>
            <template slot="width" slot-scope="text, record">
              <sd-width-input
                v-show="record.show === 1 || record.show === 2"
                v-model="record.attrFD.width"
              />
            </template>
            <!-- 支持点击 -->
            <template slot="clickable" slot-scope="text, record">
              <a-checkbox
                :disabled="!record['show']"
                :checked="record.attrFD.clickable"
                @change="record.attrFD = { ...record.attrFD, clickable: $event.target.checked }"
              />
            </template>
          </sd-table>
        </a-tab-pane>
        <a-tab-pane :key="2" tab="默认排序规则">
          <a-button icon="plus" type="link" @click="selectValue">
            新增
          </a-button>
          <sd-table
            :scroll="{ y: 450 }"
            :class="$style.rule"
            :row-selection="{}"
            :columns="[
              {
                title: '字段',
                dataIndex: 'fieldName',
                scopedSlots: { customRender: 'fieldName' },
              },
            ]"
            :data-source.sync="sortFields"
            sortable
            size="small"
            :pagination="false"
            row-key="fieldId"
          >
            <template slot="fieldName" slot-scope="text, record">
              <div>
                {{ text }}
                <a-radio-group v-model="record.sortMode" button-style="solid" size="small">
                  <a-radio-button value="ASC">
                    升序
                  </a-radio-button>
                  <a-radio-button value="DESC">
                    降序
                  </a-radio-button>
                  <a-button icon="sd-trash2" type="link" @click="record.sortMode = null" />
                </a-radio-group>
              </div>
            </template>
          </sd-table>
        </a-tab-pane>
        <a-tab-pane :key="4" tab="页签配置">
          <a-button type="link" icon="plus" @click="tabs.push({})">
            新增
          </a-button>
          <sd-draggable v-model="tabs" handle=".handle">
            <a-row v-for="(item, index) in tabs" :key="index" :gutter="[4, 8]" :class="$style.row">
              <a-col class="handle"></a-col>
              <a-col :span="3"><a-input v-model="item.label" placeholder="页签"/></a-col>
              <a-col>
                <sd-formula-exps v-model="item.value" :fields="fields" />
              </a-col>
              <a-col :span="1">
                <a-icon type="delete" @click="() => tabs.splice(index, 1)" />
              </a-col>
            </a-row>
          </sd-draggable>
        </a-tab-pane>
        <a-tab-pane :key="5" tab="自定义变量">
          <a-button
            type="link"
            icon="plus"
            @click="
              customFields.push({
                dataType: 'string',
                name:
                  'sdCustomField' +
                  (Number(
                    (customFields.slice(-1)[0] || { name: '0' }).name.replace('sdCustomField', '')
                  ) +
                    1),
              })
            "
            >新增
          </a-button>
          <a-row
            v-for="(item, index) in customFields"
            :key="index"
            :gutter="[4, 8]"
            :class="$style.row"
          >
            <a-col :span="3"><a-input v-model="item.caption" placeholder="字段名" /> </a-col>
            <a-col :span="1">
              <a-select
                :value="
                  (item.attr && item.attr.selectionType && item.attr.selectionType.toLowerCase()) ||
                    item.dataType
                "
                :options="[
                  { key: 'string', label: '文本' },
                  { key: 'number', label: '数值' },
                  { key: 'user', label: '用户' },
                  { key: 'group', label: '部门' },
                ]"
                @change="
                  (value) => {
                    item.dataType = value
                    item.attr = {}
                    if (value === 'user' || value === 'group') {
                      item.attr.selectionType = value.toUpperCase()
                      item.dataType = 'selectperson'
                    }
                    customFields = [...customFields]
                  }
                "
              />
            </a-col>
            <a-col>
              <a-icon type="delete" @click="() => customFields.splice(index, 1)" />
            </a-col>
          </a-row>
        </a-tab-pane>
        <a-tab-pane :key="6" tab="列表过滤">
          <sd-formula-exps v-model="filterFormulaObject" :fields="fields.concat(customFields)" />
        </a-tab-pane>
        <a-tab-pane v-if="isOnline" :key="7" tab="按钮设置">
          <a-button v-if="tabkey === 7" type="link" icon="sd-trash2" @click="removeButton">
            删除
          </a-button>
          <a-button v-if="tabkey === 7" type="link" icon="plus" @click="addButton">
            新增
          </a-button>
          <sd-table
            :row-selection="{
              onChange: onSelectChange,
              selectedRowKeys: selectedRowKeys,
            }"
            :columns="btnCfgColumns"
            :data-source.sync="buttonsList"
            :sortable="true"
            size="small"
            :pagination="false"
            row-key="buttonId"
            :scroll="{ y: 450 }"
          >
            <template slot="buttonName" slot-scope="text, record, index">
              <span :class="$style.clickable" @click="editButton(record, index)">{{ text }}</span>
            </template>
          </sd-table>
          <sd-list-buttons-config-modal
            ref="buttonModal"
            :form-id="formId"
            :form-fields="fields"
            :check-button="checkButton"
            @saved="saveButton"
          />
        </a-tab-pane>
        <a-tab-pane :key="8" tab="新建设置">
          <sd-child-table v-model="newConfig.defaultValues" label="默认值" :fields="defValFields">
            <template v-slot:form="{ model }">
              <sd-form-item name="field">
                <sd-field-picker
                  v-model="model.field"
                  :form-id="formId"
                  :disabled-types="['OpinionView', 'attachment', 'collection']"
                />
              </sd-form-item>
              <sd-form-item name="opType" />
              <sd-form-item name="value">
                <a-select
                  v-if="model.opType === 'var'"
                  v-model="model.value"
                  :options="customFieldsOptions"
                />
              </sd-form-item>
            </template>
            <template v-slot:field="{ text }">
              {{ JSON.parse(text || '[{}]')[0].name || '' }}
            </template>
            <template v-slot:value="{ text }">
              {{ getCustomFieldLabel(text) }}
            </template>
          </sd-child-table>
        </a-tab-pane>
        <a-tab-pane :key="3" tab="其他">
          <a-card :class="$style.otherset">
            <!-- 可视化的无流程表单列表配置时可选择是否新窗口 -->
            <div v-if="!isFlow && isOnline">
              <label :class="$style.label">详情打开方式</label>
              <a-radio-group v-model="isNewWindow" button-style="solid" size="small">
                <a-radio-button :value="false" title="新建或编辑表单时在当前页面显示">
                  当前页
                </a-radio-button>
                <a-radio-button :value="true" title="新建或编辑表单时打开新窗口显示">
                  新窗口
                </a-radio-button>
              </a-radio-group>
            </div>
            <!-- 列表高级查询区域默认显示 -->
            <div>
              <label :class="$style.label">高级查询默认状态</label>
              <a-radio-group v-model="defaultShowAdvSearch" button-style="solid" size="small">
                <a-radio-button :value="false">
                  收起
                </a-radio-button>
                <a-radio-button :value="true">
                  展开
                </a-radio-button>
              </a-radio-group>
            </div>
            <div>
              <label :class="$style.label">隐藏按钮</label>
              <a-radio-group v-model="formListReadonly" button-style="solid" size="small">
                <a-radio-button :value="true">
                  是
                </a-radio-button>
                <a-radio-button :value="false">
                  否
                </a-radio-button>
              </a-radio-group>
            </div>
            <div>
              <label :class="$style.label">滚动区域宽</label>
              <a-input-number
                :value="scrollX"
                class="sd-shrinking-input"
                :min="1"
                @change="
                  (value) => {
                    debounce(() => {
                      scrollX = value
                    }, 200)()
                  }
                "
              />
            </div>
          </a-card>
        </a-tab-pane>
      </a-tabs>
    </a-card>
  </a-modal>
</template>

<script>
import debounce from 'lodash.debounce'
import pickValues from '@/common/services/pick-values'
import axios from '@/common/services/axios-instance'
import sdListPickerVue from '@/common/components/sd-list-picker.vue'
import { message } from 'ant-design-vue'
import components from './_import-components/sd-business-list-config-import'
export default {
  name: 'SdBusinessListConfig',
  metaInfo: {
    title: '列表设置',
  },
  components,
  props: {
    readOnly: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      visible: false,
      searchValue: '',
      configColumns: [
        {
          title: '字段',
          dataIndex: 'fieldName',
          scopedSlots: { customRender: 'fieldName' },
          width: '200px',
        },
        {
          title: '显示',
          dataIndex: 'show',
          scopedSlots: { customRender: 'show' },
        },
        {
          title: '宽度',
          dataIndex: 'width',
          scopedSlots: { customRender: 'width' },
          width: '200px',
        },
        {
          title: '查询',
          dataIndex: 'search',
          scopedSlots: { customRender: 'search' },
        },
        {
          title: '支持排序',
          dataIndex: 'sort',
          scopedSlots: { customRender: 'sort' },
        },
        {
          title: '支持点击',
          dataIndex: 'clickable',
          scopedSlots: { customRender: 'clickable' },
        },
      ],
      onlListColumnDefs: [],
      isFlow: false,
      isNewWindow: false,
      isOnline: true, // 自定义表单
      saveParmas: {},
      defaultShowAdvSearch: false,
      tabkey: 1,
      tabs: undefined,
      customFields: undefined,
      filterFormulaObject: undefined,
      btnCfgColumns: [
        {
          title: '按钮名称',
          dataIndex: 'buttonName',
          scopedSlots: { customRender: 'buttonName' },
        },
        {
          title: '按钮编码',
          dataIndex: 'buttonId',
        },
        {
          title: '按钮说明',
          dataIndex: 'buttonDesc',
        },
      ],
      buttonsList: [],
      selectedRowKeys: [],
      formId: '',
      formListReadonly: false,
      newConfig: {
        defaultValues: [],
      },
      defValFields: [
        {
          name: 'field',
          caption: '字段',
          dataType: 'string',
          required: true,
          attr: {},
        },
        {
          name: 'opType',
          caption: '赋值方式',
          dataType: 'selectlist',
          attr: {
            defaultValue: 'manual',
            selectListItem: [
              { label: '手动输入', value: 'manual' },
              { label: '选择变量', value: 'var' },
            ],
          },
        },
        {
          name: 'value',
          caption: '值',
          dataType: 'string',
          attr: {},
        },
      ],
      scrollX: undefined,
      debounce: debounce,
    }
  },
  computed: {
    columns() {
      return this.onlListColumnDefs
        .filter((item) => item.show)
        .map((item) => ({
          title: item.fieldName,
          dataIndex: item.fieldId,
          sorter: item.sort === 1,
          ...item.attrFD,
          sdCandidate: item.show === 2,
        }))
    },
    sortFields: {
      get: function() {
        return this.onlListColumnDefs
          .filter((item) => item.sortMode)
          .sort((a, b) => a.sortSeq - b.sortSeq)
      },
      set: function(newValue) {
        newValue.forEach((item, index) => {
          item.sortSeq = index
        })
      },
    },
    onlListColumnDefsFilter() {
      return this.onlListColumnDefs.filter((item) => item.fieldName.includes(this.searchValue))
    },
    fields() {
      const fields = this.onlListColumnDefs
        .filter((item) => item.searchConfigurable && !item.fieldId.includes('.'))
        .map((item) => {
          return {
            attr: item.fieldAttr,
            attrFD: item.fieldAttrFD,
            name: item.fieldId,
            caption: item.fieldName,
            dataType: item.fieldType.replace(/selectgroup|selectuser/, 'selectperson'),
          }
        })
      if (this.isFlow) {
        fields.push({
          name: 'FLOW_STATUS',
          caption: '流程状态',
          dataType: 'number',
        })
      }
      return fields
    },
    viewtabs() {
      let t = this.tabs?.filter((t) => t.label)
      if (!t?.length) {
        t = [{ label: '全部' }]
        if (this.isFlow) t = [{ label: '已办结' }, { label: '办理中' }, { label: '全部' }]
      }
      return t
    },
    searchFields() {
      return this.onlListColumnDefs.filter((i) => i.search)
    },
    customFieldsOptions() {
      return this.customFields.map((c) => ({ value: c.name, label: c.caption }))
    },
  },
  methods: {
    getCustomFieldLabel(name) {
      return this.customFields.find((c) => c.name === name)?.caption || name
    },
    addButton() {
      this.$refs.buttonModal?.show()
    },
    saveButton(data) {
      const { rowIndex, ...button } = data
      if (rowIndex !== undefined) {
        this.$set(this.buttonsList, rowIndex, button)
      } else {
        this.buttonsList.push(button)
      }
    },
    editButton(button, index) {
      this.$refs.buttonModal?.show({ ...button, rowIndex: index })
    },
    onSelectChange(selectedRowKeys) {
      this.selectedRowKeys = selectedRowKeys
    },
    removeButton() {
      if (this.selectedRowKeys.length) {
        this.buttonsList = this.buttonsList.filter(
          (b) => !this.selectedRowKeys.includes(b.buttonId)
        )
        this.selectedRowKeys = []
      }
    },
    checkButton(button) {
      return new Promise((resolve) => {
        const { rowIndex, buttonId } = button
        const repeatIndex = this.buttonsList.findIndex(
          (b, i) => b.buttonId === buttonId && rowIndex !== i
        )
        if (repeatIndex !== -1) {
          resolve({ code: -1, message: '按钮编码重复' })
        }
        resolve({ code: 1 })
      })
    },
    selectValue() {
      pickValues(sdListPickerVue, {
        loadListData: () => {
          return this.onlListColumnDefs.filter((item) => item.sortConfigurable)
        },
        optionLabel: 'fieldName',
        optionValue: 'fieldId',
        value: this.sortFields,
      }).then((values) => {
        if (values === undefined) return
        this.onlListColumnDefs.forEach((item) => {
          if (values.find((i) => i.fieldId === item.fieldId) === undefined) {
            // 没有选择的排序字段的排序规则清空
            item.sortMode = null
          }
        })
        values.forEach((item, index) => {
          // 保留上次选择时设置的状态
          const c = this.onlListColumnDefs.find((i) => i.fieldId === item.fieldId)
          item.sortSeq = index
          // 默认升序
          c.sortMode = item.sortMode || 'ASC'
        })
      })
    },
    save() {
      this.onlListColumnDefs.forEach((item, index) => (item.showSeq = index))
      // 自定义表单、代码开发表单
      const url = 'api/framework/v1/we-app-form-list/save'
      axios
        .post(url, {
          ...this.saveParmas,
          onlListColumnDefs: this.onlListColumnDefs,
          attr: {
            detailNewWindow: this.isNewWindow,
            defaultShowAdvSearch: this.defaultShowAdvSearch,
            tabs: this.tabs?.filter((item) => item.label),
            customFields: this.customFields?.filter((item) => item.caption),
            filterFormulaObject: this.filterFormulaObject,
            buttons: this.buttonsList,
            readonly: this.formListReadonly,
            newConfig: this.newConfig,
            scrollX: this.scrollX,
          },
        })
        .then(() => {
          message.success('保存成功')
        })
    },
    processReq(req) {
      req.method = 'get'
      return req
    },
    processRes(res) {
      return { datas: [], total: 0 }
    },
    initd() {
      this.tabkey = 1
      this.selectedRowKeys = []
    },
    show(record) {
      this.initd()
      this.isOnline = record.isOnline
      this.isFlow = record.isFlow
      axios
        .get(
          `api/framework/v1/we-app-form-list/show?isShowChildColumn=1&appModuleId=${record.id}&formListId=${record.formListId}`
        )
        .then((res) => {
          const data = res.data
          this.saveParmas = data
          this.isNewWindow = data.attr?.detailNewWindow ?? false
          // 代码开发的无流程表单，默认为新窗口打开
          if (!this.isOnline && !this.isFlow) {
            this.isNewWindow = true
          }
          this.defaultShowAdvSearch = data.attr?.defaultShowAdvSearch ?? false
          this.onlListColumnDefs = data.onlListColumnDefs
            .filter(
              (item) =>
                item.fieldAttrFD?.cid !== 'sd-linked-data' && item.fieldType !== 'relateddoc'
            )
            .sort((a, b) => (a.showSeq ?? 999) - (b.showSeq ?? 999))
            .map((f) => {
              // 无[支持点击]配置时，显示列默认可点击（兼容历史数据）
              if (f.attrFD.clickable === undefined) {
                f.attrFD.clickable = !!f.show
              }
              return f
            })
          if (!this.onlListColumnDefs.some((item) => item.sortMode)) {
            // 设置一个默认排序
            const field = this.onlListColumnDefs.find((item) =>
              ['creationTime', 'CREATION_TIME'].includes(item.fieldId)
            )
            if (field) {
              field.sortMode = 'DESC'
            }
          }
          this.tabs = data.attr?.tabs || []
          this.customFields = data.attr?.customFields || []
          this.filterFormulaObject = data.attr?.filterFormulaObject
          this.buttonsList = data.attr?.buttons || []
          this.formListReadonly = data.attr?.readonly ?? false
          this.formId = data.formId?.replace('onlhead:', '')
          this.newConfig = data.attr?.newConfig || {}
          this.visible = true
          this.scrollX = data.attr?.scrollX
        })
    },
  },
}
</script>

<style module lang="scss">
@use '@/common/design' as *;
@import './advance-search.scss';
.save {
  height: auto;
  padding-right: 70px;
}
.modal {
  :global(.ant-modal) {
    // 覆盖style标签里面的样式
    /* stylelint-disable-next-line  */
    top: 0 !important;
  }
  :global(.ant-modal-body) {
    height: 100vh;
    max-height: 100vh;
    padding: 0;
  }
}
.wrapper {
  height: calc(100% - 600px);
  table {
    table-layout: fixed;
  }
  :global(.ant-card-body) {
    height: calc(100% - 60px);
    overflow: scroll;
  }
}
.preview {
  height: 220px;
  overflow: hidden;
  :global(.ant-table-empty div.ant-table-body) {
    /* stylelint-disable-next-line  */
    overflow-x: auto !important;
  }
}
.otherset {
  :global(.ant-card-body) {
    > div {
      margin-bottom: 20px;
    }
  }
  .label {
    margin-right: 10px;
    font-size: $font-size-lg;
    font-weight: 500;
    color: $heading-color;
  }
}
.row {
  display: flex;
  align-items: center;
  width: 100%;
  :global(.handle) {
    display: flex;
    align-items: center;
    align-self: stretch;
    width: 15px;
  }
  /* stylelint-disable-next-line */
  :global(.handle_sd-draggable_common::before) {
    position: absolute;
    /* stylelint-disable-next-line */
    color: #999;
    content: '\22EE\22EE';
  }
}
.hidden-tab {
  :global(.ant-tabs-bar) {
    visibility: hidden;
  }
}
.clickable {
  color: $primary-color;
  cursor: pointer;
  &:hover {
    color: $primary-5;
  }
  &:active {
    color: $primary-7;
  }
}
</style>
