import { _asyncToGenerator } from "../../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
import { _objectWithoutProperties } from "../../../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectWithoutProperties.js";
import dayjs from "dayjs";
import React, { useEffect, useMemo } from "react";
import { Button, Checkbox, Col, Form, Input, Row, Space, TimePicker } from "antd";
import { locales } from "@pisell/utils";
import { PisellModal } from "@pisell/materials";
import { DeleteOutlined, PlusOutlined } from "@ant-design/icons";
//#region src/plus/saasAttendance/settings/components/shiftModal/index.tsx
const _excluded = ["startSort"];
const WEEKDAYS = [
	1,
	2,
	3,
	4,
	5,
	6,
	7
];
const AntRow = Row;
const AntCol = Col;
const AntSpace = Space;
const generateUUID = () => {
	return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
		const r = Math.random() * 16 | 0;
		return (c === "x" ? r : r & 3 | 8).toString(16);
	});
};
const pad2 = (val) => String(val).padStart(2, "0");
const createTime = (hour, minute) => {
	return dayjs().hour(hour).minute(minute).second(0).millisecond(0);
};
const toMinutes = (val) => val.hour() * 60 + val.minute();
const parseHHmm = (hhmm) => {
	const [h, m] = (hhmm || "").split(":").map((v) => Number(v));
	if (!Number.isFinite(h) || !Number.isFinite(m)) return null;
	return createTime(h, m);
};
const formatHHmm = (val) => `${pad2(val.hour())}:${pad2(val.minute())}`;
const buildInitialDays = (value) => {
	const byWeekday = /* @__PURE__ */ new Map();
	if (Array.isArray(value)) value.forEach((item) => {
		if (item && typeof item.weekday === "number") byWeekday.set(item.weekday, item);
	});
	return WEEKDAYS.map((weekday) => {
		const src = byWeekday.get(weekday);
		const times = Array.isArray(src === null || src === void 0 ? void 0 : src.times) ? src.times : [];
		return {
			weekday,
			enabled: times.length > 0,
			times: times.map((t) => {
				return {
					id: (t === null || t === void 0 ? void 0 : t.id) || generateUUID(),
					start: (t === null || t === void 0 ? void 0 : t.start) ? parseHHmm(t.start) : null,
					end: (t === null || t === void 0 ? void 0 : t.end) ? parseHHmm(t.end) : null
				};
			})
		};
	});
};
const getWeekdayText = (weekday) => {
	return locales.getText(`pisell2.attendance.group-settings.shift-schedule.modal.weekday.${weekday}`);
};
const ShiftModal = (props) => {
	const [form] = Form.useForm();
	useEffect(() => {
		if (!props.open) return;
		form.setFieldsValue({ days: buildInitialDays(props.value) });
	}, [
		form,
		props.open,
		props.value
	]);
	const isTimeOverlapping = (dayIndex, timeIndex) => {
		const times = form.getFieldValue([
			"days",
			dayIndex,
			"times"
		]) || [];
		const cur = times === null || times === void 0 ? void 0 : times[timeIndex];
		if (!(cur === null || cur === void 0 ? void 0 : cur.start) || !(cur === null || cur === void 0 ? void 0 : cur.end)) return false;
		const curStart = toMinutes(cur.start);
		const curEnd = toMinutes(cur.end);
		if (curStart >= curEnd) return false;
		for (let i = 0; i < times.length; i += 1) {
			if (i === timeIndex) continue;
			const other = times[i];
			if (!(other === null || other === void 0 ? void 0 : other.start) || !(other === null || other === void 0 ? void 0 : other.end)) continue;
			const oStart = toMinutes(other.start);
			const oEnd = toMinutes(other.end);
			if (oStart >= oEnd) continue;
			if (curStart <= oEnd && oStart <= curEnd) return true;
		}
		return false;
	};
	const triggerDayValidation = (dayIndex) => {
		const times = form.getFieldValue([
			"days",
			dayIndex,
			"times"
		]) || [];
		const fields = [];
		times.forEach((t, idx) => {
			if (t === null || t === void 0 ? void 0 : t.start) fields.push([
				"days",
				dayIndex,
				"times",
				idx,
				"start"
			]);
			if (t === null || t === void 0 ? void 0 : t.end) fields.push([
				"days",
				dayIndex,
				"times",
				idx,
				"end"
			]);
		});
		if (!fields.length) return;
		form.validateFields(fields).catch(() => {});
	};
	const toScheduleValue = (days) => {
		const byWeekday = /* @__PURE__ */ new Map();
		days.forEach((d) => {
			if (d && typeof d.weekday === "number") byWeekday.set(d.weekday, d);
		});
		return WEEKDAYS.map((weekday) => {
			const day = byWeekday.get(weekday);
			if (!(day === null || day === void 0 ? void 0 : day.enabled)) return {
				weekday,
				times: []
			};
			return {
				weekday,
				times: (Array.isArray(day.times) ? day.times : []).filter((t) => (t === null || t === void 0 ? void 0 : t.start) && (t === null || t === void 0 ? void 0 : t.end)).map((t) => ({
					id: t.id || generateUUID(),
					start: formatHHmm(t.start),
					end: formatHHmm(t.end),
					startSort: toMinutes(t.start)
				})).sort((a, b) => a.startSort - b.startSort).map((_ref) => {
					let { startSort: _startSort } = _ref;
					return _objectWithoutProperties(_ref, _excluded);
				})
			};
		});
	};
	const handleConfirm = function() {
		var _ref2 = _asyncToGenerator(function* () {
			let values;
			try {
				values = yield form.validateFields();
			} catch (_unused) {
				return;
			}
			const days = Array.isArray(values === null || values === void 0 ? void 0 : values.days) ? values.days : [];
			props.onOk(toScheduleValue(days));
			props.onCancel();
		});
		return function handleConfirm() {
			return _ref2.apply(this, arguments);
		};
	}();
	const footer = useMemo(() => {
		return /* @__PURE__ */ React.createElement(AntSpace, { style: {
			width: "100%",
			justifyContent: "flex-end"
		} }, /* @__PURE__ */ React.createElement(Button, { onClick: props.onCancel }, locales.getText("pisell2.attendance.group-settings.actions.cancel")), /* @__PURE__ */ React.createElement(Button, {
			type: "primary",
			onClick: handleConfirm
		}, locales.getText("pisell2.attendance.group-settings.actions.confirm")));
	}, [handleConfirm, props.onCancel]);
	return /* @__PURE__ */ React.createElement(PisellModal, {
		open: props.open,
		onCancel: props.onCancel,
		title: locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.title"),
		width: 720,
		bodyStyle: { padding: 20 },
		footer,
		destroyOnClose: true
	}, /* @__PURE__ */ React.createElement(Form, {
		form,
		layout: "vertical"
	}, /* @__PURE__ */ React.createElement(Form.List, { name: "days" }, (dayFields) => /* @__PURE__ */ React.createElement("div", null, dayFields.map((dayField, dayIndex) => {
		return /* @__PURE__ */ React.createElement("div", {
			key: dayField.key,
			style: { padding: "12px 0" }
		}, /* @__PURE__ */ React.createElement(AntRow, {
			gutter: 12,
			align: "top"
		}, /* @__PURE__ */ React.createElement(AntCol, { flex: "180px" }, /* @__PURE__ */ React.createElement(Form.Item, {
			name: [dayField.name, "enabled"],
			valuePropName: "checked",
			style: { marginBottom: 0 }
		}, /* @__PURE__ */ React.createElement(Checkbox, { onChange: (e) => {
			const checked = e.target.checked;
			const timesPath = [
				"days",
				dayIndex,
				"times"
			];
			if (checked) {
				if (!(form.getFieldValue(timesPath) || []).length) form.setFieldValue(timesPath, [{
					id: generateUUID(),
					start: null,
					end: null
				}]);
			} else form.setFieldValue(timesPath, []);
		} }, getWeekdayText(dayIndex + 1))), /* @__PURE__ */ React.createElement(Form.Item, {
			name: [dayField.name, "weekday"],
			hidden: true
		}, /* @__PURE__ */ React.createElement(Input, null))), /* @__PURE__ */ React.createElement(AntCol, { flex: "auto" }, /* @__PURE__ */ React.createElement(Form.Item, {
			noStyle: true,
			shouldUpdate: (prev, cur) => {
				var _prev$days, _cur$days, _prev$days2, _cur$days2;
				return (prev === null || prev === void 0 || (_prev$days = prev.days) === null || _prev$days === void 0 || (_prev$days = _prev$days[dayIndex]) === null || _prev$days === void 0 ? void 0 : _prev$days.enabled) !== (cur === null || cur === void 0 || (_cur$days = cur.days) === null || _cur$days === void 0 || (_cur$days = _cur$days[dayIndex]) === null || _cur$days === void 0 ? void 0 : _cur$days.enabled) || (prev === null || prev === void 0 || (_prev$days2 = prev.days) === null || _prev$days2 === void 0 || (_prev$days2 = _prev$days2[dayIndex]) === null || _prev$days2 === void 0 ? void 0 : _prev$days2.times) !== (cur === null || cur === void 0 || (_cur$days2 = cur.days) === null || _cur$days2 === void 0 || (_cur$days2 = _cur$days2[dayIndex]) === null || _cur$days2 === void 0 ? void 0 : _cur$days2.times);
			}
		}, () => {
			if (!form.getFieldValue([
				"days",
				dayIndex,
				"enabled"
			])) return /* @__PURE__ */ React.createElement("div", { style: {
				lineHeight: "40px",
				color: "#6b7280"
			} }, locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.no-shift"));
			return /* @__PURE__ */ React.createElement(Form.List, { name: [dayField.name, "times"] }, (timeFields, { add, remove }) => /* @__PURE__ */ React.createElement("div", null, timeFields.map((timeField, timeIndex) => {
				return /* @__PURE__ */ React.createElement(AntRow, {
					key: timeField.key,
					gutter: 8,
					style: { marginBottom: 8 }
				}, /* @__PURE__ */ React.createElement(AntCol, { flex: "1 1 220px" }, /* @__PURE__ */ React.createElement(Form.Item, {
					name: [timeField.name, "id"],
					hidden: true
				}, /* @__PURE__ */ React.createElement(Input, null)), /* @__PURE__ */ React.createElement(Form.Item, {
					label: timeIndex === 0 ? locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.start") : void 0,
					name: [timeField.name, "start"],
					rules: [{ validator: function() {
						var _ref3 = _asyncToGenerator(function* (_rule, value) {
							if (!value) throw new Error(locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.validation.start-required"));
							if (isTimeOverlapping(dayIndex, timeField.name)) throw new Error(locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.validation.overlap"));
						});
						return function validator(_x, _x2) {
							return _ref3.apply(this, arguments);
						};
					}() }]
				}, /* @__PURE__ */ React.createElement(TimePicker, {
					use12Hours: true,
					format: "h:mm A",
					style: { width: "100%" },
					onChange: () => {
						triggerDayValidation(dayIndex);
						form.validateFields([[
							"days",
							dayIndex,
							"times",
							timeField.name,
							"end"
						]]).catch(() => {});
					}
				}))), /* @__PURE__ */ React.createElement(AntCol, { flex: "1 1 220px" }, /* @__PURE__ */ React.createElement(Form.Item, {
					label: timeIndex === 0 ? locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.end") : void 0,
					name: [timeField.name, "end"],
					rules: [{ validator: function() {
						var _ref4 = _asyncToGenerator(function* (_rule, value) {
							if (!value) throw new Error(locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.validation.end-required"));
							const startValue = form.getFieldValue([
								"days",
								dayIndex,
								"times",
								timeField.name,
								"start"
							]) || null;
							if (startValue && toMinutes(startValue) >= toMinutes(value)) throw new Error(locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.validation.range"));
						});
						return function validator(_x3, _x4) {
							return _ref4.apply(this, arguments);
						};
					}() }]
				}, /* @__PURE__ */ React.createElement(TimePicker, {
					use12Hours: true,
					format: "h:mm A",
					style: { width: "100%" },
					onChange: () => {
						triggerDayValidation(dayIndex);
					}
				}))), /* @__PURE__ */ React.createElement(AntCol, { flex: "0 0 40px" }, timeIndex === 0 ? /* @__PURE__ */ React.createElement("div", { style: { height: 48 } }) : null, /* @__PURE__ */ React.createElement(Button, {
					icon: /* @__PURE__ */ React.createElement(DeleteOutlined, null),
					onClick: () => {
						remove(timeField.name);
						triggerDayValidation(dayIndex);
						if (!(form.getFieldValue([
							"days",
							dayIndex,
							"times"
						]) || []).length) form.setFieldValue([
							"days",
							dayIndex,
							"enabled"
						], false);
					}
				})));
			}), /* @__PURE__ */ React.createElement(Button, {
				icon: /* @__PURE__ */ React.createElement(PlusOutlined, null),
				onClick: () => {
					const times = form.getFieldValue([
						"days",
						dayIndex,
						"times"
					]) || [];
					const last = times[times.length - 1];
					if (!(last === null || last === void 0 ? void 0 : last.start) || !(last === null || last === void 0 ? void 0 : last.end)) {
						add({
							id: generateUUID(),
							start: null,
							end: null
						});
						triggerDayValidation(dayIndex);
						return;
					}
					const lastEnd = last.end;
					const endDateText = lastEnd.format("YYYY-MM-DD");
					const nextStart = lastEnd.add(1, "hour");
					const nextEnd = lastEnd.add(2, "hour");
					if (nextEnd.format("YYYY-MM-DD") !== endDateText || nextStart.format("YYYY-MM-DD") !== endDateText) {
						add({
							id: generateUUID(),
							start: createTime(23, 0),
							end: createTime(23, 55)
						});
						triggerDayValidation(dayIndex);
						return;
					}
					add({
						id: generateUUID(),
						start: nextStart,
						end: nextEnd
					});
					triggerDayValidation(dayIndex);
				}
			}, locales.getText("pisell2.attendance.group-settings.shift-schedule.modal.add-time"))));
		}))));
	})))));
};
//#endregion
export { ShiftModal as default };
