<template>
  <div :class="$style.wrapper">
    <div :class="[$style.caption, !label && readOnly ? $style.hideCaption : '']">
      <span class="child-table-title">{{ label }}</span>
      <div v-if="!readOnly" :class="$style.header">
        <a-space>
          <!-- <a-button
            v-if="value.length < max && !disableAd"
            type="link"
            :disabled="selectedRowKeys.length === 0"
            @click="duplicate(selectedRowKeys)"
          >
            <a-icon type="plus-circle" :theme="'filled'" />
            复制
          </a-button> -->
          <a-dropdown-button
            v-if="allowImport && value.length < max"
            :trigger="['click']"
            placement="bottomRight"
          >
            <a-upload :before-upload="importFromExcel" accept=".xlsx,.xls"> Excel导入 </a-upload>
            <a-menu slot="overlay" :class="$style.menu">
              <a-menu-item @click="exportTemplate"> 导出模板 </a-menu-item>
            </a-menu>
          </a-dropdown-button>
          <a-button
            v-for="(btn, index) in headerButtons"
            :key="index"
            type="link"
            :disabled="btn.buttonType === 'batch' ? selectedRowKeys.length === 0 : false"
            :title="btn.buttonDesc"
            @click="buttonClick(btn)"
          >
            {{ btn.buttonName }}
          </a-button>
          <a-button
            v-if="!!multipleSelector"
            type="link"
            @click="() => pickerData(multipleSelector)"
          >
            <a-icon type="plus-circle" :theme="'filled'" />
            选择
          </a-button>
          <a-button
            v-if="value.length < max && !disableAd && addButtonShow"
            type="link"
            @click="add"
          >
            <a-icon type="plus-circle" :theme="'filled'" />
            新增
          </a-button>
          <a-button
            v-if="!disableAd && deleteButtonShow"
            type="link"
            :disabled="selectedRowKeys.length === 0"
            @click="remove(selectedRowKeys)"
          >
            <a-icon type="minus-circle" :theme="'filled'" />
            删除
          </a-button>
        </a-space>
      </div>
    </div>
    <sd-table
      ref="table"
      :key="sequenceColumn"
      size="middle"
      :columns="_columns"
      :sortable="false"
      :data-source="value"
      :row-key="(record, index) => record.id"
      :pagination="flagpage ? pagination : false"
      :row-selection="
        readOnly
          ? null
          : {
              getCheckboxProps(record) {
                return {
                  props: { disabled: !showSelection(record) },
                }
              },
              selectedRowKeys: selectedRowKeys,
              onChange: onSelectChange,
            }
      "
      :custom-row="
        (record, index) => {
          return {
            on: {
              click: () => {
                edit(record.id)
              },
            },
          }
        }
      "
      :bordered="nestedHeader"
      @update:data-source="emitValue"
      @change="onChange"
    >
      <template slot="index" slot-scope="text, record, index">
        {{ index + 1 }}
      </template>
      <template v-for="field in fields" :slot="'sd_' + field.name" slot-scope="text, record">
        <slot v-bind="{ field, text, record }" :name="field.name">
          <sd-attachment
            v-if="field.dataType === 'attachment' && text"
            :key="attkeys[record.id]"
            :group-id="JSON.parse(text).value"
            read-only
          />
          <sd-quill-reader v-else-if="field.dataType === 'tinymce'" :value="text" />
          <span v-else :key="field.name">
            {{ getDisplayVaule(field, text) }}
          </span>
        </slot>
      </template>
    </sd-table>
    <a-modal
      v-model="visible"
      :title="label || '详情'"
      destroy-on-close
      v-bind="{
        width:
          modalWidth ||
          ($attrs.modalProps && $attrs.modalProps.width) ||
          800 + (($attrs.childAttrFD && $attrs.childAttrFD.columns) || 0) * 150,
        bodyStyle: { minHeight: '380px' },
      }"
      :mask-closable="false"
      :footer="readOnly ? null : undefined"
      @ok="save"
      @cancel="attkeys[action] = Math.random()"
    >
      <sdForm
        ref="form"
        :init-values="editRecord"
        :read-only="readOnly"
        :form-relations="formRelations"
      >
        <template v-slot="scope">
          <!--
          @slot 详情表单内容,8.0.4及以后版本支持
          @binding {object} model 整个表单的数据，可用于 v-model 绑定
          @binding {object} fields 后台返回的字段定义
        -->
          <slot v-bind="scope" name="form">
            <sd-form-item
              v-for="field in fields"
              :key="field.name"
              :hidden="field.dataType === 'id'"
              :name="field.name"
              :label="field.dataType === 'collection' ? null : field.caption"
            />
          </slot>
        </template>
      </sdForm>
    </a-modal>
    <component :is="actionComponent" ref="actionComponent" />
  </div>
</template>

<script>
import cloneDeep from 'lodash.clonedeep'
import axios from '../services/axios-instance'
import sdChildTable from './sd-child-table/sd-child-table'
import components from './_import-components/sd-child-table-import'
/**
 * 主子表、动态表格字段
 * @displayName SdChildTable 主子表
 */
export default {
  name: 'SdChildTable',
  components: {
    ...components,
    sdForm: () => import('@/common/components/sd-form'),
  },
  mixins: [sdChildTable],
  props: {
    /**
     * 字表的值，{key:value}的格式
     */
    value: {
      type: Array,
      default: () => [],
    },
    /**
     * 字表的字段属性
     */
    fields: {
      type: Array,
      default: () => [],
    },
    /**
     * 是否只读
     */
    readOnly: {
      type: Boolean,
      default: false,
    },
    /**
     * 标签名
     */
    label: {
      type: String,
      default: '',
    },
    /**
     * 自定义子表列属性,如[{dataIndex:'shuxingmingzi15',width:'120px'}],8.0.4及以后版本支持
     */
    columns: {
      type: Array,
      default: () => [],
    },
    /**
     * 某行是否可选
     * @since 8.0.11
     */
    showSelection: {
      type: Function,
      default: () => true,
    },
    // 子组件接收函数
    handleBeforeAdd: {
      type: Function,
    },
    flagpage: {
      type: Boolean,
      default: false,
    },
    pages: {
      type: Number,
      default: 10,
    },
    modalWidth: {
      type: String,
      default: '1200px',
    },
    /**
     * 传给详情 modal 的 props，可以用于设置样式等
     */
    modalProps: {
      type: Object,
      default: undefined,
    },
    addButtonShow: {
      type: Boolean,
      default: true,
    },
    deleteButtonShow: {
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      editRecord: [], // 待修改或编辑的记录
    }
  },
  computed: {
    nestedHeader() {
      return this.columns.find((c) => !!c.children?.length) !== undefined
    },
    _columns() {
      const columnOrder = [...this.columns.map((item) => item.name)]
      // 按设置的列排个序
      const fields = JSON.parse(JSON.stringify(this.fields))
        .sort((a, b) => {
          return columnOrder.indexOf(a.name) - columnOrder.indexOf(b.name)
        })
        .filter((item) => !['id', 'collection'].includes(item.dataType))
        .filter((item) => item.sdHidden !== true)
      const order = {
        title: '序号',
        dataIndex: 'index',
        width: '50px',
        scopedSlots: { customRender: 'index' },
        sdHidden: this.sequenceColumn !== true,
      }
      if (this.nestedHeader) {
        // 如果包含嵌套的列，那就先用传过来的设置列再用，没被设置的其他列表
        const keys = []
        const columns = cloneDeep(this.columns)
        const f = (arr) => {
          arr.forEach((a) => {
            keys.push(a.dataIndex)
            a.title = a.title || fields.find((i) => i.name === a.dataIndex)?.caption
            a.key = a.dataIndex
            a.scopedSlots = { customRender: 'sd_' + a.dataIndex }
            if (a.children) f(a.children)
          })
        }
        f(columns)
        const othercolumns = fields
          .filter((item) => !keys.includes(item.name))
          .map((a) => {
            a.title = a.caption
            a.dataIndex = a.name
            a.scopedSlots = { customRender: 'sd_' + a.dataIndex }
            return a
          })
        return [...(this.sequenceColumn ? [order] : []), ...columns, ...othercolumns].filter(
          (item) => item.sdHidden !== true
        )
      }
      return [
        ...(this.sequenceColumn ? [order] : []),
        ...fields.map((item) => {
          const t = {
            dataIndex: item.name,
            key: item.name,
            title: item.caption,
            scopedSlots: { customRender: 'sd_' + item.name },
          }
          const column = this.columns.find((c) => c.dataIndex === item.name)
          if (column) Object.assign(t, column)
          return t
        }),
      ].filter((item) => item.sdHidden !== true)
    },
  },
  mounted() {
    // 默认排序，赋值有用
    Object.assign(this.defaultValue, this.value)
    this.pagination.pageSize = this.pages
    // 增加默认排序
    const defaultSorters = this.columns
      .filter((col) => col.defaultSortOrder)
      .map((col) => ({
        field: col.dataIndex,
        order: col.defaultSortOrder,
      }))
    // 排序方法
    if (defaultSorters.length > 0) {
      this.sorter = { ...defaultSorters[0] }
      this.sorterFun(defaultSorters[0], true)
    }
  },
  methods: {
    // 排序点击之后，重新排序
    onChange(pagination, filters, sorter) {
      this.sorter = { ...sorter }
      this.sorterFun(this.sorter)
    },
    // 排序方法
    sorterFun(sorts, isDefault) {
      if (!sorts) {
        // 如果没有sorts，说明是父组件调用，则增加默认值
        Object.assign(this.defaultValue, this.value)
        sorts = this.sorter
      }
      // 没有排序，则使用默认排序
      if (!sorts?.order) {
        while (this.value.length > 0) {
          this.value.splice(0, 1)
        }
        this.defaultValue.forEach((item) => {
          this.value.push(item)
        })
        return
      }
      const sortValue = this.value.sort((a, b) => {
        if (sorts.order === 'ascend') {
          // 升序
          if (a[sorts.field] + '' < b[sorts.field] + '') {
            return -1
          }
          if (a[sorts.field] + '' === b[sorts.field] + '') {
            return 0
          }
          if (a[sorts.field] + '' > b[sorts.field] + '') {
            return 1
          }
        } else {
          // 降序
          if (a[sorts.field] + '' < b[sorts.field] + '') {
            return 1
          }
          if (a[sorts.field] + '' === b[sorts.field] + '') {
            return 0
          }
          if (a[sorts.field] + '' > b[sorts.field] + '') {
            return -1
          }
        }
      })
      this.$set(this, 'value', sortValue)
    },
    setAttFieldId() {
      // 给创建的附件一个默认的id
      const atts = this.editRecord.filter((item) => item.dataType === 'attachment' && !item.value)
      return Promise.all(
        atts.map(() => {
          return axios('api/framework/v1/attachment-extend/attachments-create-group-code')
        })
      ).then((res) => {
        atts.forEach((att, index) => {
          att.value = JSON.stringify({
            value: res[index].data,
          })
        })
        this.visible = true
      })
    },
    add() {
      if (this.handleBeforeAdd) {
        this.handleBeforeAdd(null, (res) => {
          if (!res) {
            this.addMethod()
          }
        })
      } else {
        this.addMethod()
      }
    },
    addMethod() {
      this.editRecord = JSON.parse(JSON.stringify(this.fields))
      this.action = 'add'
      this.setAttFieldId()
    },
    edit(key) {
      this.editRecord = JSON.parse(JSON.stringify(this.fields))
      this.editRecord.forEach((item) => {
        // 把值放到字段信息fields里
        item.value = this.value.find((item) => item.id === key)[item.name]
      })
      // 设计产品定制过滤掉序号，产品不兼容 20230201
      this.editRecord = this.editRecord.filter((item) => {
        return (item.name !== 'sortNum') & (item.name !== 'xh')
      })
      axios.post('api/framework/v1/page/computeFieldValWithQLExpr', this.editRecord).then((res) => {
        res.data.forEach((item, index) => {
          this.editRecord[index].attr.displayFormulaValue = item.attr?.displayFormulaValue
        })
        this.setAttFieldId().then((res) => {
          this.action = key
        })
      })
    },
    save() {
      if (this.readOnly || !this.visible) {
        // 判断visable为false时，modal没有是为了防止快速重复点击确定
        this.visible = false
        return
      }
      this.$refs.form.validateFields().then(() => {
        const value = {}
        this.$refs.form.getBackendValues().forEach((item) => {
          value[item.name] = item.value
        })
        const data = this.value || [] // 兼容初始值是null的情况
        if (this.action === 'add') {
          // 新增
          data.push(value)
        } else {
          this.attkeys[this.action] = Math.random()
          const d = data.find((item) => item.id === this.action)
          Object.assign(d, value)
        }
        // 添加或修改之后，直接排序
        Object.assign(this.defaultValue, data)
        this.sorterFun(this.sorter)
        /**
         * 动态表格值变化时触发
         * @property {Object} data 子表的值
         */
        this.emitValue([...data])
        this.visible = false
      })
    },
  },
}
</script>

<style module lang="scss" src="./sd-child-table/sd-child-table.scss"></style>
