import { format } from "date-fns-tz";
import { tryCatch } from "../../../globalUtils/tryCatch.js";
import { query } from "../../sqlServer/prodSqlServer.js";

const improvedQuery = `

DECLARE @StartDate DATE = '[startDate]' -- 2025-1-1
DECLARE @EndDate DATE = '[endDate]' -- 2025-1-31

SELECT 
	[RunningNumber] as lot
      ,[ProfitCentreDescription]
      ,[MachineDescription]
      ,[ArticleHumanReadableId]
      ,[ArticleDescription]
      ,[DeliveryAddressHumanReadableId]
      ,[DeliveryAddressDescription]
      ,[MouldHumanReadableId]
      ,[BlowheadHumanReadableId1]
      ,[PackagingInstructionHumanReadableId]
      ,[PackagingInstructionDescription]
      ,[MainMaterialHumanReadableId]
      ,[MainMaterialDescription]
      ,[CompoundHumanReadableId]
      ,[CompoundDescription]
      ,[ProductionLotState]
      ,[PlanType]
      ,[ProducedQuantityLoadingUnit]
      ,[ProducedQuantityPieces]
      ,[PlanStart]
      ,[PlanEnd]
	  ,[ProdStart] 
	  ,[TheoreticEnd]
    	  ,[ProdDuration]
      ,[SetupDuration]  
      ,[StartupDuration]
    
      ,[NetEquipmentEfficiency]
      ,[UtilisationDuration]
      ,[CycleTime]
      ,[Cavities]
      ,[FixedQuantity]
      ,[ProducedQuantityTrucks]
      ,[ProducedQuantityTradeUnit]
      ,[MaxRegrind]
      ,[Conflict]
      ,[ProductionOrderHumanReadableId]
      ,[ProductionDataImportSource]
      ,[Remark]
      ,[BlowheadDescription1]
      ,[MouldDescription]
      ,[ProcessLossPercentage]
      ,[SetupTypeNumberOfPersons]
      ,[UnplannedDowntimePercentage]
      ,[PlanQuantityLoadingUnit]
      ,[PlanQuantityPieces]
      ,[PlanQuantityTradeUnit]
      ,[PlanQuantityTrucks]
      ,[PublishState]
      ,[LastChange]
      ,[MaterialConsumed]
      ,[MaterialStaged]
      ,[MachineLocation]
      ,[HasPrioritization]
      ,[ArticleAlias]

  FROM [test1_AlplaPROD2.0_Read].[productionScheduling].[ProductionLot] with (nolock)
  where TheoreticEnd between @StartDate and @EndDate
  and ArticleHumanReadableId in ([articles])
    and PublishState = 1
  order by PlanStart 

`;
export const improvedPsiPlanningInfo = async (something: any) => {
	const { data, error } = (await tryCatch(
		query(
			improvedQuery
				.replace("[articles]", something.avs)
				.replace("[startDate]", something.startDate)
				.replace("[endDate]", something.endDate),
			"PSI planning info",
		),
	)) as any;

	// add error handling in later here

	return splitProduction(data.data);
};

const splitProduction = (runs: any) => {
	const results: any = [];
	const WORKDAY_START_HOUR = 7; // 07:00 start well later get this from the shift def

	runs.forEach((e: any) => {
		const {
			PlanStart,
			PlanEnd,
			PlanQuantityPieces,
			ArticleHumanReadableId,
			ProdDuration,
		} = e;

		const prodStart: any = new Date(PlanStart);
		const prodEnd: any = new Date(PlanEnd);
		const prodDuration = ProdDuration
			? ProdDuration * 60 * 60 * 1000
			: prodEnd - prodStart;

		// get the prod date the production falls under
		function getProdDayStart(date: Date) {
			const d = new Date(date);
			d.setHours(WORKDAY_START_HOUR, 0, 0, 0);

			if (date.getHours() < WORKDAY_START_HOUR) {
				// before 07:00, belongs to previous calendar day
				d.setDate(d.getDate() - 1);
			}
			return d;
		}

		// current pointer starts at the work-day start that contains our start time
		let currentStart = new Date(prodStart);
		let prodDayStart = getProdDayStart(currentStart);

		while (prodDayStart < prodEnd) {
			// 1️⃣ The next day’s start = prodDayStart + 1 day at 07:00
			const nextProdDayStart = new Date(prodDayStart);
			nextProdDayStart.setDate(nextProdDayStart.getDate() + 1);

			// 2️⃣ Segment end is either the next work-day start or the actual end, whichever is sooner
			const segmentEnd = new Date(
				Math.min(nextProdDayStart.getTime(), prodEnd.getTime()),
			);

			// 3️⃣ Determine overlap window within (startTime..endTime)
			const segStart: any = new Date(
				Math.max(prodDayStart.getTime(), prodStart.getTime()),
			);
			const segEnd: any = segmentEnd;

			if (segEnd > segStart) {
				const segMs = segEnd - segStart;
				const proportion = segMs / prodDuration;
				const qty = PlanQuantityPieces * proportion;
				const pal = e.PlanQuantityLoadingUnit * proportion;

				results.push({
					Article: ArticleHumanReadableId,
					Description: e.ArticleAlias,
					MachineId: e.MachineLocation,
					MachineName: e.MachineDescription,
					LotNumber: e.lot,
					ProductionDay: format(prodDayStart, "M/d/yyyy"),
					TotalPlanned: e.PlanQuantityPieces,
					// PlanEnd,
					// TheoreticEnd,
					QTYPerDay: parseInt(qty.toFixed(0)),
					PalDay: parseFloat(pal.toFixed(2)),
					finished: e.ProductionLotState === 3 ? 1 : 0,
					//prodDuration,
				});
			}

			// move to next production-day window
			prodDayStart = nextProdDayStart;
		}
	});

	return results;
};
