import { addDays } from "date-fns";
import XLSX from "xlsx";
import { runDatamartQuery } from "../datamart/datamart.controller.js";
import { returnFunc } from "../utils/returnHelper.utils.js";
//import { sendEmail } from "../utils/sendEmail.utils.js";
import { tryCatch } from "../utils/trycatch.utils.js";
import { postData } from "./logistics.dm.postData.js";

const customerID = 4;
export const lorealForecast = async (data: any, user: any) => {
	/**
	 * Post a standard forecast based on the standard template.
	 */

	const buffer = Buffer.from(data.buffer);

	const workbook = XLSX.read(buffer, { type: "buffer" });

	const sheet: any = workbook.Sheets["Alpla HDPE"];
	const range = XLSX.utils.decode_range(sheet["!ref"]);

	const psheet: any = workbook.Sheets["Alpla PET"];
	const prange = XLSX.utils.decode_range(psheet["!ref"]);

	const headers = [];
	for (let C = range.s.c; C <= range.e.c; ++C) {
		const cellAddress = XLSX.utils.encode_cell({ r: 1, c: C }); // row 0 = Excel row 1
		const cell = sheet[cellAddress];
		headers.push(cell ? cell.v : undefined);
	}

	const pheaders = [];
	for (let C = prange.s.c; C <= prange.e.c; ++C) {
		const cellAddress = XLSX.utils.encode_cell({ r: 1, c: C }); // row 0 = Excel row 1
		const cell = psheet[cellAddress];
		pheaders.push(cell ? cell.v : undefined);
	}

	const ebmForeCastData: any = XLSX.utils.sheet_to_json(sheet, {
		defval: "",
		header: headers,
		range: 3,
	});

	const petForeCastData: any = XLSX.utils.sheet_to_json(psheet, {
		defval: "",
		header: pheaders,
		range: 3,
	});

	const ebmForecastData: any = [];
	const missingSku: any = [];

	const { data: a, error: ae } = await tryCatch(
		runDatamartQuery({ name: "activeArticles", options: {} }),
	);

	if (ae) {
		return returnFunc({
			success: false,
			level: "error",
			module: "logistics",
			subModule: "forecast",
			message: `Error getting Article info`,
			data: [ae.message],
			notify: true,
		});
	}

	const article: any = a?.data;

	//console.log(article);

	// process the ebm forcast
	for (let i = 0; i < ebmForeCastData.length; i++) {
		// bottle code
		const sku = ebmForeCastData[i]["HDPE Bottle Code"];

		// ignore the blanks
		if (sku === "") continue;

		// ignore zero qty
		// if (ebmForeCastData[i][`Day ${i}`]) continue;

		for (let f = 0; f <= 90; f++) {
			const day = `Day ${f + 1}`;
			// if (ebmForeCastData[i][day] === 0) continue;

			const forcast = {
				customerArticleNo: sku,
				requirementDate: addDays(new Date(Date.now()), f), //excelDateStuff(parseInt(date)),
				quantity: ebmForeCastData[i][day] ?? 0,
			};

			if (forcast.quantity === 0) continue;

			// checking to make sure there is a real av to add to.
			const activeAV = article.filter(
				(c: any) =>
					c?.CustomerArticleNumber === forcast.customerArticleNo.toString(),
			);

			if (activeAV.length === 0) {
				if (typeof forcast.customerArticleNo === "number") {
					missingSku.push(forcast);
				}
				continue;
			}

			ebmForecastData.push(forcast);
		}

		//console.log(ebmForeCastData.length);
	}

	// pet forecast
	for (let i = 0; i < petForeCastData.length; i++) {
		// bottle code
		const sku = petForeCastData[i]["South PET Bottle Code"];

		// ignore the blanks
		if (sku === "") continue;

		// ignore zero qty
		// if (ebmForeCastData[i][`Day ${i}`]) continue;

		for (let f = 0; f <= 90; f++) {
			const day = `Day ${f + 1}`;
			// if (ebmForeCastData[i][day] === 0) continue;

			const forcast = {
				customerArticleNo: sku,
				requirementDate: addDays(new Date(Date.now()), f), //excelDateStuff(parseInt(date)),
				quantity: petForeCastData[i][day] ?? 0,
			};

			if (forcast.quantity === 0 || forcast.quantity === "") continue;

			if (forcast.customerArticleNo < 99999) {
				//console.log(`Sku a normal av ${forcast.customerArticleNo}`);
				continue;
			}

			// checking to make sure there is a real av to add to.
			const activeAV = article.filter(
				(c: any) =>
					c?.CustomerArticleNumber === forcast.customerArticleNo.toString(),
			);

			if (activeAV.length === 0) {
				if (typeof forcast.customerArticleNo === "number") {
					missingSku.push(forcast);
				}
				continue;
			}

			ebmForecastData.push(forcast);
		}
	}

	//console.log(comForecast);

	// email the  for the missing ones
	// const missedGrouped = Object.values(
	// 	missingSku.reduce((acc: any, item: any) => {
	// 		const key = item.customerArticleNo;

	// 		if (!acc[key]) {
	// 			// first time we see this customer
	// 			acc[key] = item;
	// 		} else {
	// 			// compare dates and keep the earliest
	// 			if (
	// 				new Date(item.requirementDate) < new Date(acc[key].requirementDate)
	// 			) {
	// 				acc[key] = item;
	// 			}
	// 		}

	// 		return acc;
	// 	}, {}),
	// );

	// TODO: change this to a flagged notification so that he users can subscribe or leave it. this removes the hardcody shit.
	// const emailSetup = {
	// 	email:
	// 		"Blake.matthes@alpla.com; Stuart.Gladney@alpla.com; Harold.Mccalister@alpla.com; Jenn.Osbourn@alpla.com",
	// 	subject:
	// 		missedGrouped.length > 0
	// 			? `Alert! There are ${missedGrouped.length}, missing skus.`
	// 			: `Alert! There is a missing SKU.`,
	// 	template: "missingLorealSkus",
	// 	context: {
	// 		items: missedGrouped,
	// 	},
	// };
	// sendEmail(emailSetup);

	// if the customerarticle number is not matching just ignore it
	const predefinedObject = {
		receivingPlantId: process.env.PROD_PLANT_TOKEN ?? "test1",
		documentName: `ForecastFromLST-${new Date(Date.now()).toLocaleString(
			"en-US",
		)}`,
		sender: user.username || "lst-system",
		customerId: customerID,
		positions: [],
	};

	const updatedPredefinedObject = {
		...predefinedObject,
		positions: [...predefinedObject.positions, ...ebmForecastData],
	};
	// console.log(updatedPredefinedObject);

	// posting the data to the new backend so we can store the data.
	const posting: any = await postData(
		{
			type: "forecast",
			endpoint: "/public/v1.0/DemandManagement/DELFOR",
			data: updatedPredefinedObject as any,
		},
		user,
	);

	return {
		success: posting.success,
		message: posting.message,
		data: posting.data === "" ? ebmForecastData : posting.data,
	};
};
