// priceListProcessor.js

// Fungsi helper: Parse string tanggal ke Date (handle null/kosong/tidak valid)
const parseDate = (dateStr) => {
	if (!dateStr || dateStr.trim() === "") return null;
	const date = new Date(dateStr + "T00:00:00Z"); // Asumsi UTC, tambah waktu 00:00 untuk presisi
	return isNaN(date.getTime()) ? null : date;
};

// Fungsi helper: Format Date ke string "YYYY-MM-DD"
const formatDate = (date) => {
	if (!date) return null;
	return date.toISOString().split("T")[0]; // YYYY-MM-DD
};

// Fungsi helper: Kurangi 1 hari dari Date
const subtractOneDay = (date) => {
	const newDate = new Date(date);
	newDate.setDate(newDate.getDate() - 1);
	return newDate;
};

// Fungsi helper: Tambah 1 hari dari Date
const addOneDay = (date) => {
	const newDate = new Date(date);
	newDate.setDate(newDate.getDate() + 1);
	return newDate;
};

// Fungsi utama: Proses data untuk presisi (dengan handling invalid valid_from)
const processPriceList = (data) => {
	if (!data || data.length === 0) return [];

	const currentDate = new Date(); // Hari ini (UTC)
	currentDate.setHours(0, 0, 0, 0); // Reset ke awal hari untuk perbandingan presisi
	const yesterday = subtractOneDay(currentDate); // Hari ini - 1 hari

	// Kelompokkan berdasarkan item_code + price_list
	const groups = {};
	data.forEach((item) => {
		const groupKey = `${item.item_code}-${item.price_list || "default"}`; // Handle null price_list
		if (!groups[groupKey]) groups[groupKey] = [];
		groups[groupKey].push({ ...item }); // Clone untuk immutable
	});

	const processedData = [];

	// Proses setiap grup
	Object.values(groups).forEach((group) => {
		if (group.length === 0) return;

		// Parse valid_from ke Date
		const parsedGroup = group.map((item) => ({
			...item,
			parsedFrom: parseDate(item.valid_from),
		}));

		// Pisahkan valid dan invalid
		const validEntries = parsedGroup.filter((item) => item.parsedFrom !== null);
		const invalidEntries = parsedGroup.filter((item) => item.parsedFrom === null);

		// Sort valid entries ascending
		const sortedValid = validEntries.sort((a, b) => a.parsedFrom.getTime() - b.parsedFrom.getTime());

		// Handle invalid entries
		invalidEntries.forEach((item) => {
			const processedItem = { ...item };
			let newValidFrom = null;
			let newValidUpto = null;

			if (sortedValid.length > 0) {
				// Ada entri valid lain: assign sebelum earliest valid
				const earliestValidFrom = sortedValid[0].parsedFrom;
				newValidFrom = subtractOneDay(earliestValidFrom);
				newValidUpto = formatDate(addOneDay(earliestValidFrom)); // +1 hari dari valid_from yang sudah ada
			} else {
				// Tidak ada entri valid lain: assign hari ini -1 hari
				newValidFrom = yesterday;
				newValidUpto = null; // Tidak disebutkan, jadi null (aktif masa lalu)
			}

			// Assign nilai baru
			processedItem.valid_from = formatDate(newValidFrom);
			processedItem.valid_upto = newValidUpto;
			processedItem.parsedFrom = newValidFrom; // Untuk sorting nanti
			// Simulasi update
			processedItem.modified = new Date().toISOString();
			processedItem.modified_by = "system";

			processedData.push(processedItem); // Push invalid dulu (akan di-sort global nanti)
		});

		if (sortedValid.length === 0) {
			// Jika hanya invalid, sudah diproses di atas, lanjut ke next grup
			return;
		}

		// Sekarang proses valid entries (termasuk logic active seperti sebelumnya)
		// Tentukan entri aktif: yang valid_from paling dekat dengan currentDate (paling baru <= currentDate)
		let activeIndex = -1;
		let closestFutureIndex = -1;
		for (let i = 0; i < sortedValid.length; i++) {
			const fromDate = sortedValid[i].parsedFrom;
			if (fromDate <= currentDate) {
				// Cari yang paling baru <= currentDate
				if (activeIndex === -1 || fromDate > sortedValid[activeIndex].parsedFrom) {
					activeIndex = i;
				}
			} else if (closestFutureIndex === -1 || fromDate < sortedValid[closestFutureIndex].parsedFrom) {
				closestFutureIndex = i;
			}
		}

		// Jika tidak ada yang <= currentDate, ambil yang paling dekat di masa depan sebagai "aktif sementara"
		if (activeIndex === -1 && closestFutureIndex !== -1) {
			activeIndex = closestFutureIndex;
		}

		// Adjust valid_upto untuk setiap valid entry
		for (let i = 0; i < sortedValid.length; i++) {
			const item = sortedValid[i];
			const processedItem = { ...item };

			if (i === activeIndex) {
				// Entri aktif: valid_upto = null
				processedItem.valid_upto = null;
				// Simulasi update modified (opsional, untuk tracking)
				processedItem.modified = new Date().toISOString();
				processedItem.modified_by = "system"; // Atau user current
			} else {
				// Entri lama: set valid_upto ke valid_from selanjutnya - 1 hari
				let nextFrom = null;
				if (i + 1 < sortedValid.length) {
					nextFrom = sortedValid[i + 1].parsedFrom;
				} else if (activeIndex > i) {
					// Jika ada aktif di belakang, gunakan itu
					nextFrom = sortedValid[activeIndex].parsedFrom;
				}

				if (nextFrom) {
					processedItem.valid_upto = formatDate(subtractOneDay(nextFrom));
				} else {
					// Jika tidak ada selanjutnya, set ke null
					processedItem.valid_upto = null;
				}
				// Simulasi update
				processedItem.modified = new Date().toISOString();
				processedItem.modified_by = "system";
			}

			// Hapus parsedFrom (temporary field)
			delete processedItem.parsedFrom;
			processedData.push(processedItem);
		}
	});

	// Sort output berdasarkan name (untuk konsistensi), dan pastikan jumlah sama
	const sortedOutput = processedData.sort((a, b) => a.name.localeCompare(b.name));
	if (sortedOutput.length !== data.length) {
		console.warn(`Warning: Output length (${sortedOutput.length}) != Input length (${data.length})`);
	}
	return sortedOutput;
};

module.exports = { processPriceList, parseDate, formatDate, subtractOneDay, addOneDay };
