<script setup lang="ts">
import symbolKeys from "@@@/table/symbol"
import VbTr from "@@@/table/partials/header/HeaderTr.vue"
import type { Sort, Header, HeaderEx } from "@@@/table/models"

const propOpts = inject(symbolKeys.header, {
	columns: ref([]),
	hasCheckbox: true,
	isMultipleCheck: true,
	sortField: "",
	sortOrder: "asc",
	headerClass: "fixed",
	thTrClass: "text-center text-gray-800 fw-bold fs-7"
})
const { columns } = propOpts

const sort = ref<Sort>({
	label: propOpts.sortField,
	order: propOpts.sortOrder as "asc" | "desc"
})

const columnList = ref<HeaderEx[][]>([])
const headerColumns = ref<HeaderEx[][]>([])
const rowspan = computed(() => {
	return columnList.value.length
})

const convert = (headers: Header[], deep: number): HeaderEx[][] => {
	const allLists: HeaderEx[][] = []

	const recursion = (h: Header[], d: number): HeaderEx[] => {
		if (!allLists[d]) {
			allLists[d] = []
		}
		const currentLevelList = allLists[d]
		const currentChildren: HeaderEx[] = []

		h.forEach((v) => {
			if (
				v.visible === false ||
				(v.children && v.children.every((child) => child.visible === false))
			) {
				return
			}

			const item: HeaderEx = Object.assign({}, v, {
				rowspan: (rs: number) => rs - d,
				colspan: v.children?.length ?? 1,
				children: [] as HeaderEx[]
			})

			// 处理有子级的列：行合并为1，递归处理子级
			if (v.children && v.children.length > 0) {
				delete item.isSort
				item.rowspan = 1 // 有子级的列，自身行合并为1
				const childItems = recursion(v.children, d + 1)
				item.children = childItems
			}

			currentChildren.push(item)
			currentLevelList.push(item)
		})

		const calcColspan = (children?: HeaderEx[]): number => {
			let totalColspan = 0
			if (!children || children.length === 0) return totalColspan
			children.forEach((child) => {
				totalColspan +=
					child.children && child.children.length > 0 ? calcColspan(child.children) : child.colspan
			})
			return totalColspan
		}

		currentLevelList.forEach((item) => {
			if (item.children && item.children.length > 0) {
				item.colspan = calcColspan(item.children) // 子级列数求和作为当前列colspan
			} else {
				item.colspan = 1 // 无子级的列，列合并为1
			}
		})

		return currentChildren
	}

	recursion(headers, deep)
	return allLists
}

watch(
	() => columns.value,
	async () => {
		await nextTick() // 等待DOM更新，确保计算准确
		columnList.value = []
		headerColumns.value = []

		if (columns.value.some((v) => v.children && v.children.length > 0)) {
			const convertedLists = convert(columns.value, 0)
			columnList.value = convertedLists
			headerColumns.value = convertedLists
		} else {
			const flatColumns = columns.value.filter((v) => v.visible !== false) as HeaderEx[]
			flatColumns.forEach((item) => {
				item.rowspan = rowspan.value
				item.colspan = 1
			})
			columnList.value = [flatColumns]
			headerColumns.value = [flatColumns]
		}
	},
	{
		immediate: true, // 初始化执行一次
		deep: true // 深度监听columns（包括children变化）
	}
)
</script>

<template>
	<thead :class="propOpts.headerClass">
		<template v-for="(v, i) in headerColumns" :key="i">
			<vb-tr
				:rowspan="rowspan"
				:columns="v"
				:sort="sort"
				:has-checkbox="i === 0 && propOpts.hasCheckbox"
				:is-multiple-check="propOpts.isMultipleCheck"
				:th-tr-class="propOpts.thTrClass">
				<template v-for="(_, name) in $slots" #[name]="{ row }">
					<slot :name="name" :row="row" />
				</template>
			</vb-tr>
		</template>
	</thead>
</template>
