<template>
	<div class="sc-table" ref="tableWrapper">
		<!-- 表格内容 -->
		<div class="sc-table-content" ref="tableContent">
			<a-table
				v-if="dataSource.length > 0"
				:columns="tableColumns"
				:data-source="dataSource"
				:loading="loading"
				:pagination="false"
				:row-key="rowKey"
				:row-selection="rowSelection"
				:scroll="scroll"
				:bordered="tableSettings.bordered"
				:size="tableSettings.size"
				:show-header="showHeader"
				:locale="locale"
				:expanded-row-keys="expandedRowKeys"
				:expand-row-by-click="expandRowByClick"
				@change="handleTableChange"
				@resizeColumn="handleResizeColumn"
			>
				<!-- 自定义单元格内容 -->
				<template #bodyCell="{ text, record, index, column }">
					<!-- 序号列 -->
					<template v-if="column.dataIndex === '_index'">
						{{ getTableIndex(index) }}
					</template>
					<!-- 自定义插槽 -->
					<template v-else-if="column.slot">
						<slot :name="column.slot || column.dataIndex" :text="text" :record="record" :index="index" :column="column"></slot>
					</template>
				</template>

				<!-- 空状态 -->
				<template #emptyText>
					<a-empty :image="Empty.PRESENTED_IMAGE_SIMPLE" :description="emptyText" />
				</template>
			</a-table>
		</div>

		<!-- 工具栏 -->
		<div v-if="showToolbar" class="sc-table-tool">
			<div class="tool-left">
				<a-pagination v-bind="pagination" @change="handlePaginationChange" @showSizeChange="handlePaginationChange" />
			</div>
			<div class="tool-right">
				<!-- 右侧工具栏插槽 -->
				<slot name="toolRight"></slot>
				<!-- 刷新按钮 -->
				<a-tooltip v-if="showRefresh" title="刷新">
					<a-button shape="circle" :loading="loading" @click="handleRefresh">
						<template #icon>
							<SyncOutlined />
						</template>
					</a-button>
				</a-tooltip>

				<!-- 表格设置按钮 -->
				<a-tooltip v-if="showColumnSetting" title="表格设置">
					<a-popover v-model:open="tableSettingVisible" placement="topRight" trigger="click" :width="240">
						<template #content>
							<div class="table-setting">
								<div class="table-setting-header">
									<span>表格设置</span>
								</div>
								<div class="table-setting-body">
									<!-- 边框设置 -->
									<div class="setting-item">
										<span class="setting-label">显示边框</span>
										<a-switch v-model:checked="tableSettings.bordered" size="small" />
									</div>
									<!-- 表格大小 -->
									<div class="setting-item">
										<span class="setting-label">表格大小</span>
										<a-radio-group v-model:value="tableSettings.size" size="small" button-style="solid">
											<a-radio-button value="small">小</a-radio-button>
											<a-radio-button value="middle">中</a-radio-button>
											<a-radio-button value="large">大</a-radio-button>
										</a-radio-group>
									</div>
								</div>
							</div>
						</template>
						<a-button shape="circle">
							<template #icon>
								<TableOutlined />
							</template>
						</a-button>
					</a-popover>
				</a-tooltip>

				<!-- 列设置按钮 -->
				<a-tooltip v-if="showColumnSetting" title="列设置">
					<a-popover v-model:open="columnSettingVisible" placement="topRight" trigger="click">
						<template #content>
							<div class="column-setting">
								<div class="column-setting-header">
									<span>显示与排序</span>
								</div>
								<div class="column-setting-list">
									<div
										v-for="(colKey, index) in sortedColumns"
										:key="colKey"
										class="column-setting-item"
										:class="{
											dragging: draggingIndex === index,
										}"
										draggable="true"
										@dragstart="handleDragStart(index, $event)"
										@dragover="handleDragOver(index, $event)"
										@dragend="handleDragEnd"
										@drop="handleDrop(index)"
									>
										<HolderOutlined class="drag-handle" />
										<a-checkbox :checked="visibleColumns.includes(colKey)" @change="(e) => toggleColumn(colKey, e.target.checked)">
											{{ getColumnTitle(colKey) }}
										</a-checkbox>
									</div>
								</div>
							</div>
						</template>
						<a-button shape="circle">
							<template #icon>
								<HolderOutlined />
							</template>
						</a-button>
					</a-popover>
				</a-tooltip>
			</div>
		</div>
	</div>
</template>

<script setup>
import { ref, computed, watch, reactive, useTemplateRef, onMounted, onBeforeUnmount } from 'vue'
import { Empty } from 'ant-design-vue'

defineOptions({
	name: 'scTable',
})

const props = defineProps({
	// 数据源
	dataSource: {
		type: Array,
		default: () => [],
	},
	// 列配置
	columns: {
		type: Array,
		default: () => [],
		required: true,
	},
	// 行的唯一标识
	rowKey: {
		type: [String, Function],
		default: 'id',
	},
	// 加载状态
	loading: {
		type: Boolean,
		default: false,
	},
	// 分页配置
	pagination: {
		type: [Object, Boolean],
		default: () => ({
			current: 1,
			pageSize: 20,
			total: 0,
			showSizeChanger: true,
			showTotal: (total) => `共 ${total} 条`,
			pageSizeOptions: ['20', '50', '100', '200'],
		}),
	},
	// 行选择配置
	rowSelection: {
		type: Object,
		default: null,
	},
	// 表格大小
	size: {
		type: String,
		default: 'middle', // large, middle, small
	},
	// 是否显示边框
	bordered: {
		type: Boolean,
		default: false,
	},
	// 是否显示表头
	showHeader: {
		type: Boolean,
		default: true,
	},
	// 本地化配置
	locale: {
		type: Object,
		default: () => ({}),
	},
	// 是否显示序号列
	showIndex: {
		type: Boolean,
		default: false,
	},
	// 序号列宽度
	indexColumnWidth: {
		type: Number,
		default: 100,
	},
	// 序号列标题
	indexTitle: {
		type: String,
		default: '序号',
	},
	// 是否显示工具栏
	showToolbar: {
		type: Boolean,
		default: true,
	},
	// 是否显示刷新按钮
	showRefresh: {
		type: Boolean,
		default: true,
	},
	// 是否显示列设置
	showColumnSetting: {
		type: Boolean,
		default: true,
	},
	// 空状态文字
	emptyText: {
		type: String,
		default: '暂无数据',
	},
	// 树形表格配置
	defaultExpandAll: {
		type: Boolean,
		default: false,
	},
	expandRowByClick: {
		type: Boolean,
		default: false,
	},
})

// 展开的行keys
const expandedRowKeys = ref([])

const tableContent = useTemplateRef('tableContent')
const tableWrapper = useTemplateRef('tableWrapper')
let scroll = ref({
	scrollToFirstRowOnChange: true,
	x: 'max-content',
	y: true,
})

// 递归获取所有节点的key
const getAllNodeKeys = (nodes) => {
	const keys = []
	const traverse = (list) => {
		list.forEach((node) => {
			// 如果节点有children且不为空，则该节点需要展开
			if (node.children && node.children.length > 0) {
				const key = typeof props.rowKey === 'function' ? props.rowKey(node) : node[props.rowKey]
				keys.push(key)
				traverse(node.children)
			}
		})
	}
	traverse(nodes)
	return keys
}

// 监听数据变化，自动展开所有节点
watch(
	() => props.dataSource,
	(newData) => {
		if (props.defaultExpandAll && newData && newData.length > 0) {
			expandedRowKeys.value = getAllNodeKeys(newData)
		} else {
			expandedRowKeys.value = []
		}
	},
	{ immediate: true, deep: true },
)

onMounted(() => {
	updateTableHeight()
})

const updateTableHeight = () => {
	if (tableContent.value) {
		const tableHeight = tableContent.value.clientHeight - 56
		scroll.value.y = tableHeight > 0 ? tableHeight : 400
	}
}

// 根据表格宽度优化横向滚动配置
watch(
	[() => props.columns, () => props.showIndex, tableContent],
	() => {
		// 如果列有固定宽度且总宽度较大，使用max-content
		// 否则使用true让表格自适应
		const hasFixedColumns = props.columns.some((col) => col.width)
		if (hasFixedColumns || props.showIndex) {
			scroll.value.x = 'max-content'
		} else {
			scroll.value.x = true
		}
	},
	{ immediate: true, deep: true },
)

// 表格设置状态
const tableSettings = reactive({
	bordered: props.bordered,
	size: props.size,
})

// 监听props变化
watch(
	() => props.bordered,
	(val) => {
		tableSettings.bordered = val
	},
)

watch(
	() => props.size,
	(val) => {
		tableSettings.size = val
	},
)

const emit = defineEmits(['refresh', 'change', 'resizeColumn', 'select', 'selectAll', 'selectNone', 'paginationChange'])

// 列设置相关
const columnSettingVisible = ref(false)
const tableSettingVisible = ref(false)
const visibleColumns = ref([])
const sortedColumns = ref([]) // 排序后的列key数组
const draggingIndex = ref(-1) // 当前拖拽的索引

// 所有列
const allColumns = computed(() => {
	return props.columns.filter((col) => col.dataIndex && col.dataIndex !== '_index')
})

// 获取列标题
const getColumnTitle = (colKey) => {
	const col = allColumns.value.find((c) => (c.dataIndex || c.key) === colKey)
	return col ? col.title : colKey
}

// 初始化可见列和排序
watch(
	() => props.columns,
	(newColumns) => {
		const columnKeys = newColumns.filter((col) => col.dataIndex && col.dataIndex !== '_index').map((col) => col.dataIndex || col.key)

		// 如果是首次初始化，使用原始顺序
		if (sortedColumns.value.length === 0) {
			sortedColumns.value = [...columnKeys]
		} else {
			// 保留已存在的顺序，添加新列
			const existingKeys = sortedColumns.value.filter((key) => columnKeys.includes(key))
			const newKeys = columnKeys.filter((key) => !existingKeys.includes(key))
			sortedColumns.value = [...existingKeys, ...newKeys]
		}

		visibleColumns.value = [...sortedColumns.value]
	},
	{ immediate: true, deep: true },
)

// 切换列的显示状态
const toggleColumn = (colKey, checked) => {
	if (checked) {
		if (!visibleColumns.value.includes(colKey)) {
			visibleColumns.value.push(colKey)
		}
	} else {
		visibleColumns.value = visibleColumns.value.filter((key) => key !== colKey)
	}
}

// 拖拽开始
const handleDragStart = (index, event) => {
	draggingIndex.value = index
	event.dataTransfer.effectAllowed = 'move'
	event.dataTransfer.setData('text/plain', index.toString())
}

// 拖拽经过
const handleDragOver = (index, event) => {
	event.preventDefault()
	event.dataTransfer.dropEffect = 'move'
}

// 拖拽结束
const handleDragEnd = () => {
	draggingIndex.value = -1
}

// 拖拽放置
const handleDrop = (dropIndex) => {
	if (draggingIndex.value === dropIndex) return

	const draggedKey = sortedColumns.value[draggingIndex.value]
	const newColumns = [...sortedColumns.value]

	// 移除被拖拽的项
	newColumns.splice(draggingIndex.value, 1)

	// 插入到新位置
	newColumns.splice(dropIndex, 0, draggedKey)

	sortedColumns.value = newColumns
	draggingIndex.value = -1
}

// 处理刷新
const handleRefresh = () => {
	emit('refresh')
}

// 处理分页变化
const handlePaginationChange = (page, pageSize) => {
	emit('paginationChange', { page, pageSize })
}

// 处理表格变化（排序、筛选）
const handleTableChange = (filters, sorter, extra) => {
	emit('change', { filters, sorter, extra })
}

// 处理列宽调整
const handleResizeColumn = (width, column) => {
	emit('resizeColumn', { width, column })
}

// 获取表格序号
const getTableIndex = (index) => {
	const { current = 1, pageSize = 10 } = props.pagination || {}
	return (current - 1) * pageSize + index + 1
}

// 表格列配置
const tableColumns = computed(() => {
	let columns = []

	// 添加序号列
	if (props.showIndex) {
		columns.push({
			title: props.indexTitle,
			dataIndex: '_index',
			key: '_index',
			width: props.indexColumnWidth,
			align: 'center',
			fixed: 'left',
		})
	}

	// 添加数据列（按排序顺序）
	sortedColumns.value.forEach((colKey) => {
		// 过滤掉未显示的列
		if (!visibleColumns.value.includes(colKey)) {
			return
		}

		const col = props.columns.find((c) => (c.dataIndex || c.key) === colKey)
		if (col) {
			columns.push({
				...col,
				customRender: col.slot ? undefined : col.customRender,
			})
		}
	})

	return columns
})

// 暴露方法给父组件
defineExpose({
	refresh: handleRefresh,
	getTableIndex,
})
</script>

<style scoped lang="scss">
.sc-table {
	width: 100%;
	height: 100%;
	display: flex;
	flex-direction: column;
	background: #fff;

	&-tool {
		height: 56px;
		display: flex;
		flex-direction: row;
		justify-content: space-between;
		align-items: center;
		padding: 0 10px;

		.tool-left,
		.tool-right {
			display: flex;
			flex-direction: row;
			gap: 8px;
			align-items: center;
		}
	}

	&-content {
		flex: 1;
		overflow: hidden;
		display: flex;
		flex-direction: column;
	}
}

.column-setting {
	min-width: 200px;

	&-header {
		padding: 8px 0;
		font-weight: 500;
		color: #000;
		border-bottom: 1px solid #f0f0f0;
		margin-bottom: 8px;
	}

	&-list {
		max-height: 400px;
		overflow-y: auto;
	}

	&-item {
		display: flex;
		align-items: center;
		padding: 6px 4px;
		cursor: move;
		transition: all 0.2s;
		border-radius: 4px;

		&:hover {
			background: #f5f5f5;
		}

		&.dragging {
			opacity: 0.5;
			background: #e6f7ff;
		}

		.drag-handle {
			margin-right: 8px;
			color: #999;
			cursor: grab;
			flex-shrink: 0;

			&:active {
				cursor: grabbing;
			}
		}

		:deep(.ant-checkbox-wrapper) {
			flex: 1;
			margin: 0;
		}
	}
}

.table-setting {
	min-width: 200px;

	&-header {
		padding: 8px 0;
		font-weight: 500;
		color: #000;
		border-bottom: 1px solid #f0f0f0;
		margin-bottom: 12px;
	}

	&-body {
		.setting-item {
			display: flex;
			align-items: center;
			justify-content: space-between;
			padding: 8px 0;

			&:not(:last-child) {
				border-bottom: 1px dashed #f0f0f0;
			}

			.setting-label {
				color: #666;
				font-size: 14px;
			}
		}
	}
}
</style>
