import { isAfter } from "date-fns";
import { format } from "date-fns-tz";
import XLSX from "xlsx";
import { runDatamartQuery } from "../datamart/datamart.controller.js";
import { excelDateStuff } from "../utils/excelToDate.utils.js";
import { returnFunc } from "../utils/returnHelper.utils.js";
import { tryCatch } from "../utils/trycatch.utils.js";
import { abbottForecast } from "./logistics.dm.forecast.map.abbott.js";
import { postData } from "./logistics.dm.postData.js";

// customeris/articles stuff will be in basis once we move to iowa
const customerID = 8;
const invoiceID = 9;
const articles = "118,120";
export const abbottOrders = async (data: any, user: any) => {
	/**
	 * Standard orders meaning that we get the standard file exported and fill it out and uplaod to lst.
	 */

	// articleInfo
	const { data: article, error: ae } = await tryCatch(
		runDatamartQuery({ name: "bulkOrderArticleInfo", options: { articles } }),
	);

	const a: any = article?.data;
	if (ae) {
		return returnFunc({
			success: false,
			level: "error",
			module: "logistics",
			subModule: "orders",
			message: `Error getting Article info`,
			data: [ae.message],
			notify: true,
		});
	}

	const { data: o, error: oe } = await tryCatch(
		runDatamartQuery({ name: "orderState", options: {} }),
	);

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

	const openOrders: any = o?.data;

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

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

	const sheetName = workbook.SheetNames[0] as string;
	const sheet = workbook.Sheets[sheetName] as any;

	abbottForecast(sheet, user);
	// Define custom headers
	const customHeaders = ["date", "time", "newton8oz", "newton10oz"];
	const orderData = XLSX.utils.sheet_to_json(sheet, {
		range: 5, // Start at row 5 (index 4)
		header: customHeaders,
		defval: "", // Default value for empty cells
	});

	// the base of the import
	const predefinedObject = {
		receivingPlantId: process.env.PROD_PLANT_TOKEN ?? "test1",
		documentName: `OrdersFromLST-${new Date(Date.now()).toLocaleString(
			"en-US",
		)}`,
		sender: user.username || "lst-system",
		externalRefNo: `OrdersFromLST-${new Date(Date.now()).toLocaleString(
			"en-US",
		)}`,
		orders: [],
	};
	//const oOrders: any = openOrders;
	//console.log(orderData);

	function trimAll(str: string) {
		return str.replace(/\s+/g, "");
	}
	let correctedOrders: any = orderData
		.filter(
			(o: any) =>
				(o.newton8oz && o.newton8oz.trim() !== "") ||
				(o.newton10oz && o.newton10oz.trim() !== ""),
		)
		.map((o: any) => ({
			date: excelDateStuff(o.date, o.time),
			po:
				trimAll(o.newton8oz) !== ""
					? trimAll(o.newton8oz)
					: o.newton10oz.replace(/[\s\u00A0]+/g, ""),
			customerArticleNumber:
				o.newton8oz !== ""
					? a.filter((a: any) => a.av === 118)[0].CustomerArticleNumber
					: a.filter((a: any) => a.av === 120)[0].CustomerArticleNumber,
			qty:
				o.newton8oz !== ""
					? a.filter((a: any) => a.av === 118)[0].totalTruckLoad
					: a.filter((a: any) => a.av === 120)[0].totalTruckLoad,
		}));

	//console.log(correctedOrders);
	// now we want to make sure we only correct orders that or after now
	correctedOrders = correctedOrders.filter((o: any) => {
		//const parsedDate = parse(o.date, "M/d/yyyy, h:mm:ss a", new Date());
		return isAfter(new Date(o.date), new Date().toISOString());
	});
	//console.log(correctedOrders);
	// last map to remove orders that have already been started
	// correctedOrders = correctedOrders.filter((oo: any) =>
	//     oOrders.some((o: any) => o.CustomerOrderNumber === oo.po)
	// );
	const postedOrders: any = [];
	const filterOrders: any = correctedOrders;

	//console.log(filterOrders);

	filterOrders.forEach((oo: any) => {
		const isMatch = openOrders.some(
			(o: any) => String(o.po).trim() === String(oo.po).trim(),
		);
		//console.log(isMatch, oo.po);
		if (!isMatch) {
			//console.log(`ok to update: ${oo.po}`);

			// oo = {
			//     ...oo,
			//     CustomerOrderNumber: oo.CustomerOrderNumber.replace(" ", ""),
			// };
			postedOrders.push(oo);
		} else {
			//console.log(`Not valid order to update: ${oo.po}`);
			//console.log(oo)
		}
	});

	// Map Excel data to predefinedObject format
	const orders = filterOrders.map((o: any) => {
		//console.log(o.po, " ", o.date, format(o.date, "M/d/yyyy HH:mm"));
		return {
			customerId: customerID,
			invoiceAddressId: invoiceID,
			customerOrderNo: o.po,
			orderDate: new Date(Date.now()).toLocaleString("en-US"),
			positions: [
				{
					deliveryAddressId: 8,
					customerArticleNo: o.customerArticleNumber,
					quantity: o.qty,
					deliveryDate: format(o.date, "M/d/yyyy HH:mm"), // addHours(format(o.date, "M/d/yyyy HH:mm"), 1), //addHours(addDays(o.date, 1), 1), // adding this in so we can over come the constant 1 day behind thing as a work around
					customerLineItemNo: 1, // this is how it is currently sent over from abbott
					customerReleaseNo: 1, // same as above
				},
			],
		};
	});

	//console.log(orders);
	// combine it all together.
	const updatedPredefinedObject = {
		...predefinedObject,
		orders: [...predefinedObject.orders, ...orders],
	};

	//console.log(updatedPredefinedObject);
	// post the orders to the server
	const posting: any = await postData(
		{
			type: "orders",
			endpoint: "/public/v1.0/DemandManagement/ORDERS",
			data: updatedPredefinedObject as any,
		},
		user,
	);

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