<template>
	<div class="table-view">
		<div class="table-view__filter">
			<el-select v-model="filters.status" placeholder="状态" clearable style="width: 100px">
				<el-option label="待办" :value="0" />
				<el-option label="进行中" :value="1" />
				<el-option label="已完成" :value="2" />
				<el-option label="已关闭" :value="3" />
			</el-select>
			<el-select v-model="filters.priority" placeholder="优先级" clearable style="width: 100px">
				<el-option label="P0 紧急" :value="0" />
				<el-option label="P1 高" :value="1" />
				<el-option label="P2 中" :value="2" />
				<el-option label="P3 低" :value="3" />
			</el-select>
			<el-input
				v-model="filters.keyWord"
				placeholder="搜索任务"
				clearable
				style="width: 180px"
			/>
			<el-button type="primary" @click="emit('open-task', 0)">新建任务</el-button>
			<el-button type="success" :icon="Download" :loading="exporting" @click="exportGanttExcel">
				导出Excel
			</el-button>
		</div>

		<el-table
			:data="treeData"
			style="width: 100%"
			height="100%"
			row-key="id"
			default-expand-all
			:tree-props="{ children: 'children' }"
		>
			<el-table-column prop="name" label="名称" min-width="260">
				<template #default="{ row }">
					<span :class="{ 'phase-name': row._isPhase }">{{ row.name }}</span>
				</template>
			</el-table-column>
			<el-table-column prop="status" label="状态" width="90" align="center">
				<template #default="{ row }">
					<el-tag
						:type="row._isPhase ? phaseStatusTagType(row.status) : statusTagType(row.status)"
						size="small"
					>
						{{ row._isPhase ? phaseStatusLabel(row.status) : statusLabel(row.status) }}
					</el-tag>
				</template>
			</el-table-column>
			<el-table-column prop="priority" label="优先级" width="90" align="center">
				<template #default="{ row }">
					<template v-if="!row._isPhase && row.priority !== undefined">
						<el-tag :type="priorityTagType(row.priority)" size="small">
							{{ priorityLabel(row.priority) }}
						</el-tag>
					</template>
					<span v-else class="text-placeholder">-</span>
				</template>
			</el-table-column>
			<el-table-column prop="category" label="分类" width="80" align="center">
				<template #default="{ row }">
					{{ row.category || '-' }}
				</template>
			</el-table-column>
			<el-table-column prop="assignee" label="负责人" width="80" align="center">
				<template #default="{ row }">
					{{ row.assignee || '-' }}
				</template>
			</el-table-column>
			<el-table-column label="开始" width="100" align="center">
				<template #default="{ row }">
					{{ row.startDate || '-' }}
				</template>
			</el-table-column>
			<el-table-column label="结束" width="100" align="center">
				<template #default="{ row }">
					{{ row.endDate || '-' }}
				</template>
			</el-table-column>
			<el-table-column prop="progress" label="进度" width="100" align="center">
				<template #default="{ row }">
					<el-progress :percentage="row.progress" :stroke-width="6" />
				</template>
			</el-table-column>
			<el-table-column label="操作" width="120" align="center">
				<template #default="{ row }">
					<template v-if="!row._isPhase">
						<el-button link type="primary" size="small" @click="emit('open-task', row._taskId)">
							编辑
						</el-button>
						<el-button link type="danger" size="small" @click="handleDelete(row)">
							删除
						</el-button>
					</template>
				</template>
			</el-table-column>
		</el-table>
	</div>
</template>

<script lang="ts" setup>
import { ref, reactive, computed } from 'vue';
import { Download } from '@element-plus/icons-vue';
import { useProjectStore } from '../../store/project';
import { ElMessage, ElMessageBox } from 'element-plus';

const emit = defineEmits<{
	(e: 'open-task', taskId: number): void;
}>();

const store = useProjectStore();
const filters = reactive({
	status: undefined as number | undefined,
	priority: undefined as number | undefined,
	keyWord: '',
});

type TagType = 'primary' | 'success' | 'info' | 'warning' | 'danger';
type ExcelStyle = any;

// 阶段状态映射
const phaseStatusMap: Record<number, string> = { 0: '未开始', 1: '进行中', 2: '已完成' };
const phaseStatusTagMap: Record<number, TagType> = { 0: 'info', 1: 'primary', 2: 'success' };
// 任务状态映射
const statusMap: Record<number, string> = { 0: '待办', 1: '进行中', 2: '已完成', 3: '已关闭' };
const statusTagMap: Record<number, TagType> = { 0: 'info', 1: 'primary', 2: 'success', 3: 'warning' };
const priorityMap: Record<number, string> = { 0: 'P0 紧急', 1: 'P1 高', 2: 'P2 中', 3: 'P3 低' };
const priorityTagMap: Record<number, TagType> = { 0: 'danger', 1: 'warning', 2: 'primary', 3: 'info' };

function phaseStatusLabel(s: number) { return phaseStatusMap[s] || '未知'; }
function phaseStatusTagType(s: number) { return phaseStatusTagMap[s] || 'info'; }
function statusLabel(s: number) { return statusMap[s] || '未知'; }
function statusTagType(s: number) { return statusTagMap[s] || 'info'; }
function priorityLabel(p: number) { return priorityMap[p] || ''; }
function priorityTagType(p: number) { return priorityTagMap[p] || 'info'; }

/**
 * 从 ganttData 构建树形表格数据
 * 层级: 阶段(phase) → 任务(task) → 子任务(subtask)
 */
const treeData = computed(() => {
	const { data } = store.ganttData;
	if (!data || data.length === 0) return [];

	// 分离阶段和任务
	const phases = data.filter((d: any) => String(d.id).startsWith('p_'));
	const tasks = data.filter((d: any) => String(d.id).startsWith('t_'));

	// 筛选任务
	const filtered = tasks.filter((t: any) => {
		if (filters.status !== undefined && t.status !== filters.status) return false;
		if (filters.priority !== undefined && t.priority !== filters.priority) return false;
		if (filters.keyWord && !t.text.includes(filters.keyWord)) return false;
		return true;
	});

	// 构建任务 map（用 gantt id 做 key）
	const taskMap = new Map<string, any>();
	for (const t of filtered) {
		taskMap.set(t.id, {
			id: t.id,
			_taskId: parseInt(String(t.id).replace('t_', '')),
			_isPhase: false,
			name: t.text,
			status: t.status,
			priority: t.priority,
			category: t.category,
			assignee: t.assignee,
			startDate: t.start_date,
			endDate: t.end_date,
			progress: Math.round((t.progress || 0) * 100),
			sortOrder: t.sortOrder,
			children: [] as any[],
		});
	}

	// 组装子任务到父任务
	const rootTasks: any[] = []; // 没有 parent 的任务
	const phaseChildren = new Map<string, any[]>(); // phaseId → tasks

	for (const t of filtered) {
		const node = taskMap.get(t.id);
		if (!node) continue;

		if (t.parent && t.parent.startsWith('t_') && taskMap.has(t.parent)) {
			// 子任务挂到父任务
			taskMap.get(t.parent).children.push(node);
		} else if (t.parent && t.parent.startsWith('p_')) {
			// 任务挂到阶段
			const arr = phaseChildren.get(t.parent) || [];
			arr.push(node);
			phaseChildren.set(t.parent, arr);
		} else {
			rootTasks.push(node);
		}
	}

	// 构建阶段节点
	const tree: any[] = [];
	for (const p of phases) {
		const children = phaseChildren.get(p.id) || [];
		// 如果有筛选条件且该阶段下没有匹配的任务，跳过
		const hasFilter = filters.status !== undefined || filters.priority !== undefined || filters.keyWord;
		if (hasFilter && children.length === 0) continue;

		tree.push({
			id: p.id,
			_isPhase: true,
			name: p.text,
			status: p.status,
			startDate: p.start_date || p.end_date,
			endDate: p.end_date || p.start_date,
			progress: Math.round((p.progress || 0) * 100),
			sortOrder: p.sortOrder,
			children,
		});
	}

	// 无阶段的根任务追加到末尾
	tree.push(...rootTasks);

	return tree;
});

const exporting = ref(false);

/**
 * 导出甘特图样式 Excel
 * 左侧: 层级名称 | 状态 | 负责人 | 开始 | 结束
 * 右侧: 日期列，用彩色填充表示工期条
 */
async function exportGanttExcel() {
	const rows = treeData.value;
	if (!rows || rows.length === 0) {
		ElMessage.warning('暂无数据可导出');
		return;
	}

	exporting.value = true;
	try {
		const ExcelJS = await import('exceljs');
		const { saveAs } = await import('file-saver');

		// 展平树形数据，记录层级
		const flatRows: { row: any; level: number }[] = [];
		function flatten(items: any[], level: number) {
			for (const item of items) {
				flatRows.push({ row: item, level });
				if (item.children?.length) flatten(item.children, level + 1);
			}
		}
		flatten(rows, 0);

		// 计算日期范围
		let minDate = '', maxDate = '';
		for (const { row } of flatRows) {
			if (row.startDate && (!minDate || row.startDate < minDate)) minDate = row.startDate;
			if (row.endDate && (!maxDate || row.endDate > maxDate)) maxDate = row.endDate;
		}
		if (!minDate || !maxDate) {
			const today = new Date().toISOString().slice(0, 10);
			minDate = minDate || today;
			maxDate = maxDate || today;
		}
		// 前后各留 3 天
		const rangeStart = new Date(minDate);
		rangeStart.setDate(rangeStart.getDate() - 3);
		const rangeEnd = new Date(maxDate);
		rangeEnd.setDate(rangeEnd.getDate() + 3);

		// 生成日期列表
		const dates: string[] = [];
		const d = new Date(rangeStart);
		while (d <= rangeEnd) {
			dates.push(d.toISOString().slice(0, 10));
			d.setDate(d.getDate() + 1);
		}

		const wb = new ExcelJS.Workbook();
		const ws = wb.addWorksheet('甘特图');

		// 固定列定义
		const fixedCols = ['名称', '状态', '负责人', '开始', '结束'];
		const fixedColCount = fixedCols.length;

		// 表头行1: 固定列 + 月份合并
		const headerRow1Data: string[] = [...fixedCols];
		// 表头行2: 固定列空 + 日期(日)
		const headerRow2Data: string[] = fixedCols.map(() => '');

		// 按月分组日期，用于合并单元格
		const monthGroups: { label: string; start: number; count: number }[] = [];
		let lastMonth = '';
		for (let i = 0; i < dates.length; i++) {
			const dt = new Date(dates[i]);
			const monthLabel = `${dt.getFullYear()}年${dt.getMonth() + 1}月`;
			const dayLabel = `${dt.getDate()}日`;
			headerRow1Data.push(monthLabel);
			headerRow2Data.push(dayLabel);
			if (monthLabel !== lastMonth) {
				monthGroups.push({ label: monthLabel, start: fixedColCount + i + 1, count: 1 });
				lastMonth = monthLabel;
			} else {
				monthGroups[monthGroups.length - 1].count++;
			}
		}

		const row1 = ws.addRow(headerRow1Data);
		const row2 = ws.addRow(headerRow2Data);

		// 合并月份单元格
		for (const mg of monthGroups) {
			if (mg.count > 1) {
				ws.mergeCells(1, mg.start, 1, mg.start + mg.count - 1);
			}
		}
		// 合并固定列表头（行1和行2）
		for (let c = 1; c <= fixedColCount; c++) {
			ws.mergeCells(1, c, 2, c);
		}

		// 表头样式
		const headerFill: ExcelStyle = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF4472C4' } };
		const headerFont: ExcelStyle = { bold: true, color: { argb: 'FFFFFFFF' }, size: 10 };
		const headerAlign: ExcelStyle = { horizontal: 'center', vertical: 'middle' };
		const thinBorder: ExcelStyle = {
			top: { style: 'thin', color: { argb: 'FFD0D0D0' } },
			bottom: { style: 'thin', color: { argb: 'FFD0D0D0' } },
			left: { style: 'thin', color: { argb: 'FFD0D0D0' } },
			right: { style: 'thin', color: { argb: 'FFD0D0D0' } },
		};

		for (const r of [row1, row2]) {
			r.eachCell(cell => {
				cell.fill = headerFill;
				cell.font = headerFont;
				cell.alignment = headerAlign;
				cell.border = thinBorder;
			});
			r.height = 22;
		}

		// 颜色配置
		const phaseBarColor = 'FF2F5496';   // 深蓝 - 阶段
		const taskBarColor = 'FF5B9BD5';    // 蓝色 - 任务
		const subtaskBarColor = 'FF9DC3E6';  // 浅蓝 - 子任务
		const phaseBgColor = 'FFDCE6F1';    // 阶段行背景

		// 写入数据行
		for (const { row: item, level } of flatRows) {
			const indent = level > 0 ? '  '.repeat(level) : '';
			const name = indent + item.name;
			const status = item._isPhase ? phaseStatusLabel(item.status) : statusLabel(item.status);
			const assignee = item.assignee || '';
			const startDate = item.startDate || '';
			const endDate = item.endDate || '';

			const rowData: any[] = [name, status, assignee, startDate, endDate];

			// 日期列填充
			for (const _date of dates) {
				rowData.push('');
			}

			const dataRow = ws.addRow(rowData);
			dataRow.height = 24;

			// 固定列样式
			for (let c = 1; c <= fixedColCount; c++) {
				const cell = dataRow.getCell(c);
				cell.border = thinBorder;
				cell.alignment = { vertical: 'middle', horizontal: c === 1 ? 'left' : 'center' };
				cell.font = { size: 10, bold: item._isPhase };
				if (item._isPhase) {
					cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: phaseBgColor } };
				}
			}

			// 甘特条填充
			if (startDate && endDate) {
				const barColor = item._isPhase ? phaseBarColor : level >= 2 ? subtaskBarColor : taskBarColor;
				for (let i = 0; i < dates.length; i++) {
					const cell = dataRow.getCell(fixedColCount + i + 1);
					cell.border = thinBorder;
					if (dates[i] >= startDate && dates[i] <= endDate) {
						cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: barColor } };
					}
				}
			}
		}

		// 列宽设置
		ws.getColumn(1).width = 30; // 名称
		ws.getColumn(2).width = 10; // 状态
		ws.getColumn(3).width = 10; // 负责人
		ws.getColumn(4).width = 12; // 开始
		ws.getColumn(5).width = 12; // 结束
		for (let i = 0; i < dates.length; i++) {
			ws.getColumn(fixedColCount + i + 1).width = 4.5;
		}

		// 冻结左侧固定列 + 表头
		ws.views = [{ state: 'frozen', xSplit: fixedColCount, ySplit: 2 }];

		const buf = await wb.xlsx.writeBuffer();
		const projectName = store.currentProject?.name || '项目';
		saveAs(new Blob([buf]), `${projectName}_甘特图.xlsx`);
		ElMessage.success('导出成功');
	} catch (e: any) {
		console.error(e);
		ElMessage.error('导出失败: ' + (e.message || e));
	} finally {
		exporting.value = false;
	}
}

async function handleDelete(row: any) {
	await ElMessageBox.confirm(`确定删除任务「${row.name}」？`, '提示', { type: 'warning' });
	await store.deleteTask([row._taskId]);
	ElMessage.success('删除成功');
}
</script>

<style lang="scss" scoped>
.table-view {
	padding: 10px;
	height: 100%;
	display: flex;
	flex-direction: column;
	overflow: hidden;

	&__filter {
		display: flex;
		gap: 10px;
		margin-bottom: 16px;
		flex-shrink: 0;
	}

	:deep(.el-table) {
		flex: 1;
		overflow: hidden;
	}
}

.phase-name {
	font-weight: 600;
	color: var(--el-color-primary);
}

.text-placeholder {
	color: #c0c4cc;
}
</style>
