<template>
  <div class="basic-table">
    <cip-table :offset="offset"
               v-model:data="proxyValue"
               :columns="options"
               :depend-on-values="dependOnValues"
               :border="!hideBorder"
               :field-key="fieldKey"
               :row-key="securityConfig.rowKey"
               :tree-props="optionProps"
               :default-expand-all="securityConfig.defaultExpendAll"
               :rule-key="securityConfig.ruleKey || fieldKey"
               :tableHeaderLabel="securityConfig.tableHeaderLabel"
               :hide-index="securityConfig.hideIndex"
               :index-fixed="securityConfig.indexFixed ?? true"
               :show-summary="securityConfig.showSummary"
               :span-method="securityConfig.spanMethod"
               :height="securityConfig.height"
               :expandRender="securityConfig.expandRender"
               size="default"
               :stripe="true"
               :in-form="true">
      <el-table-column :min-width="isTreeTable && !securityConfig.hideAddChild ? '90px':'70px'" v-if="!securityConfig.hideDelete" fixed="right" label="操作">
        <template #default="{$index, row}">
          <cip-button-text v-if="!securityConfig.hideAdd" @click="insertItem($index)">
            <i class="el-icon-circle-plus-outline cip-primary-color  handler-size"/>
          </cip-button-text>
          <template v-if="isTreeTable && !securityConfig.hideAddChild">
            <cip-button-text @click="insertChildItem($index,row)">
              <svg t="1656469520966" class="handler-size"  viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1591" width="1em" height="1em">
                <path style="transform: scale(0.5)" stroke-width="24px" stroke="currentColor" fill="currentColor" d="M778.5984 619.52H727.04v-51.5584c0-11.3152-9.1648-20.48-20.48-20.48s-20.48 9.1648-20.48 20.48V619.52h-51.5584c-11.3152 0-20.48 9.1648-20.48 20.48s9.1648 20.48 20.48 20.48H686.08v51.5584c0 11.3152 9.1648 20.48 20.48 20.48s20.48-9.1648 20.48-20.48V660.48h51.5584c11.3152 0 20.48-9.1648 20.48-20.48s-9.1648-20.48-20.48-20.48z"   p-id="1592"></path>
                <path stroke-width="24px" stroke="currentColor" fill="currentColor" d="M704 404.48c-122.624 0-223.0784 94.8224-232.192 215.0912-0.256 0-0.512-0.0512-0.768-0.0512H286.72V194.56h419.84c11.3152 0 20.48-9.1648 20.48-20.48s-9.1648-20.48-20.48-20.48H107.52c-11.3152 0-20.48 9.1648-20.48 20.48s9.1648 20.48 20.48 20.48h138.24v445.44c0 11.3152 9.1648 20.48 20.48 20.48h204.8c0.4096 0 0.768-0.1024 1.1264-0.1024C483.6864 778.24 583.0656 870.4 704 870.4c128.6656 0 232.96-104.2944 232.96-232.96S832.6656 404.48 704 404.48z m0 424.96c-105.8816 0-192-86.1184-192-192S598.1184 445.44 704 445.44s192 86.1184 192 192-86.1184 192-192 192z"  p-id="1593"></path>
              </svg>
            </cip-button-text>
          </template>
          <cip-button-text @click="deleteItem($index, row)">
            <i class="el-icon-remove-outline cip-danger-color handler-size"/>
          </cip-button-text>
        </template>
      </el-table-column>
    </cip-table>
    <div style="text-align: center" v-if="!securityConfig.hideAdd">
      <cip-button-text size="large" @click="addItem">
        <i  class="el-icon-circle-plus create-handle" />
      </cip-button-text>
    </div>
  </div>
</template>
<script>
import { computed, defineAsyncComponent, nextTick } from 'vue'
import { formInputProps, fromInputEmits } from '@cip/components/cip-form-input/form-input-props'
import { ElMessageBox, ElTableColumn } from 'element-plus'
import { useFormInput, useElementFormEvent } from '@cip/components/hooks/form-input'
import CipButtonText from '@cip/components/cip-button-text'
import { v4 as uuid } from 'uuid'
import { setOptionWritable } from './util'
import { setFieldValue, getFieldValue } from '@cip/utils/util'
import { analyseData, getPropertyKeyByPath } from '../../../cip-table/util'
export default {
  name: 'basic-table',
  components: {
    CipTable: defineAsyncComponent(() => import('@cip/components/cip-table')),
    CipButtonText,
    ElTableColumn
  },
  props: {
    ...formInputProps,
    type: {
      default: 'input'
    }
  },
  emits: [...fromInputEmits],
  setup (props, context) {
    const { handleChange } = useElementFormEvent() // inject('elFormItem', {})
    const formInput = useFormInput(props, context)
    const { proxyValue, securityConfig } = formInput

    const offset = computed(() => {
      return securityConfig.value.hideIndex ? undefined : 0
    })
    const hideBorder = computed(() => {
      return securityConfig.value.hideBorder
    })
    const optionProps = computed(() => {
      // el-table 默认treeProps参数
      return Object.assign({ children: 'children', hasChildren: 'hasChildren' }, securityConfig.value.optionProps)
    })
    const isTreeTable = computed(() => {
      // 只要设置了rowKey即认为该表单可能是树形表单
      return securityConfig.value.rowKey
    })
    const options = computed(() => {
      let options = securityConfig.value.options || []
      if (securityConfig.value.tableColumnStatus === 'writable') {
        options = setOptionWritable(options, true)
      }
      return options
    })

    const emitItemValidate = (val) => { // 触发验证
      nextTick(() => {
        handleChange(val)
      })
    }
    const getNewItem = () => {
      // tree 新增时必须由唯一key
      return isTreeTable.value ? { $id: uuid() } : {}
    }
    // 插入一个最后的行
    const addItem = () => {
      const val = Array.isArray(proxyValue.value) ? proxyValue.value : []
      const newItem = getNewItem()
      val.push(newItem)
      emitItemValidate(val)
      proxyValue.value = val
    }
    // 在当前行上方插入
    const insertItem = (index) => {
      const allArray = props.modelValue || []
      const newItem = getNewItem()
      if (isTreeTable.value) {
        const indexed = analyseData(allArray, optionProps.value)
        const realIndexArr = indexed[index]
        if (realIndexArr.length > 1) {
          const realIndex = realIndexArr.pop() // realIndex 为要剔除的index realIndexArr为父数组下标
          const key = getPropertyKeyByPath(realIndexArr, optionProps.value)
          const parentArr = getFieldValue(allArray, key)
          parentArr[optionProps.value.children].splice(realIndex, 0, newItem)
        } else {
          allArray.splice(realIndexArr[0], 0, newItem)
        }
      } else {
        allArray.splice(index, 0, newItem)
      }
      emitItemValidate(allArray)
      proxyValue.value = allArray
    }
    // 插入一个最后的子行
    const insertChildItem = (index, row) => {
      if (isTreeTable.value) {
        const newItem = getNewItem()
        const children = getFieldValue(row, optionProps.value.children)
        if (!children) {
          setFieldValue(row, optionProps.value.children, [newItem])
        } else {
          children.push(newItem)
        }
      }
    }
    // 删除当前行
    const deleteItem = (index) => {
      ElMessageBox.confirm('确实删除此列', '提示').then(() => {
        const allArray = props.modelValue || []
        if (isTreeTable.value) {
          const indexed = analyseData(allArray, optionProps.value)
          const realIndexArr = indexed[index]
          if (realIndexArr.length > 1) {
            const realIndex = realIndexArr.pop() // realIndex 为要剔除的index realIndexArr为父数组下标
            const key = getPropertyKeyByPath(realIndexArr, optionProps.value)
            const parentArr = getFieldValue(allArray, key)
            parentArr[optionProps.value.children].splice(realIndex, 1)
          } else {
            allArray.splice(realIndexArr[0], 1)
          }
        } else {
          allArray.splice(index, 1)
        }
        emitItemValidate(allArray)
        proxyValue.value = allArray
      }).catch(() => {})
    }

    return {
      offset,
      hideBorder,
      options,
      securityConfig,
      isTreeTable,
      insertItem,
      insertChildItem,
      deleteItem,
      addItem,
      proxyValue,
      optionProps
    }
  }
}
</script>
<style lang="less">
@import "./index.less";
</style>
