<template>
  <div class="select-table">
    <div class="select-table-box">
      <page-layout-list class="dialog-table">
        <template #filter v-if="searchFieldList.length > 0">
          <cip-search-form v-model:model="searchFilter" :field-list="searchFieldList" @search="handleSearch"></cip-search-form>
        </template>
        <cip-table v-if="checkType === 'radio'"
                  :data="itemList"
                  :columns="tableColumns"
                  :offset="offset"
                  ref="tableRef"
                  size="small"
                  :select-type="checkType"
                  :select-radio="selectRadio"
                  :select-label="optionProps.value"
                  @current-change="currentChange"
                  v-loading="listLoading">
        </cip-table>
        <cip-table v-if="checkType === 'checkbox'"
                  :data="itemList"
                  :columns="tableColumns"
                  :offset="offset"
                  ref="tableRef"
                  size="small"
                  :select-type="checkType"
                  @select="onSelect"
                  @select-all="onSelectAll"
                  :selectable="selectable"
                  v-loading="listLoading">
        </cip-table>
        <template #pagination v-if="withPagination">
          <cip-pagination v-model:offset="offset"
                          v-model:limit="limit"
                          :total="total"
                          :current-page="currentPage"
                          @refresh="getItemList"></cip-pagination>
        </template>
      </page-layout-list>
      <slot name="group"></slot>
      <tags v-if="!$slots.group && withTags" class="dialog-tags" :options="checkOptions" :keyProp="optionProps" @update:options="changeOptions"></tags>
    </div>
  </div>
</template>

<script>
import { useCurd } from '@cip/hooks/use-curd'
import { useTableCacheSelect } from '@cip/components/hooks/table-cache-select'
import { ref, computed, nextTick, watch, watchEffect } from 'vue'
import { ElLoading } from 'element-plus'
import PageLayoutList from '@cip/components/page-layout/list'
import CipSearchForm from '@cip/components/cip-search-form'
import CipTable from '@cip/components/cip-table'
import CipPagination from '@cip/components/cip-pagination'
import { useFormInput, useOptions } from '@cip/components/hooks/form-input'
import { formInputProps } from '../../form-input-props'
import Tags from './tags'
export default {
  components: { Tags, PageLayoutList, CipSearchForm, CipTable, CipPagination },
  directives: {
    loading: ElLoading.directive
  },
  props: formInputProps,
  emits: ['update:modelValue'],
  setup (props, context) {
    const { emitInput, ...formInput } = useFormInput(props, context)
    const { optionProps } = useOptions(props, false, formInput.emitInput)
    const checkOptions = computed(() => {
      return cacheSelectedList.value.length === 0 ? props.modelValue : cacheSelectedList.value
    })
    // 类型
    const checkType = computed(() => {
      return props.config?.checkType ?? 'radio'
    })
    // 列表头
    const tableColumns = computed(() => {
      return props.config?.tableColumns ?? []
    })
    // 搜索头
    const searchFieldList = computed(() => {
      return props.config?.searchFieldList ?? []
    })
    // 是否显示分页
    const withPagination = computed(() => {
      return props.config?.withPagination ?? true
    })
    // 是否显示选中tag
    const withTags = computed(() => {
      return props.config?.withTags ?? true
    })
    // 表格行是否可选，这里整个表格行为一致, selectable为function
    const selectable = computed(() => {
      return props.config?.selectable ?? (() => true)
    })

    // 右侧数据改变
    const changeOptions = (item) => {
      cacheSelectedList.value = item
      emitInput(item)
      handleSelectShow()
    }

    const tableRef = ref()
    const CURD = useCurd(props.config.entity, { ...props.config.curdFn, itemType: props.config.itemType })
    const { itemList, getItemList, searchFilter, search } = CURD
    watch(() => props.config?.defaultSearchFilter, val => {
      getTableList(val)
    })
    // 外层触发请求
    const getTableList = (item = {}) => {
      searchFilter.value = { ...props.config.defaultSearchFilter, ...searchFilter.value, ...item }
      getItemList()
    }
    getTableList()

    const { cacheSelectedList, onSelect, onSelectAll } = useTableCacheSelect(itemList, optionProps.value.value, val => {
      emitInput(val)
    })

    // 已选择的radio
    const selectRadio = computed(() => {
      if (props.modelValue && props.modelValue[optionProps.value.value]) {
        return props.modelValue[optionProps.value.value]
      }
      return radioCache.value
    })
    // radio类型时的缓存
    const radioCache = computed(() => {
      const cache = itemList.value?.find(v => v[optionProps.value.value] === props.modelValue)
      return cache ? cache[optionProps.value.value] : undefined
    })
    const currentChange = (currentRow, oldCurrentRow) => {
      // 单选不能取消，只能有值时才填入
      if (currentRow) {
        emitInput(currentRow[optionProps.value.value])
      }
    }

    // checkbox类型更新选中视图
    const showSelectedView = (rows, select) => {
      nextTick(() => {
        rows.forEach(row => {
          tableRef.value.cipTableRef.value.toggleRowSelection(row, select)
        })
      })
    }
    // tag组件传入值需要更新table选中视图
    const handleSelectShow = () => {
      const selectedPropsCode = cacheSelectedList.value.map(button => button[optionProps.value.value])
      const rows = itemList.value.filter(item => {
        return !selectedPropsCode.includes(item[optionProps.value.value])
      })
      showSelectedView(rows, false)
    }
    if (checkType.value === 'checkbox') {
      // 分页切换时缓存数据处理
      watch(() => [itemList.value, props.modelValue], list => {
        cacheHandle()
      })
    } else {
      const unWatch = watchEffect(() => {
        if (props.modelValue && props.modelValue[optionProps.value.value]) {
          const checkItem = itemList.value.filter(item => item[optionProps.value.value] === props.modelValue[optionProps.value.value])[0]
          if (checkItem) {
            emitInput(checkItem)
            unWatch()
          }
        }
      })
    }
    // 缓存数据处理
    const cacheHandle = () => {
      if (cacheSelectedList.value.length === 0) {
        cacheSelectedList.value = props.modelValue ?? []
      }
      const cacheSelectButtonCode = cacheSelectedList.value.map(button => button[optionProps.value.value])
      const rows = itemList.value.filter(item => {
        const selectList = props.modelValue || (cacheSelectButtonCode.includes(item[optionProps.value.value]) ? cacheSelectButtonCode : [])
        return selectList.findIndex(v => v[optionProps.value.value] === item[optionProps.value.value]) !== -1
      })
      showSelectedView(rows, true)
    }
    // 搜索
    const handleSearch = () => {
      search()
    }

    return {
      changeOptions,
      checkOptions,
      getTableList,
      handleSearch,
      optionProps,
      checkType,
      tableColumns,
      searchFieldList,
      withPagination,
      withTags,

      ...CURD,
      tableRef,
      selectable,
      selectRadio,
      currentChange,
      onSelect,
      onSelectAll,
      cacheSelectedList
    }
  }
}
</script>

<style lang="less" scoped>
.select-table{
  flex: 1;
  .select-table-box{
    display: flex;
  }
  .dialog-table{
    flex: 1;
    margin: 0 15px 15px 0;
    padding: 0;
  }
  .dialog-tags{
    padding: 8px 0;
    flex-basis: 220px;
  }
}
</style>
