<script setup lang="ts">
import { ref, defineProps, withDefaults, defineEmits, watch, onBeforeUnmount } from "vue"
import type { Sort, Header } from "@/components/Table/table-partials/models"
import TableHeadRow from "@/components/Table/table-partials/table-content/table-head/TableHeadRow.vue"
import TableBodyRow from "@/components/Table/table-partials/table-content/table-body/TableBodyRow.vue"

const props = withDefaults(
  defineProps<{
    table: any
    header: Array<Header>
    data: Array<any>
    selectedItems: Array<any>
    fixedNumber: number
    hasCheckbox?: boolean //是否有选择框
    checkboxField?: string //选择框字段
    checkMultiple?: boolean //是否多选
    multiplePageCheck?: boolean //跨页多选
    sortField?: string //排序字段
    sortOrder?: "asc" | "desc"
    tableBoxClass?: string
    tableClass?: string
    headerClass?: string
    bodyClass?: string
    thTrClass?: string
    tdTrClass?: string
    rowSpanSuffix?: string //rowsapn 的字段后缀 后台应该组成 `${字段}${后缀}`
  }>(),
  {
    hasCheckbox: true,
    checkMultiple: false,
    multiplePageCheck: false,
    checkboxField: "",
    sortOrder: "asc",
    tableBoxClass: "bg-white",
    rowSpanSuffix: "_rowSpan",
  }
)
const emits = defineEmits<{
  (e: "on-sort", v: Sort): void
  (e: "on-select-all", v: any): void
  (e: "update:selectedItems", v: Array<any>): void
  (e: "on-sort", v: Sort): void
  (e: "on-change", isChecked: boolean, v: any, row: any): void
  (e: "on-items-all-change", isChecked: boolean, rows: Array<any>): void
}>()
const fixedNum = ref(props.hasCheckbox ? props.fixedNumber + 1 : props.fixedNumber)
const tableBox = ref()
const selectedItems = ref(props.selectedItems)

const allSelectedItems = ref<Array<unknown>>([])
const check = ref<boolean>(false)

const onSelectAll = (checked: any) => {
  check.value = checked
  if (checked) {
    selectedItems.value = [...new Set([...selectedItems.value, ...allSelectedItems.value])]
  } else {
    selectedItems.value = []
  }
  emits("on-select-all", check.value)
}
const onSelectItemsChange = (isChecked: boolean, v: any, row: any) => {
  emits("update:selectedItems", v)
  selectedItems.value = []
  v.forEach((item: any) => {
    if (!selectedItems.value.includes(item)) selectedItems.value.push(item)
  })
  check.value =
    Array.from(new Set([...selectedItems.value, ...allSelectedItems.value])).length ==
    Array.from(new Set([...selectedItems.value])).length
  emits("on-change", isChecked, v, row)
}
const onSort = (v: Sort) => {
  emits("on-sort", v)
}
function onScroll() {
  tableBox.value.className = tableBox.value.className.replace("no-shadow", "")
  if (props.table.parentElement) {
    const left = props.table.parentElement.scrollLeft
    if (left == 0) {
      tableBox.value.className += " no-shadow"
    }
  }
}
watch(
  () => props.data,
  () => {
    selectedItems.value = props.multiplePageCheck ? selectedItems.value : []
    allSelectedItems.value = []
    check.value = false
    props.data.forEach((item: any) => {
      if (item[props.checkboxField]) {
        allSelectedItems.value.push(item[props.checkboxField])
      }
    })
    //console.log("allSelectedItems:", allSelectedItems.value)
  }
)

watch(
  () => props.table,
  (val: HTMLElement) => {
    const tr = val.firstElementChild?.firstElementChild
    if (tr && tr.children) {
      let width = 0
      for (let i = 0; i < fixedNum.value; i++) {
        width += tr.children[i]?.clientWidth ?? 0
      }
      tableBox.value.style.width = width + "px"
      tableBox.value.firstElementChild.style.width = val.clientWidth + "px"
    }
    if (props.table.parentElement) {
      props.table.parentElement.addEventListener("scroll", onScroll, true)
    }
  }
)
onBeforeUnmount(() => {
  if (props.table?.parentElement) {
    props.table.parentElement.removeEventListener("scroll", onScroll, true)
  }
})
</script>
<template>
  <div class="fixed-columns no-shadow" ref="tableBox">
    <table class="table align-middle fs-6 gy-5 no-footer" :class="tableClass">
      <TableHeadRow
        @on-sort="onSort"
        @on-select-all="onSelectAll"
        :checkbox-all-value="check"
        :has-checkbox="hasCheckbox"
        :check-multiple="checkMultiple"
        :sort-field="sortField"
        :sort-order="sortOrder"
        :header="header"
        :header-class="headerClass"
        :th-tr-class="thTrClass"
      >
        <template v-for="(_, name) in $slots" #[name]="{ row: item }">
          <slot v-if="name.toString().endsWith('_header')" :name="name" :row="item" />
        </template>
      </TableHeadRow>
      <TableBodyRow
        v-if="data.length !== 0"
        @on-change="onSelectItemsChange"
        v-model:currently-selected-items="selectedItems"
        :check-multiple="checkMultiple"
        :data="data"
        :header="header"
        :has-checkbox="hasCheckbox"
        :checkbox-field="checkboxField"
        :body-class="bodyClass"
        :td-tr-class="tdTrClass"
        :row-span-suffix="rowSpanSuffix"
      >
        <template v-for="(_, name) in $slots" v-slot:[name]="{ row: item }">
          <slot v-if="!name.toString().endsWith('_header')" :name="name" :row="item" />
        </template>
      </TableBodyRow>
    </table>
  </div>
</template>
