<template>
  <div class="app-table" v-loading="loading">
    <div class="app-table__header">
      <div class="block block--left">
        <slot name="headerLeft"></slot>
      </div>
      <div class="block block--right">
        <slot name="headerRight"></slot>
        <el-button-group v-if="showToolbar">
          <slot name="toolbar"></slot>
          <el-button icon="Refresh" @click="refresh" />
          <el-button icon="Setting" @click="showTableSetting = true" />
        </el-button-group>
      </div>
    </div>
    <div class="app-table__container">
      <el-table ref="tableRef" height="100%" :header-cell-class-name="selectionType" v-bind="$attrs"
        :highlight-current-row="highlightCurrentRow" scrollbar-always-on @row-click="onRowClick"
        @expand-change="onRowClick" @select="onSelect" @select-all="onSelect" border>
        <!-- 展开行 -->
        <el-table-column type="expand" v-if="$slots.expand">
          <template #default="{ row, $index }">
            <slot name="expand" :row="row" :index="$index"></slot>
          </template>
        </el-table-column>
        <!-- 选择列 -->
        <el-table-column type="selection" :selectable="selectable" width="55" align="center" fixed
          v-if="selectionType" />
        <!-- 序号 -->
        <el-table-column type="index" :label="t('common.orderindex')" align="center" :width="80" v-if="showIndex" />
        <!-- 数据列 -->
        <template v-for="(item, index) in columns" :key="index">
          <el-table-column :align="item.align ?? 'center'" :min-width="120" :width="item.width"
            :label="t(item.formatLabel?.() ?? item.label)" :prop="item.field" :fixed="item.fixed || false"
            :sortable="item.sortable" :show-overflow-tooltip="item.field !== 'operate'" v-if="item.show ?? true">
            <template #default="{ row, $index }">
              <slot :name="item.field" :row="row" :value="row[item.field]" :index="$index">
                <span :class="item.className">{{ handleValue(row, item) }}</span>
              </slot>
            </template>
          </el-table-column>
        </template>
        <template #append v-if="$slots.append">
          <slot name="append"></slot>
        </template>
      </el-table>
    </div>
    <div class="app-table__footer">
      <slot name="footer"></slot>
    </div>
    <app-table-setting :columns="columns" @update="updateColumn" @closed="showTableSetting = false"
      v-if="showTableSetting" />
  </div>
</template>

<script lang="ts">
import { defineComponent, shallowRef, PropType } from 'vue'
import { handleNoneValue } from '@/filters'
import AppTableSetting from '../table-setting/index.vue'
import { i18n } from '@/stores';

export default defineComponent({
  inheritAttrs: false,
  components: {
    AppTableSetting
  },
  emits: ['refresh', 'update:columns', 'rowClick', 'select', 'selectable'],
  props: {
    columns: {
      type: Array as PropType<Model.TableColumn[]>,
      default: () => ([])
    },
    // 是否显示头部工具栏
    showToolbar: Boolean,
    loading: Boolean,
    showIndex: Boolean,
    // 是否要高亮当前行
    highlightCurrentRow: {
      type: Boolean,
      default: true
    },
    // 选择列类型
    selectionType: {
      type: String as PropType<'single' | 'multiple'>,
    }
  },
  setup(props, { emit, expose }) {
    const tableRef = shallowRef()
    const tableRadio = shallowRef()
    const showTableSetting = shallowRef(false)
    const refresh = () => emit('refresh')
    const updateColumn = (value: Model.TableColumn[]) => emit('update:columns', value)

    const { global: { t } } = i18n

    // 当某一行被勾选时触发的事件
    const onSelect = (selection: unknown[], currentRow: unknown) => {
      const el = tableRef.value
      const rows = selection.filter((e) => {
        if (props.selectionType === 'single') {
          if (e === currentRow) {
            el.setCurrentRow(currentRow) // 高亮行
            return true
          } else {
            el.toggleRowSelection(e, false) // 单选取消其他选中的行
            return false
          }
        }
        return true
      })
      emit('select', rows, currentRow)
    }

    // 选择列是否可以勾选，通过 callback 改变选中值
    const selectable = (row: unknown) => {
      let isSelected = true
      const callback = (value: boolean) => {
        isSelected = value
      }
      emit('selectable', row, callback)
      return isSelected
    }

    // 当某一行被点击时选中该行
    const onRowClick = (row: unknown) => {
      // if (props.selectionType) {
      //   const el = tableRef.value
      //   const selection = el.getSelectionRows()
      //   const selected = selection.find((e: unknown) => e === row)
      //   el.toggleRowSelection(row, selected ? false : true)
      //   onSelect(el.getSelectionRows(), row)
      // }
      emit('rowClick', row)
    }

    const handleValue = (row: { [key: string]: unknown }, column: Model.TableColumn) => {
      const value = row[column.field]
      const formattedValue = column.formatValue ? column.formatValue(value) : value

      if (Number.isFinite(formattedValue) && column.decimal) {
        return Number(formattedValue).toFixed(column.decimal)
      }

      return handleNoneValue(formattedValue)
    }

    // 监听滚动条
    // onMounted(() => {
    //   const scrollbar = tableRef.value?.scrollBarRef
    //   const wrap = scrollbar?.wrapRef
    //   wrap?.addEventListener('scroll', (e: Event) => {
    //     const el = e.target as HTMLElement
    //     console.log(el.scrollTop)
    //   })
    // })

    // 暴露组件属性
    expose({
      elTable: tableRef
    })

    return {
      tableRef,
      tableRadio,
      showTableSetting,
      onSelect,
      selectable,
      onRowClick,
      handleValue,
      refresh,
      updateColumn,
      t
    }
  },
})
</script>

<style lang="less">
@import './index.less';
</style>