<template>
	<view class="calendar">
		<view class="header">
			<view class="header-title">
				<view class="head-left">
					<image class="head-img" src="/static/index/calendar/superleft.png" @click="prevYear" />
					<image class="head-img" src="/static/index/calendar/left.png" @click="prevMonth" />
				</view>
				<view class="year-month">{{ year }}年{{ month + 1 }}月</view>
				<view class="head-left">
					<image class="head-img" src="/static/index/calendar/right.png" @click="nextMonth" />
					<image class="head-img" src="/static/index/calendar/superright.png" @click="nextYear" />
				</view>
			</view>

			<view class="weekdays">
				<view v-for="(day, idx) in weekdays" :key="idx" class="weekday">{{ day }}</view>
			</view>
		</view>

		<view class="days">
			<view v-for="cell in cells" :key="cell.key" class="day-cell" :class="{
          'prev-month': cell.prev,
          'next-month': cell.next,
          'selected': isSelected(cell.key),
          'disabled': isDisabled(cell)
        }" @click="selectDate(cell)">
				<view class="gregorian">{{ cell.dateText }}</view>
				<view class="lunar" v-if="cell.lunarText">{{ cell.lunarText }}</view>
			</view>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		computed,
		watch
	} from 'vue';
	import solarlunar from 'solarlunar'; // npm install solarlunar

	// 支持对象和旧类型（String/Date/Number）
	const props = defineProps({
		modelValue: {
			
			default: null
		}
	});
	const emit = defineEmits(['update:modelValue', 'datachange']);

	// 当前视图年月
	const now = new Date();
	const year = ref(now.getFullYear());
	const month = ref(now.getMonth()); // 0-based

	// 选中 key（YYYY-MM-DD 格式字符串）或 null
	const selectedKey = ref(null);

	// 如果外部传入的是对象，我们记录这个事实，以便 emit 回对象
	let incomingWasObject = false;

	// 保存时间部分（针对字符串/Date/Number 输入）
	// 如果输入是对象，则不使用时间部分
	let lastKnownTime = null;

	// 辅助：把年月日转成便于比较的数字 YYYYMMDD（m 为 0-based）
	function toDateNumber(y, m, d) {
		const mm = m + 1;
		return y * 10000 + mm * 100 + d;
	}

	// 获取今天的 YYYYMMDD（按本地时间）
	function getTodayNumber() {
		const d = new Date();
		return toDateNumber(d.getFullYear(), d.getMonth(), d.getDate());
	}

	// 格式化 key（m 0-base => 输出两位）
	function formatKey(y, m, d) {
		const mm = String(m + 1).padStart(2, '0');
		const dd = String(d).padStart(2, '0');
		return `${y}-${mm}-${dd}`;
	}

	const weekdays = ['一', '二', '三', '四', '五', '六', '日'];
	const firstWeekdayOfMonth = (y, m) => {
		const d = new Date(y, m, 1).getDay(); // 0 (Sun) - 6 (Sat)
		return (d + 6) % 7; // Monday=0 .. Sunday=6
	};

	// 生成 cells（和你原来逻辑一致）
	function buildCells(y, m) {
		const list = [];
		const prevDate = new Date(y, m, 0);
		const prevYear = prevDate.getFullYear();
		const prevMonth = prevDate.getMonth();
		const prevTotal = prevDate.getDate();

		const startOffset = firstWeekdayOfMonth(y, m);

		for (let i = 0; i < startOffset; i++) {
			const day = prevTotal - startOffset + i + 1;
			const lunar = solarlunar.solar2lunar(prevYear, prevMonth + 1, day);
			list.push({
				key: `prev-${prevYear}-${prevMonth + 1}-${day}`,
				dateText: day,
				lunarText: lunar ? lunar.dayCn : '',
				prev: true,
				next: false,
				year: prevYear,
				month: prevMonth,
				day,
				dateNumber: toDateNumber(prevYear, prevMonth, day),
			});
		}

		const totalDays = new Date(y, m + 1, 0).getDate();
		for (let d = 1; d <= totalDays; d++) {
			const lunar = solarlunar.solar2lunar(y, m + 1, d);
			list.push({
				key: formatKey(y, m, d),
				dateText: d,
				lunarText: lunar ? lunar.dayCn : '',
				prev: false,
				next: false,
				year: y,
				month: m,
				day: d,
				dateNumber: toDateNumber(y, m, d),
			});
		}

		const need = 42 - list.length;
		for (let i = 1; i <= need; i++) {
			const nd = new Date(y, m + 1, i);
			const ny = nd.getFullYear();
			const nm = nd.getMonth();
			const lunar = solarlunar.solar2lunar(ny, nm + 1, i);
			list.push({
				key: `next-${ny}-${nm + 1}-${i}`,
				dateText: i,
				lunarText: lunar ? lunar.dayCn : '',
				prev: false,
				next: true,
				year: ny,
				month: nm,
				day: i,
				dateNumber: toDateNumber(ny, nm, i),
			});
		}

		return list;
	}

	const cells = computed(() => buildCells(year.value, month.value));

	function isSelected(key) {
		return selectedKey.value === key;
	}

	// 是否禁用（大于今天）
	function isDisabled(cell) {
		// 只按年月日比较（cell.month 已是 0-based）
		return toDateNumber(cell.year, cell.month, cell.day) > getTodayNumber();
	}

	// 解析外部 modelValue，返回 { y, m (1-12), d, time|null, isObject:boolean } 或 null
	function parseIncomingModel(val) {
		if (val == null) return null;

		// 对象形式（优先）
		if (typeof val === 'object' && !(val instanceof Date) && !Array.isArray(val)) {
			const hasYear = val.year != null && Number(val.year) > 0;
			const hasMonth = val.month != null && String(val.month).trim() !== '';
			const hasDay = val.day != null && String(val.day).trim() !== '';

			if (!hasYear || !hasMonth || !hasDay) {
				return null;
			}

			const y = Number(val.year);
			const m = Number(val.month);
			const d = Number(val.day);

			if (isNaN(y) || isNaN(m) || isNaN(d)) return null;

			return {
				y,
				m,
				d,
				time: null,
				isObject: true
			};
		}

		// Date 对象
		if (val instanceof Date) {
			return {
				y: val.getFullYear(),
				m: val.getMonth() + 1,
				d: val.getDate(),
				time: `${String(val.getHours()).padStart(2, '0')}:${String(val.getMinutes()).padStart(2,'0')}:${String(val.getSeconds()).padStart(2,'0')}`,
				isObject: false
			};
		}

		// 数字 -> 视为时间戳
		if (typeof val === 'number') {
			const dObj = new Date(val);
			if (isNaN(dObj.getTime())) return null;
			return {
				y: dObj.getFullYear(),
				m: dObj.getMonth() + 1,
				d: dObj.getDate(),
				time: `${String(dObj.getHours()).padStart(2,'0')}:${String(dObj.getMinutes()).padStart(2,'0')}:${String(dObj.getSeconds()).padStart(2,'0')}`,
				isObject: false
			};
		}

		// 字符串：支持 YYYY-MM-DD、YYYY-MM-DD hh:mm[:ss]
		if (typeof val === 'string') {
			const parts = val.trim().split(/[ T]/);
			const datePart = parts[0];
			const timePart = parts[1] || null;

			const m = datePart.match(/^(\d{4})-(\d{1,2})-(\d{1,2})$/);
			if (m) {
				return {
					y: Number(m[1]),
					m: Number(m[2]),
					d: Number(m[3]),
					time: timePart ? timePart.split('.')[0] : null,
					isObject: false
				};
			}

			// 回退 new Date
			const dt = new Date(val);
			if (!isNaN(dt.getTime())) {
				return {
					y: dt.getFullYear(),
					m: dt.getMonth() + 1,
					d: dt.getDate(),
					time: `${String(dt.getHours()).padStart(2,'0')}:${String(dt.getMinutes()).padStart(2,'0')}:${String(dt.getSeconds()).padStart(2,'0')}`,
					isObject: false
				};
			}

			return null;
		}

		return null;
	}

	// 把 props.modelValue 应用到组件（设置视图年月、选中项）
	// 注意：如果传入日期 > 今天，则不会被设为选中（保持 UI 与“禁用未来日”的逻辑一致）
	function applyModelValue(val) {
		const parsed = parseIncomingModel(val);
		if (!parsed) {
			selectedKey.value = null;
			lastKnownTime = null;
			incomingWasObject = false;
			return;
		}

		incomingWasObject = !!parsed.isObject;

		const parsedDateNumber = toDateNumber(parsed.y, parsed.m - 1, parsed.d);
		if (parsedDateNumber > getTodayNumber()) {
			// 传入是未来日期 -> 不选中（如果你想保留初始选中，请改这里）
			selectedKey.value = null;
			lastKnownTime = null;
			// 仍把视图切到该年月以便用户看到传入的年月（可选：若不想切换可注释下面）
			year.value = parsed.y;
			month.value = parsed.m - 1;
			return;
		}

		// 设置视图到对应月份（parsed.m 是 1-12）
		year.value = parsed.y;
		month.value = parsed.m - 1;
		selectedKey.value = formatKey(parsed.y, parsed.m - 1, parsed.d);

		lastKnownTime = parsed.time || null;
	}

	// 组件初始化时应用一次
	applyModelValue(props.modelValue);

	// 监听外部 modelValue 变化（同步）
	watch(() => props.modelValue, (v) => {
		applyModelValue(v);
	});

	// 选择日期（单选，重复点击取消）
	// 当外部传入对象时，emit 回对象；否则 emit 字符串（与旧行为兼容）
	function selectDate(cell) {
		// 禁用或跨月的格子不可选
		if (cell.prev || cell.next) return;
		if (isDisabled(cell)) return;

		const key = formatKey(cell.year, cell.month, cell.day);

		// 取消选择
		if (selectedKey.value === key) {
			selectedKey.value = null;
			emit('update:modelValue', null);
			emit('datachange', {
				date: null
			});
			return;
		}

		// 选中
		selectedKey.value = key;

		if (incomingWasObject) {
			// 重点：返回的 month 和 day 都是两位字符串（带前导 0）
			const outObj = {
				year: cell.year,
				month: String(cell.month + 1).padStart(2, '0'),
				day: String(cell.day).padStart(2, '0')
			};
			emit('update:modelValue', outObj);
			emit('datachange', {
				date: outObj
			});
		} else {
			let outStr = key;
			if (lastKnownTime) outStr = `${key} ${lastKnownTime}`;
			emit('update:modelValue', outStr);
			emit('datachange', {
				date: outStr
			});
		}
	}

	// 年月切换
	function prevMonth() {
		if (month.value === 0) {
			year.value--;
			month.value = 11;
		} else {
			month.value--;
		}
	}

	function nextMonth() {
		if (month.value === 11) {
			year.value++;
			month.value = 0;
		} else {
			month.value++;
		}
	}

	function prevYear() {
		year.value--;
	}

	function nextYear() {
		year.value++;
	}
</script>

<style scoped lang="less">
	.calendar {
		padding: 16px;
		background: #fff;
		border-radius: 30rpx;
		box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
		margin: 0 auto;
		overflow: hidden;
	}

	.header {
		width: 100%;
		display: flex;
		flex-direction: column;
	}

	.header-title {
		width: 100%;
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin-bottom: 10rpx;
	}

	.year-month {
		font-size: 18px;
		font-weight: bold;
	}

	.weekdays {
		display: flex;
		background-color: #F8F8FA;
		border-radius: 18rpx;
		padding: 8rpx;
		margin-top: 8rpx;
	}

	.weekday {
		flex: 1;
		text-align: center;
		font-size: 12px;
	}

	.days {
		display: flex;
		flex-wrap: wrap;
		padding: 8rpx 0;
	}

	.day-cell {
		width: calc(100% / 7);
		height: 78rpx;
		text-align: center;
		padding-top: 8rpx;
		box-sizing: border-box;
		position: relative;
		cursor: pointer;
	}

	/* 前后月份灰色显示 */
	.day-cell.prev-month .gregorian,
	.day-cell.next-month .gregorian {
		color: #ccc;
	}

	/* 禁用（未来日期）样式 & 行为 */
	.day-cell.disabled {
		pointer-events: none;
		/* 完全不可点击 */
		opacity: 1;
		/* 保持背景，但把文字变灰 */
	}

	.day-cell.disabled .gregorian,
	.day-cell.disabled .lunar {
		color: #ccc !important;
	}

	/* 选中（单选）样式 */
	.day-cell.selected {
		background-color: #0B98DC;
		border-radius: 8rpx;
	}

	.day-cell.selected .gregorian,
	.day-cell.selected .lunar {
		color: #fff;
	}

	.gregorian {
		font-size: 14px;
	}

	.lunar {
		font-size: 10px;
		color: #888;
	}

	.head-left {
		width: 100rpx;
		display: flex;
		justify-content: space-between;

		.head-img {
			width: 40rpx;
			height: 40rpx;
		}
	}
</style>