const require_duration = require('../duration.js');

//#region ../../node_modules/.pnpm/luxon@3.5.0/node_modules/luxon/src/impl/diff.js
function dayDiff(earlier, later) {
	const utcDayStart = (dt) => dt.toUTC(0, { keepLocalTime: true }).startOf("day").valueOf(), ms = utcDayStart(later) - utcDayStart(earlier);
	return Math.floor(require_duration.default.fromMillis(ms).as("days"));
}
function highOrderDiffs(cursor, later, units) {
	const differs = [
		["years", (a, b) => b.year - a.year],
		["quarters", (a, b) => b.quarter - a.quarter + (b.year - a.year) * 4],
		["months", (a, b) => b.month - a.month + (b.year - a.year) * 12],
		["weeks", (a, b) => {
			const days = dayDiff(a, b);
			return (days - days % 7) / 7;
		}],
		["days", dayDiff]
	];
	const results = {};
	const earlier = cursor;
	let lowestOrder, highWater;
	for (const [unit, differ] of differs) if (units.indexOf(unit) >= 0) {
		lowestOrder = unit;
		results[unit] = differ(cursor, later);
		highWater = earlier.plus(results);
		if (highWater > later) {
			results[unit]--;
			cursor = earlier.plus(results);
			if (cursor > later) {
				highWater = cursor;
				results[unit]--;
				cursor = earlier.plus(results);
			}
		} else cursor = highWater;
	}
	return [
		cursor,
		results,
		highWater,
		lowestOrder
	];
}
function diff_default(earlier, later, units, opts) {
	let [cursor, results, highWater, lowestOrder] = highOrderDiffs(earlier, later, units);
	const remainingMillis = later - cursor;
	const lowerOrderUnits = units.filter((u) => [
		"hours",
		"minutes",
		"seconds",
		"milliseconds"
	].indexOf(u) >= 0);
	if (lowerOrderUnits.length === 0) {
		if (highWater < later) highWater = cursor.plus({ [lowestOrder]: 1 });
		if (highWater !== cursor) results[lowestOrder] = (results[lowestOrder] || 0) + remainingMillis / (highWater - cursor);
	}
	const duration = require_duration.default.fromObject(results, opts);
	if (lowerOrderUnits.length > 0) return require_duration.default.fromMillis(remainingMillis, opts).shiftTo(...lowerOrderUnits).plus(duration);
	else return duration;
}

//#endregion
exports.default = diff_default;