import { _objectSpread2 } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
import dayjs from "dayjs";
import { isArr, locales } from "@pisell/utils";
//#region src/components/schedules/schedules/utils.ts
/**
* 根据日程配置生成日历数据
* @param values
* @param others
* @param type
*/
const calcCalendarDataBySchedule = (values, others, type) => {
	if (type === "time-slots") return calcCalendarDataByTimeSlots(values, others);
	if (type === "designation") return calcCalendarDataByDesignation(values, others);
	return calcCalendarDataByStandard(values, others);
};
/**
* 获取开始时间和结束时间之间的所有日期
* @param startDate
* @param endDate
*/
const getDaysByStartEnd = (startDate, endDate) => {
	let start = dayjs(startDate);
	const end = dayjs(endDate);
	const daysArray = [];
	while (start.isBefore(end, "day") || start.isSame(end, "day")) {
		daysArray.push(start.format("YYYY-MM-DD"));
		start = start.add(1, "day");
	}
	return daysArray;
};
/**
* 合并日期和时间
* @param date
* @param time
*/
const mergeDateTime = (date, time) => {
	return dayjs(`${dayjs(date).format("YYYY-MM-DD")}${time ? dayjs(time).format(" HH:MM") : ""}`);
};
const getDataRange = ({ start, end, type, time_slot }) => {
	if (type === "time-slots") {
		let dateRange = [];
		getDaysByStartEnd(start, end).forEach((str) => {
			time_slot === null || time_slot === void 0 || time_slot.forEach((time) => {
				dateRange.push({
					start: `${str} ${time.start_time}`,
					end: `${str} ${time.end_time}`
				});
			});
		});
		return dateRange;
	}
	return [{
		start: start.format("YYYY-MM-DD HH:mm:ss"),
		end: end.format("YYYY-MM-DD HH:mm:ss")
	}];
};
/**
* 按天重复配置获取日期
* @param params
*/
const getDaysByRepeatDay = (params, isGetRange) => {
	const { start, end, deadline, frequency, type, time_slot, excludedDays } = params;
	const scheduleDiff = end.diff(start, "second");
	const excludedDaysMap = new Map(excludedDays.map((day) => [day, true]));
	let startTmp = getMaxStart(start);
	const daysArr = [];
	while (startTmp.isBefore(deadline, "day") || startTmp.isSame(deadline, "day")) {
		const e = startTmp.add(scheduleDiff, "second");
		if (isGetRange) {
			if (excludedDaysMap.has(startTmp.format("YYYY-MM-DD"))) {
				startTmp = startTmp.add(frequency, "day");
				continue;
			}
			const arr = getDataRange({
				start: startTmp,
				end: e,
				type,
				time_slot
			});
			daysArr.push(...arr);
		} else daysArr.push(...getDaysByStartEnd(startTmp, e));
		startTmp = startTmp.add(frequency, "day");
	}
	return Array.from(new Set(daysArr));
};
/**
* 按周重复配置获取日期
* @param params
*/
const getDaysByRepeatWeek = (params, isGetRange) => {
	const { start, end, deadline, frequency, frequency_date, type, time_slot, excludedDays } = params;
	const scheduleDiff = end.diff(start, "second");
	const excludedDaysMap = new Map(excludedDays.map((day) => [day, true]));
	let startTmp = getMaxStart(start);
	const daysArr = [];
	while (startTmp.isBefore(deadline, "day") || startTmp.isSame(deadline, "day")) {
		for (let i = 0; i < frequency_date.length; i++) {
			const item = frequency_date[i];
			const _start = startTmp.day(item);
			const _end = _start.add(scheduleDiff, "second");
			if (isGetRange) {
				if (excludedDaysMap.has(_start.format("YYYY-MM-DD"))) {
					startTmp = startTmp.day(1).add(frequency, "day");
					continue;
				}
				const arr = getDataRange({
					start: _start,
					end: _end,
					type,
					time_slot
				});
				daysArr.push(...arr);
			} else daysArr.push(...getDaysByStartEnd(_start, _end));
		}
		startTmp = startTmp.day(1).add(frequency, "week");
	}
	return Array.from(new Set(daysArr));
};
/**
* 日期和排除日期格式化日历所需数据格式
* @param days
* @param color
* @param excludedDays
*/
const formatDayColor = ({ days, color, excludedDays }) => {
	const excludedDaysSet = new Set(excludedDays);
	return days.map((item) => ({
		date: item,
		color: [color],
		isExcluded: excludedDaysSet.has(item)
	}));
};
/**
* 获取开始结束时间数组的所有日期
* @param arr
*/
const getDaysByStartEndArr = (arr = []) => {
	const daysArr = [];
	arr.forEach((item) => {
		if (item && item.start && item.end) daysArr.push(...getDaysByStartEnd(item.start, item.end));
	});
	return Array.from(new Set(daysArr));
};
/**
* 处理日期重复逻辑
* @param repeat_type
* @param start
* @param end
* @param color
* @param endRadio
* @param end_date
* @param excluded_date
* @param included_date
* @param frequency
* @param excludedStatus
* @param includeStatus
* @param frequency_date
*/
const processDateRange = ({ repeat_type, start, end, color, endRadio, end_date, excluded_date, included_date, frequency, excludedStatus, includeStatus, frequency_date, type, time_slot }, isGetRange) => {
	/** 时间范围或天 */
	let days = [];
	const excludedDays = getDaysByStartEndArr(excluded_date);
	const includedDays = getDaysByStartEndArr(included_date);
	if (repeat_type === "0") if (isGetRange) if (type === "time-slots") days = (time_slot === null || time_slot === void 0 ? void 0 : time_slot.map((item) => ({
		start: start.format(`YYYY-MM-DD ${item.start_time}`),
		end: end.format(`YYYY-MM-DD ${item.end_time}`)
	}))) || [];
	else days = [{
		start: start.format("YYYY-MM-DD HH:mm:ss"),
		end: end.format("YYYY-MM-DD HH:mm:ss")
	}];
	else days = getDaysByStartEnd(start, end);
	else {
		let endDate = dayjs(end_date);
		if (endRadio === 1) endDate = isGetRange ? dayjs().add(12, "month") : dayjs().add(18, "month");
		if (repeat_type === "1") days = getDaysByRepeatDay({
			start,
			end,
			deadline: endDate,
			frequency,
			type,
			time_slot,
			excludedDays
		}, isGetRange);
		else if (repeat_type === "2") days = getDaysByRepeatWeek({
			start,
			end,
			deadline: endDate,
			frequency,
			frequency_date,
			type,
			time_slot,
			excludedDays
		}, isGetRange);
	}
	if (isGetRange) {
		if (includedDays.length) for (let i = 0; i < includedDays.length; i++) {
			const includedDay = includedDays[i];
			days.push(...getDataRange({
				start: dayjs(includedDay),
				end: dayjs(includedDay),
				type,
				time_slot
			}));
		}
		return days;
	}
	if (includeStatus) days = days.concat(includedDays);
	return formatDayColor({
		days,
		color,
		excludedDays: excludedStatus ? excludedDays : []
	});
};
/**
* 根据标准日程计算日历数据
* @param values
* @param others
*/
const calcCalendarDataByStandard = (values, others, isGetRange) => {
	const { color, excluded_date, included_date, end_date, designation, repeat_type, frequency = 1, frequency_date = [], time_slot, start_time, end_time } = values;
	const { endRadio, isAllDay, includeStatus, excludedStatus } = others;
	if (isArr(designation)) return [];
	return processDateRange({
		repeat_type,
		start: designation ? mergeDateTime(designation.start_date, isAllDay ? designation.start_time : "") : dayjs(start_time),
		end: designation ? mergeDateTime(designation.end_date, isAllDay ? designation.end_time : "") : dayjs(end_time),
		color,
		endRadio,
		end_date,
		excluded_date,
		excludedStatus,
		frequency,
		frequency_date,
		included_date,
		includeStatus,
		time_slot,
		type: "standard"
	}, isGetRange);
};
const getMaxStart = (start_time) => {
	const valueStart = dayjs(start_time);
	const currentYearStart = dayjs().startOf("year").set("hour", valueStart.get("hour")).set("minute", valueStart.get("minutes")).set("second", valueStart.get("second"));
	return valueStart.isBefore(currentYearStart) ? currentYearStart : valueStart;
};
/**
* 根据多时间段计算日历数据
* @param values
* @param others
*/
const calcCalendarDataByTimeSlots = (values, others, isGetRange) => {
	const { color, excluded_date, included_date, end_date, repeat_type, frequency = 1, frequency_date = [], start_time, time_slot } = values;
	const { endRadio, excludedStatus, includeStatus } = others;
	if (!start_time) return [];
	return processDateRange({
		repeat_type,
		start: dayjs(start_time),
		end: dayjs(start_time),
		color,
		endRadio,
		end_date,
		excluded_date,
		excludedStatus,
		frequency,
		frequency_date,
		included_date,
		includeStatus,
		time_slot,
		type: "time-slots"
	}, isGetRange);
};
/**
* 根据指定日期计算日历数据
* @param values
* @param others
*/
const calcCalendarDataByDesignation = (values, others, isGetRange) => {
	const { designation, color } = values;
	const days = [];
	if (isArr(designation)) designation.forEach((item) => {
		const start = mergeDateTime(item.start_date, item.start_time);
		const end = mergeDateTime(item.end_date, item.end_time);
		if (isGetRange) days.push({
			start: `${item.start_date} ${item.start_time}`,
			end: `${item.end_date} ${item.end_time}`
		});
		else days.push(...getDaysByStartEnd(start, end));
	});
	if (isGetRange) return days;
	return formatDayColor({
		days,
		color,
		excludedDays: []
	});
};
const isAllDay = (value) => {
	return dayjs(value.start_time).format("HH:mm:ss") === "00:00:00" && dayjs(value.end_time).format("HH:mm:ss") === "23:59:59";
};
const repeatTypeMap = {
	none: "0",
	daily: "1",
	weekly: "2"
};
const endTypeMap = {
	never: 1,
	date: 2
};
/**
* 根据接口返回的Schedule计算日历数据
* @param schedule
*/
const calcCalendarDataByScheduleResult = (schedule) => {
	const { scheduleFormData, scheduleFormOtherValue } = formatScheduleResult(schedule);
	return calcCalendarDataBySchedule(scheduleFormData, scheduleFormOtherValue, schedule.type);
};
/**
* 接口返回schedule转换格式
* @param schedule
*/
const formatScheduleResult = (schedule) => {
	const { color, name, repeat_type, designation, repeat_rule, start_time, end_time, is_all, type, time_slot } = schedule;
	const { frequency, end, frequency_date, included_date, excluded_date } = repeat_rule || {};
	return {
		scheduleFormData: {
			color,
			name,
			repeat_type: repeatTypeMap[repeat_type],
			designation,
			frequency,
			frequency_date,
			end_time,
			start_time,
			excluded_date,
			included_date,
			time_slot,
			end_date: end === null || end === void 0 ? void 0 : end.end_date
		},
		scheduleFormOtherValue: {
			endRadio: endTypeMap[(end === null || end === void 0 ? void 0 : end.type) || "never"],
			isAllDay: !!is_all,
			type,
			excludedStatus: !!(excluded_date === null || excluded_date === void 0 ? void 0 : excluded_date.length),
			includeStatus: !!(included_date === null || included_date === void 0 ? void 0 : included_date.length)
		}
	};
};
const calcScheduleDateRange = (schedule) => {
	const { scheduleFormData, scheduleFormOtherValue } = formatScheduleResult(schedule);
	if (schedule.type === "time-slots") return calcCalendarDataByTimeSlots(scheduleFormData, scheduleFormOtherValue, true);
	if (schedule.type === "designation") return calcCalendarDataByDesignation(scheduleFormData, scheduleFormOtherValue, true);
	return calcCalendarDataByStandard(scheduleFormData, scheduleFormOtherValue, true);
};
const calcCalendarDataBySchedules = (schedules) => {
	const allSchedules = [];
	schedules.forEach((item) => {
		allSchedules.push(...calcCalendarDataByScheduleResult(item));
	});
	const dateMap = allSchedules.reduce((pre, cur) => {
		var _pre$cur$date, _pre$cur$date2;
		return _objectSpread2(_objectSpread2({}, pre), {}, { [cur.date]: _objectSpread2(_objectSpread2({}, cur), {}, {
			color: [...((_pre$cur$date = pre[cur.date]) === null || _pre$cur$date === void 0 ? void 0 : _pre$cur$date.color) || [], ...cur.color],
			isExcluded: ((_pre$cur$date2 = pre[cur.date]) === null || _pre$cur$date2 === void 0 ? void 0 : _pre$cur$date2.isExcluded) || cur.isExcluded
		}) });
	}, {});
	return Object.values(dateMap);
};
const calcMinTimeMaxTimeBySchedules = (schedules, scheduleAllMap, selectDate) => {
	return schedules.reduce((pre, cur) => {
		var _scheduleAllMap$cur$i;
		let dateRange = ((_scheduleAllMap$cur$i = scheduleAllMap[cur.id]) === null || _scheduleAllMap$cur$i === void 0 ? void 0 : _scheduleAllMap$cur$i.dateRange) || calcScheduleDateRange(cur);
		let dateRangeFormat = [];
		if (selectDate) {
			const dateRangeTmp = [];
			const dateRangeFormatTmp = [];
			for (let i = 0; i < dateRange.length; i++) {
				const range = dateRange[i];
				const start = dayjs(range.start);
				const end = dayjs(range.end);
				const isSameStart = range.start.includes(selectDate);
				const isSameEnd = range.end.includes(selectDate);
				if (isSameStart || isSameEnd) {
					dateRangeTmp.push(range);
					if (isSameStart && !isSameEnd) dateRangeFormatTmp.push({
						start: range.start,
						end: end.format("YYYY-MM-DD 23:59:59")
					});
					else if (!isSameStart && isSameEnd) dateRangeFormatTmp.push({
						start: start.format("YYYY-MM-DD 00:00:00"),
						end: range.end
					});
					else dateRangeFormatTmp.push(range);
				}
			}
			dateRange = dateRangeTmp;
			dateRangeFormat = dateRangeFormatTmp;
		}
		let minTime = null;
		let maxTime = null;
		if (dateRange.length) {
			minTime = dayjs(dateRange[0].start);
			maxTime = dayjs(dateRange[dateRange.length - 1].end);
		}
		return _objectSpread2(_objectSpread2({}, pre), {}, { [cur.id]: {
			minTime,
			maxTime,
			minTimeStr: (minTime === null || minTime === void 0 ? void 0 : minTime.format("YYYY-MM-DD HH:mm:ss")) || null,
			maxTimeStr: (maxTime === null || maxTime === void 0 ? void 0 : maxTime.format("YYYY-MM-DD HH:mm:ss")) || null,
			dateRange,
			dateRangeFormat
		} });
	}, {});
};
/**
* @title: 格式化日程数据
* @description: 
* @param {Array} relation 资源列表
* @param {string} table_type 关联表类型
* @param {string} item_type 资源类型
* @param {boolean} isExcluded 是否排除
* @return {*}
* @Author: WangHan
* @Date: 2024-09-04 11:54
*/
const formatScheduleData = (relation, table_type, item_type, isExcluded) => {
	const _relation = relation || [];
	if (table_type && item_type && isExcluded) return _relation.find((item) => (item === null || item === void 0 ? void 0 : item.relation_table_type) === table_type && (item === null || item === void 0 ? void 0 : item.item_type) !== item_type);
	if (table_type && item_type) return _relation.find((item) => (item === null || item === void 0 ? void 0 : item.relation_table_type) === table_type && (item === null || item === void 0 ? void 0 : item.item_type) === item_type);
	if (table_type) return _relation.some((item) => (item === null || item === void 0 ? void 0 : item.relation_table_type) === table_type);
	if (item_type) return _relation.find((item) => (item === null || item === void 0 ? void 0 : item.item_type) === item_type);
};
/**
* @title: 格式化日程为二维结构
* @description: 
* @param {any} list
* @param {any} filterItem
* @return {*}
* @Author: WangHan
* @Date: 2024-07-29 19:28
*/
const formatScheduleListByTabs = (list, filterItem) => {
	let _list = list || [];
	if (filterItem) _list = _list.filter(filterItem);
	let categoryObject = {
		all: {
			id: 0,
			name: locales.getText("pisell2.schedule.tab.all"),
			products: _list
		},
		surcharge: {
			id: 1,
			name: locales.getText("pisell2.schedule.tab.surcharge"),
			products: []
		},
		resources: {
			id: 2,
			name: locales.getText("pisell2.schedule.tab.resources"),
			products: []
		},
		products: {
			id: 3,
			name: locales.getText("pisell2.schedule.tab.products"),
			products: []
		},
		events: {
			id: 4,
			name: locales.getText("pisell2.schedule.tab.events"),
			products: []
		},
		quotation: {
			id: 5,
			name: locales.getText("pisell2.schedule.tab.quotation"),
			products: []
		},
		"open-hours": {
			id: 6,
			name: locales.getText("pisell2.schedule.tab.open-hours"),
			products: []
		}
	};
	for (let i = 0; i < _list.length; i++) {
		const productItem = _list[i];
		const _relation = productItem.relation || [];
		if (formatScheduleData(_relation, "custom_surcharge")) categoryObject.surcharge.products.push(productItem);
		if (formatScheduleData(_relation, "form", "opening_hours", true)) categoryObject.resources.products.push(productItem);
		if (formatScheduleData(_relation, "product")) categoryObject.products.products.push(productItem);
		if (formatScheduleData(_relation, "product", "event_item")) categoryObject.events.products.push(productItem);
		if (formatScheduleData(_relation, "shelf", "quotation")) categoryObject.quotation.products.push(productItem);
		if (formatScheduleData(_relation, "", "opening_hours")) categoryObject["open-hours"].products.push(productItem);
	}
	Object.keys(categoryObject).forEach((cur) => {
		var _categoryObject$cur;
		if ((categoryObject === null || categoryObject === void 0 || (_categoryObject$cur = categoryObject[cur]) === null || _categoryObject$cur === void 0 || (_categoryObject$cur = _categoryObject$cur.products) === null || _categoryObject$cur === void 0 ? void 0 : _categoryObject$cur.length) === 0) delete categoryObject[cur];
	});
	return Object.values(categoryObject);
};
//#endregion
export { calcCalendarDataBySchedule, calcCalendarDataBySchedules, calcMinTimeMaxTimeBySchedules, formatScheduleListByTabs, isAllDay };
