<template>
	<div class="gantt-box">
		<div class="header">
			<div class="left-content">
				<div class="item" v-for="(item, index) in headerList" :key="index">
					<div class="color-block" :style="{ background: item.color }"></div>
					<div class="label">{{ item.label }}</div>
				</div>
			</div>
			<div class="right-content">备注：更新（进度填报）内容后该甘特图将自动更新</div>
		</div>
		<div class="gantt-chart">
			<div class="table" @scroll="handleScroll">
				<div class="thead">
					<div class="row">
						<div class="td">分部分项工程名称</div>
						<div class="td">开始日期</div>
						<div class="td" style="border-right: 1px solid #0a769a">完成日期</div>
						<div class="td" v-for="date in dateList" :key="date">
							<div class="date">
								<div class="month">
									{{ date }}
								</div>
								<div class="days">
									<div class="day" v-for="day in getDays(date)" :key="day.num">
										{{ day.num }}
									</div>
								</div>
							</div>
						</div>
					</div>
				</div>
				<div class="tbody">
					<div class="row-groups" :class="{ open: openedIndex === i }" v-for="(p, i) in projects" :key="p.name">
						<div class="row">
							<div class="td" @click="handleOpen(i)" style="color: #35e5fd">{{ p.name }}</div>
							<div class="td">{{ p.planStartTime }}</div>
							<div class="td">{{ p.planEndTime }}</div>
							<div class="td" v-for="date in dateList" :key="date + 'grid-date'">
								<div class="grids">
									<div
										class="grid"
										v-for="day in getDays(date)"
										:key="'grid' + day.num"
										:ref="(el: any) => setItemRef(el, p.name + '@|@' + day.date)"
									></div>
								</div>
							</div>
							<div
								class="progress"
								:style="gantt"
								v-for="(gantt, index) in p.gantts"
								:key="index"
								@mouseenter="handleHover"
								@mouseleave="handleLeave"
							></div>
						</div>
						<div class="children">
							<div class="row" v-for="child in p.children" :key="'child-' + child.name">
								<div class="td">{{ child.name }}</div>
								<div class="td">{{ child.planStartTime }}</div>
								<div class="td">{{ child.planEndTime }}</div>
								<div class="td" v-for="date in dateList" :key="date + 'grid-date'">
									<div class="grids">
										<div
											class="grid"
											v-for="day in getDays(date)"
											:key="'grid' + day.num"
											:ref="(el: any) => setItemRef(el, child.name + '@|@' + day.date)"
										></div>
									</div>
								</div>
								<div
									class="progress"
									:style="gantt"
									v-for="(gantt, index) in child.gantts"
									:key="index"
									@mouseenter="handleHover"
									@mouseleave="handleLeave"
								></div>
							</div>
						</div>
					</div>
				</div>
				<div class="tooltips" :style="tooltipsStyle">
					<div class="status">已逾期5天</div>
					<div class="charger">负责人：史蒂夫</div>
				</div>
			</div>
		</div>
	</div>
</template>

<script setup lang="tsx" name="ProjectSupervisionRecord">
import { computed, reactive, ref, onMounted, onBeforeMount } from "vue";
import { bigItemAll } from "@/api/modules/huizhou";
const refChart = ref();
const headerList = reactive([
	{ label: "未开始", color: "#35e5fd" },
	{ label: "进行中", color: "#f1d520" },
	{ label: "已完成", color: "#4fd389" },
	{ label: "已逾期", color: "#fc6f8e" }
]);
const colors = ref(["#35e5fd", "#f1d520", "#4fd389", "#fc6f8e"]);
const projects = ref([]);
// const projects = ref([
// 	{
// 		pName: "抹灰工程1",
// 		startTime: "2023/05/29",
// 		endTime: "2023/07/29",
// 		status: 1,
// 		delay: 0,
// 		gantts: [],
// 		children: [
// 			{
// 				pName: "抹灰工程1-1",
// 				startTime: "2023/05/29",
// 				endTime: "2023/07/29",
// 				status: 1,
// 				delay: 0,
// 				gantts: []
// 			}
// 		]
// 	},
// 	{
// 		pName: "抹灰工程2",
// 		startTime: "2023/06/29",
// 		endTime: "2023/08/29",
// 		status: 1,
// 		delay: 0,
// 		gantts: [],
// 		children: [
// 			{
// 				pName: "抹灰工程2-1",
// 				startTime: "2023/06/29",
// 				endTime: "2023/07/29",
// 				status: 1,
// 				delay: 0,
// 				gantts: []
// 			}
// 		]
// 	},
// 	{
// 		pName: "抹灰工程3",
// 		startTime: "2023/07/29",
// 		endTime: "2023/09/29",
// 		status: 1,
// 		delay: 0,
// 		gantts: [],
// 		children: [
// 			{
// 				pName: "抹灰工程3-1",
// 				startTime: "2023/07/29",
// 				endTime: "2023/10/29",
// 				status: 1,
// 				delay: 0,
// 				gantts: []
// 			}
// 		]
// 	}
// ]);

const itemRefs = [];
const setItemRef = (el: any, va: any) => {
	if (el) {
		const b = va.split("@|@");

		const dataItem = {
			refData: va,
			item: el
		};
		if (itemRefs.length == 0) {
			const itemList = [];
			itemList.push(dataItem);
			const data = {
				name: b[0],
				itemS: itemList
			};
			itemRefs.push(data);
		} else {
			let isCheck = true;
			for (let index = 0; index < itemRefs.length; index++) {
				const element = itemRefs[index];
				if (element.name === b) {
					isCheck = false;
					element.itemS.push(dataItem);
					break;
				}
			}
			if (isCheck) {
				const itemList = [];
				itemList.push(dataItem);
				const data = {
					name: b[0],
					itemS: itemList
				};
				itemRefs.push(data);
			}
		}
	}
};
const scrollLeft = ref(0);
const scrollTimer = ref(0);
const openedIndex = ref(9999);
let tooltipsStyle = reactive({
	display: "none",
	left: 0,
	top: 0
});
const getDataList = async () => {
	const res = await bigItemAll({});
	console.log(res);
	if (res) {
		const arr = dealArr(res.result);
		projects.value = arr;
	}
	setTimeout(function () {
		setGantts();
	}, 300);
};
const dealArr = arr => {
	arr.map(item => {
		item.gantts = [];
		item.delay = 0;
		if (item.children && item.children.length > 0) {
			dealArr(item.children);
		}
	});
	return arr;
};
onBeforeMount(() => {});
onMounted(() => {
	getDataList();
	console.log(getDays("2022-09"), "月日期分布");
});
const getGanttStyle = (project: any) => {
	console.log("进入 getGanttStyle --- ", project);

	let { planStartTime, planEndTime, name } = project;
	const startArr = planStartTime.split("-");
	const endArr = planEndTime.split("-");
	let startRef = null;
	let endRef = null;
	// 抹灰工程1-1-2022/09/03

	const a = !(startArr[2] % 2);
	console.log(a, ":!(startArr[2] % 2:");
	if (a) {
		const day = startArr[2] - 1;
		startArr[2] = day < 10 ? "0" + day : day;
		planStartTime = startArr.join("-");
	}
	const b = !(endArr[2] % 2);
	console.log(a, ":!(endArr[2] % 2):");
	if (!(endArr[2] % 2)) {
		const day = endArr[2] - 1;
		endArr[2] = day < 10 ? "0" + day : day;
		planEndTime = endArr.join("-");
	}

	console.log(dateList, "planEndTime ------------", itemRefs.length);
	for (let index = 0; index < itemRefs.length; index++) {
		const data = itemRefs[index];

		if (data.name === name) {
			for (let index = 0; index < data.itemS.length; index++) {
				const element = data.itemS[index];
				if (element.refData === name + "@|@" + planStartTime) {
					startRef = data.itemS[index].item;
				}

				if (element.refData === name + "@|@" + planEndTime) {
					endRef = data.itemS[index].item;
				}
			}
		}
	}

	const startLeft = startRef.offsetLeft;

	const endWidth = endRef.offsetWidth;

	const endLeft = endRef.offsetLeft;
	const ganttWidth = endLeft - startLeft + endWidth;

	return { left: startLeft + "px", width: ganttWidth + "px" };
};
const setGantts = () => {
	const configGantts = (projects: any) => {
		console.log("进入渲染 setGantts -- ", projects);
		projects.map(project => {
			let { planEndTime, name, gantts } = project;
			const gantt = getGanttStyle(project);
			gantt.background = colors.value[project.state - 1];

			if (gantts) {
				gantts.push(gantt);
			} else {
				project.gantts = [gantt];
			}
			if (project.delay) {
				const delayStartTime = increaseDate(planEndTime, 1);
				const delayEndTime = increaseDate(planEndTime, project.delay);
				const gantt = getGanttStyle({
					planStartTime: delayStartTime,
					planEndTime: delayEndTime,
					name
				});
				gantt.background = colors.value[3];
				gantts.push(gantt);
			}
			project.children && configGantts(project.children);
		});
	};
	configGantts(projects.value);
};
const increaseDate = (date: any, delay: any) => {
	const timestamp = new Date(date).getTime() + (delay + 1) * 1000 * 60 * 60 * 24;
	return new Date(timestamp).toISOString().replace(/-/g, "-").slice(0, 10);
};
const getDays = (date: any) => {
	const year = date.split("-")[0];
	const month = +date.split("-")[1];
	const large = [1, 3, 5, 7, 8, 10, 12];
	const normal = [4, 6, 9, 11];
	const small = [2];
	let count = 0;
	switch (true) {
		case large.includes(month):
			count = 31;
			break;
		case normal.includes(month):
			count = 30;
			break;
		case small.includes(month):
			count = year % 4 ? 28 : 29;
			break;
	}

	return (() => {
		const days = new Array(count)
			.fill(0)
			.map((item, index) => {
				let num = index + 1;
				let fulldate = date + (num < 10 ? "-0" + num : "-" + num);
				return { num, date: fulldate };
			})
			.filter(item => item.num % 2);
		if (count === 28) {
			days.push({ num: 28, date: date + "-28" });
		} else if (count === 30) {
			days.push({ num: 30, date: date + "-30" });
		}
		return days;
	})();
};
const handleOpen = (index: any) => {
	console.log(666);
	console.log(index);
	console.log(openedIndex.value);
	if (index === openedIndex.value) {
		openedIndex.value = 9999;
	} else {
		openedIndex.value = index;
	}
};

const handleScroll = (e: any) => {
	if (scrollTimer.value) {
		clearTimeout(scrollTimer.value);
	}
	scrollTimer.value = setTimeout(() => {
		scrollLeft.value = e.target.scrollLeft;
		scrollTimer.value = null;
	}, 100);
};
const handleHover = (e: any) => {
	const { clientX, clientY } = e;
	const decreaseLeft = clientX - 680;
	const decreaseTop = clientY - 200;
	tooltipsStyle = {
		left: decreaseLeft + scrollLeft.value + "px",
		top: decreaseTop + "px",
		display: "block"
	};
};
const handleLeave = () => {
	tooltipsStyle.display = "none";
};
const dateList = computed(() => {
	let dates = [];
	const mapDates = data => {
		data.map(p => {
			dates.push(p.planStartTime);
			dates.push(p.planEndTime);
			p.children && mapDates(p.children);
		});
	};
	mapDates(projects.value);
	dates = dates.map(date => date.slice(0, 7)).sort();
	dates = [...new Set(dates)];
	console.log("dateList----", dates);
	return dates;
});
</script>

<style scoped lang="scss">
.gantt-box {
	box-sizing: border-box;
	width: 100%;
	height: 100%;
	padding: 18px;
	background: #092945;
	.header {
		display: flex;
		justify-content: space-between;
		width: 100%;
		height: 60px;

		.left-content {
			display: flex;
			width: 40%;
			height: 100%;

			.item {
				display: flex;
				align-items: center;
				width: calc(100% / 4);

				.color-block {
					margin-right: 10px;
					width: 15px;
					height: 15px;
					border-radius: 2px;
				}

				.label {
					color: #ccc;
					font-size: 20px;
				}
			}
		}

		.right-content {
			font-size: 20px;
			line-height: 60px;
			color: #ccc;
		}
	}
	.gantt-chart {
		height: calc(100% - 145px);

		.table {
			position: relative;
			height: 100%;
			overflow-x: auto;

			&::-webkit-scrollbar {
				width: 10px;
				height: 8px;
				cursor: pointer;
			}

			&::-webkit-scrollbar-thumb {
				border-radius: 10px;
				background-color: skyblue;
			}

			.thead {
				border-left: 1px solid #0a769a;

				.row {
					display: flex;

					.td {
						flex-shrink: 0;
						box-sizing: border-box;
						height: 42px;
						line-height: 42px;
						background-color: #092945;
						color: #fff;
						font-size: 20px;
						border-top: 1px solid #0a769a;
						.date {
							line-height: 21px;
							border-left: 1px solid #0a769a;

							.month {
								border-bottom: 1px solid #0a769a;
							}

							.days {
								display: flex;

								.day {
									flex: 1;
								}
							}
						}

						&:nth-child(1) {
							padding-left: 40px;
							width: 200px;
							overflow: hidden;
							white-space: nowrap;
							text-overflow: ellipsis;
						}

						&:not(:nth-child(1)) {
							width: 100px;
							text-align: center;
						}

						&:nth-child(n + 4) {
							width: 400px;
						}
					}
				}
			}

			.tbody {
				border-left: 1px solid #0a769a;

				.row-groups {
					position: relative;
					height: 42px;

					&::before {
						content: "";
						position: absolute;
						left: 26px;
						top: 16px;
						width: 0;
						height: 0;
						border-top: 4px solid transparent;
						border-right: 4px solid transparent;
						border-bottom: 4px solid transparent;
						border-left: 4px solid #5be1f4;
						z-index: 99;
					}

					&.open {
						height: unset;

						&::before {
							border-left-color: transparent;
							border-top-color: #5be1f4;
						}
					}

					> .row .td:first-child {
						user-select: none;
						cursor: pointer;
					}

					.row {
						position: relative;
						display: flex;
						border-top: 1px solid #0a769a;

						.td {
							flex-shrink: 0;
							box-sizing: border-box;
							height: 42px;
							line-height: 42px;
							background-color: #092945;
							border-right: 1px solid #0a769a;
							border-bottom: 1px solid #0a769a;
							color: #fff;
							font-size: 20px;
							border-top: 1px solid #0a769a;

							.grids {
								height: 100%;
								display: flex;

								.grid {
									position: relative;
									flex: 1;
									height: 100%;

									&:not(:last-child) {
										border-right: 1px solid #0a769a;
									}
								}
							}

							&:nth-child(1) {
								padding-left: 40px;
								width: 200px;
							}

							&:not(:nth-child(1)) {
								width: 100px;
								font-size: 18px;
								text-align: center;
							}

							&:nth-child(n + 4) {
								width: 400px;
							}
						}

						.progress {
							flex-shrink: 0;
							position: absolute;
							top: calc(50% - 7px);
							width: 20px;
							height: 14px;
							background: #557dee;
						}
					}

					.children {
						.td {
							height: 38px;
							line-height: 38px;
							font-size: 18px;
						}
					}
				}
			}

			.tooltips {
				position: absolute;
				box-sizing: border-box;
				padding: 10px;
				width: 130px;
				height: 65px;
				font-size: 20px;
				color: #fff;
				border-radius: 8px;
				background-color: #50a6b3;

				.status {
					display: inline-block;
					margin-bottom: 6px;
					padding: 0 10px;
					height: 20px;
					min-width: 60px;
					line-height: 20px;
					font-size: 16px;
					border-radius: 10px;
					background-color: #ff6c7f;
				}
			}
		}
	}
}
</style>
