import { subMinutes } from "date-fns";
import { format, formatInTimeZone } from "date-fns-tz";
import { sql } from "drizzle-orm";
import { db } from "../../../pkg/db/db.js";
import {
	type OrderScheduler,
	orderScheduler,
} from "../../../pkg/db/schema/orderScheduler.js";
import { createLogger } from "../../../pkg/logger/logger.js";
import { prodQuery } from "../../../pkg/prodSql/prodQuery.js";
import { scheduler } from "../../../pkg/prodSql/querys/scheduler/scheduler.js";
import { tryCatch } from "../../../pkg/utils/tryCatch.js";

/*
will monitor the incoming goods and the orders and update lst as they change or get updated.
*/
export const schedulerManager = async () => {
	const log = createLogger({
		module: "logistics",
		subModule: "scheduleManager",
	});

	log.info({}, "Starting the scheduler manager up.");

	setInterval(async () => {
		const targetTimeZone = "America/New_York";
		const now = new Date();

		// console.log(formatInTimeZone(now, targetTimeZone, "yyyy-M-d HH:mm"));
		// console.log(format(now, "yyyy-M-d HH:mm"));
		const { data, error } = (await tryCatch(
			prodQuery(
				scheduler.replace(
					"[dateCheck]",
					formatInTimeZone(
						subMinutes(now, 1), // dealing with the 1 min difference in case we have something missed.
						targetTimeZone,
						"yyyy-M-d HH:mm",
					),
				),
				"scheduler",
			),
		)) as any;
		// do the updates to the db so we can pull the info up to the frontend
		if (error) {
			log.error({ error: error }, "there was an error getting the data");
			return;
		}
		const orderData = data.data || ([] as OrderScheduler);
		//console.log(data);

		if (orderData.length === 0) {
			log.debug({}, "There are no new orders or incoming to be updated");
			return;
		}

		for (let i = 0; i < orderData.length; i++) {
			const { data, error } = await tryCatch(
				db
					.insert(orderScheduler)
					.values({
						av: orderData[i].av,
						description: orderData[i].description,
						orderType: orderData[i].type, //orders || incoming
						orderNumber: orderData[i].orderNumber,
						header: orderData[i].av,
						lineItemNumber: orderData[i].lineItemNumber,
						customerReleaseNumber: orderData[i].customerReleaseNumber,
						deliveryDate: new Date(orderData[i].deliveryDate),
						loadingDate: new Date(orderData[i].loadingDate),
						orderQTY: orderData[i].orderQTY,
						orderLu: orderData[i].orderLu,
						deliveredQTY: orderData[i].deliveredQTY,
						deliveredLu: orderData[i].deliveredLu,
						remark: orderData[i].remark,
						createdAsEDI: orderData[i].createdAsEDI,
						currentState: orderData[i].currentState,
						lstDateCheck: new Date(orderData[i].deliveryDate), //this will match the delivery date to start
						customerAddressId: orderData[i].customerAddressId,
						customerDescription: orderData[i].customerDescription,
						orderFrom: "prod", // manual or prod.
						// being edited change to true so it will essential lock all others from editing
						// carrier
						// carrier email. -- when dropped we can email the carrier this could be considered there confirmation.
						addDate: sql`NOW()`,
						updDate: sql`NOW()`,
					})
					.onConflictDoUpdate({
						target: orderScheduler.orderNumber,
						set: {
							deliveryDate: new Date(orderData[i].deliveryDate),
							loadingDate: new Date(orderData[i].loadingDate),
							orderQTY: orderData[i].orderQTY,
							orderLu: orderData[i].orderLu,
							remark: orderData[i].remark,
							currentState: orderData[i].currentState,
							deliveredQTY: orderData[i].deliveredQTY,
							deliveredLu: orderData[i].deliveredLu,
							lstDateCheck: new Date(orderData[i].deliveryDate),
							updDate: sql`NOW()`,
						},
					}),
			);

			if (error) {
				console.log(error);
				log.error(
					{ error: error },
					`There was an error inserting/updating the order ${orderData[i].orderNumber}`,
				);
				continue;
			}

			log.info(
				{ data: data },
				`${orderData[i].orderNumber} was inserted or updated`,
			);

			//await delay
		}
	}, 60 * 1000);
};
