<script lang="ts" generics="T extends import('$lib/types/dataTable').BaseRecord">


	// --- Props ---
	import type { PageResult, TableColumn } from '$lib/types/dataTable.ts';
	import { createEventDispatcher } from 'svelte';

	export let data: PageResult<T>;

	// 这里的 columns 被严格约束，传入错误的 key 会报错
	export let columns: TableColumn<T>[];

	export let loading: boolean = false;

	// --- State ---
	let selectedIds: Set<number | string> = new Set();

	// 响应式计算
	$: allSelected = data.records.length > 0 && data.records.every(item => selectedIds.has(item.id));
	$: indeterminate = data.records.some(item => selectedIds.has(item.id)) && !allSelected;

	// 定义事件，为了严格起见，我们明确 Payload 类型
	const dispatch = createEventDispatcher<{
		pageChange: number;
		delete: T;
		edit: T;
		batchDelete: (number | string)[];
	}>();

	// --- Logic ---
	function toggleAll() {
		if (allSelected) {
			data.records.forEach(item => selectedIds.delete(item.id));
		} else {
			data.records.forEach(item => selectedIds.add(item.id));
		}
		selectedIds = selectedIds;
	}

	function toggleOne(id: number | string) {
		if (selectedIds.has(id)) {
			selectedIds.delete(id);
		} else {
			selectedIds.add(id);
		}
		selectedIds = selectedIds;
	}

	function handleBatchDelete() {
		dispatch('batchDelete', Array.from(selectedIds));
		selectedIds = new Set();
	}
</script>

<div class="bg-base-100 rounded-box shadow-md w-full border border-base-200">
	<div class="p-4 border-b border-base-200 flex justify-between items-center bg-base-100 rounded-t-box">
		<div class="flex gap-2 items-center">
			{#if selectedIds.size > 0}
				<div class="badge badge-neutral">已选 {selectedIds.size} 项</div>
				<button class="btn btn-error btn-sm text-white" on:click={handleBatchDelete}>
					批量删除
				</button>
			{:else}
				<slot name="toolbar"></slot>
			{/if}
		</div>
		<div><slot name="toolbar-right"></slot></div>
	</div>

	<div class="overflow-x-auto">
		<table class="table w-full">
			<thead class="bg-base-200/50">
			<tr>
				<th class="w-12">
					<label>
						<input type="checkbox" class="checkbox checkbox-sm"
									 checked={allSelected}
									 indeterminate={indeterminate}
									 on:change={toggleAll} />
					</label>
				</th>
				{#each columns as col(col.key)}
					<th class="{col.align === 'right' ? 'text-right' : col.align === 'center' ? 'text-center' : 'text-left'} font-semibold">
						{col.label}
					</th>
				{/each}
				<th class="text-right">操作</th>
			</tr>
			</thead>

			<tbody>
			{#if loading}
				{#each Array(5) as _}
					<tr><td colspan={columns.length + 2} class="skeleton h-12 w-full rounded-none opacity-50"></td></tr>
				{/each}
			{:else if data.records.length === 0}
				<tr>
					<td colspan={columns.length + 2} class="text-center py-10 text-base-content/50">
						暂无数据
					</td>
				</tr>
			{:else}
				{#each data.records as row (row.id)}
					<tr class="hover group {selectedIds.has(row.id) ? 'bg-base-200/30' : ''}">
						<td>
							<label>
								<input type="checkbox" class="checkbox checkbox-sm"
											 checked={selectedIds.has(row.id)}
											 on:change={() => toggleOne(row.id)} />
							</label>
						</td>

						{#each columns as col}
							<td class="{col.align === 'right' ? 'text-right' : col.align === 'center' ? 'text-center' : 'text-left'}">
								<slot name="cell" row={row} key={col.key} value={row[col.key]}>
									{String(row[col.key] ?? '-')}
								</slot>
							</td>
						{/each}

						<td class="text-right">
							<div class="join opacity-0 group-hover:opacity-100 transition-opacity">
								<button class="btn btn-xs btn-ghost" on:click={() => dispatch('edit', row)}>编辑</button>
								<button class="btn btn-xs btn-ghost text-error" on:click={() => dispatch('delete', row)}>删除</button>
							</div>
						</td>
					</tr>
				{/each}
			{/if}
			</tbody>
		</table>
	</div>

	{#if data.total > 0}
		<div class="p-4 flex justify-between items-center border-t border-base-200">
			<span class="text-sm opacity-60">第 {data.current} / {data.pages} 页</span>
			<div class="join">
				<button class="join-item btn btn-sm" disabled={data.current === 1}
								on:click={() => dispatch('pageChange', data.current - 1)}>«</button>
				<button class="join-item btn btn-sm pointer-events-none bg-base-100">
					{data.current}
				</button>
				<button class="join-item btn btn-sm" disabled={data.current === data.pages}
								on:click={() => dispatch('pageChange', data.current + 1)}>»</button>
			</div>
		</div>
	{/if}
</div>