<template>
  <el-button
    v-bind="$attrs"
    :icon="Tools"
    color="#ac014d"
    class="column-set-button"
    @click="dialogShow"
  />
  <Dialog
    :flag="dialogFlag"
    width="1080px"
    msg-title="列设置"
    @submit-form="submitHandler"
    @reset-form="dialogHide"
  >
    <div class="dialog-content">
      <template v-if="inGroup">
        <div v-for="columnGroup in columnGroups" :key="columnGroup.title">
          <div class="group-title">{{ columnGroup.title }}</div>
          <el-checkbox-group
            v-model="tempGroups[columnGroup.title]"
            size="large"
          >
            <div
              v-for="column in columnGroup.columns"
              :key="column.columnName"
              class="checkbox-wrapper"
            >
              <el-checkbox
                :label="column.columnName"
                :disabled="column.checkDisabled"
                >{{ column.columnLabel?.replace('\n', '') }}</el-checkbox
              >
            </div>
          </el-checkbox-group>
        </div>
      </template>
      <template v-else>
        <el-checkbox-group v-model="tempKeys" size="large">
          <div
            v-for="column in needShowColumns"
            :key="column.columnName"
            class="checkbox-wrapper"
          >
            <el-checkbox
              :label="column.columnName"
              :disabled="column.checkDisabled"
            >
              {{ column.columnLabel?.replace('\n', '') }}
            </el-checkbox>
          </div>
        </el-checkbox-group>
      </template>
    </div>
  </Dialog>
</template>

<script setup lang="ts">
import { Tools } from '@element-plus/icons-vue'
import Dialog from '@/components/dialog/index.vue'
import { PropType } from 'vue'
import { CommonTableColumn, tableColumnGroup } from '~/common'
import { useTableSettingsStore } from '@/store/tableSettings'

const simpleClone = (obj: any) => JSON.parse(JSON.stringify(obj))

const props = defineProps({
  name: {
    type: String,
  },
  tableColumns: {
    type: Array as PropType<CommonTableColumn[]>,
    required: true,
  },
})

const emits = defineEmits(['checkedSubmit'])

const needShowColumns = computed(() =>
  props.tableColumns.filter(column => column.needShow)
)

const inGroup = computed(() => {
  return (
    'groupName' in
    (needShowColumns.value.length ? needShowColumns.value[0] : {})
  )
})

const dialogFlag = ref(false)
const dialogShow = () => {
  tempGroups.value = simpleClone(checkedGroups.value)
  tempKeys.value = simpleClone(checkedKeys.value)
  dialogFlag.value = true
}
const dialogHide = () => {
  dialogFlag.value = false
}
const submitHandler = () => {
  checkedGroups.value = simpleClone(tempGroups.value)
  checkedKeys.value = simpleClone(tempKeys.value)
  checkedSubmit()
  dialogHide()
}

const {
  savedHiddenColumnKeysMap,
  saveHiddenColumnKeys,
} = useTableSettingsStore()
const route = useRoute()

const checkedSubmit = () => {
  emits('checkedSubmit', checkedColumnKeys.value)
  updateHiddenColumnKeys()
}

const updateHiddenColumnKeys = () => {
  const hiddenColumnKeys = needShowColumns.value.reduce(
    (keys: string[], { columnName }) => {
      if (!checkedColumnKeys.value.includes(columnName)) {
        keys.push(columnName)
      }
      return keys
    },
    []
  )
  saveHiddenColumnKeys(hiddenColumnKeys)
}

const columnGroups = computed(() => {
  if (inGroup.value) {
    return needShowColumns.value.reduce((pre: tableColumnGroup[], curr) => {
      const theGroup = pre.find(
        columnGroup => columnGroup.title === curr.groupName
      )
      if (theGroup) {
        theGroup.columns.push(curr)
      } else {
        pre.push({
          title: curr.groupName,
          columns: [curr],
        })
      }
      return pre
    }, [])
  } else {
    return []
  }
})

// 分组的选择框
const checkedGroups = ref<any>({})
const tempGroups = ref<any>({})
//不分组的选择框
const checkedKeys = ref<string[]>([])
const tempKeys = ref<string[]>([])

const checkedColumnKeys = computed<string[]>(() => {
  if (inGroup.value) {
    return Object.keys(checkedGroups.value)
      .map(prop => checkedGroups.value[prop])
      .flat()
  } else {
    return checkedKeys.value
  }
})

const fullTableName = route.path + (props.name ? `/${props.name}` : '')

watch(needShowColumns, defaultColumns => {
  const savedHiddenColumnKeys = savedHiddenColumnKeysMap[fullTableName]
  const columns = defaultColumns.filter(column => {
    if (savedHiddenColumnKeys?.length) {
      return !savedHiddenColumnKeys.includes(column.columnName)
    }
    return !column.defaultHidden
  })

  if (inGroup.value) {
    checkedGroups.value = {}
    columns.forEach(({ columnName, groupName }) => {
      if (
        checkedGroups.value[groupName] &&
        checkedGroups.value[groupName] instanceof Array
      ) {
        checkedGroups.value[groupName].push(columnName)
      } else {
        checkedGroups.value[groupName] = [columnName]
      }
    })
  } else {
    checkedKeys.value = columns.map(({ columnName }) => columnName)
  }
  checkedSubmit()
})
</script>

<style scoped lang="scss">
.column-set-button {
  width: 30px;
  height: 30px;
  border-radius: 4px;
  font-size: 14px;
}

.dialog-content {
  padding: 0 22px;

  .group-title {
    font-size: 16px;
    font-family: Microsoft YaHei;
    font-weight: bold;
    color: #303133;
    margin: 22px 0;
  }

  .el-checkbox-group {
    display: flex;
    flex-wrap: wrap;
    align-content: center;
    .checkbox-wrapper {
      width: 20%;
      margin: 0;
    }
  }
}
</style>
