import { gpQuery } from "../gpSql/gpSqlQuery.controller.js";
import {
	type SqlGPQuery,
	sqlGpQuerySelector,
} from "../gpSql/gpSqlQuerySelector.utils.js";
import { createLogger } from "../logger/logger.controller.js";
import type { GpStatus } from "../types/purhcaseTypes.js";
import { returnFunc } from "../utils/returnHelper.utils.js";

const log = createLogger({ module: "purchase", subModule: "gp" });

export const gpReqCheck = async (data: GpStatus[]) => {
	const gpReqCheck = sqlGpQuerySelector("reqCheck") as SqlGPQuery;
	const reqs = data.map((r) => r.req.trim());

	if (!gpReqCheck.success) {
		return returnFunc({
			success: false,
			level: "error",
			module: "purchase",
			subModule: "query",
			message: `Error getting alpla purchase info`,
			data: gpReqCheck.message as any,
			notify: true,
		});
	}

	try {
		// check the initial req table
		const result = await gpQuery(
			gpReqCheck.query.replace(
				"[reqsToCheck]",
				data.map((r) => `'${r.req}'`).join(", ") ?? "xo",
			),
			"Get req info",
		);

		log.debug(
			{},
			`There are ${result.data.length} reqs that need to be updated with there current status`,
		);

		const firstFound = result.data.map((r) => ({
			req: r.req.trim(),
			approvedStatus: r.approvedStatus,
		}));

		const firstFoundSet = new Set(result.data.map((r) => r.req.trim()));

		const missing1Reqs = reqs.filter((req) => !firstFoundSet.has(req));

		//check if we have a recall on our req
		const reqCheck = await gpQuery(
			`select 
            [Requisition Number] as req
            ,case when [Workflow Status] = 'recall' then 'returned' else [Workflow Status] end as approvedStatus
            --,* 
            from  [dbo].[PurchaseRequisitions] where [Requisition Number] in (${missing1Reqs.map((r) => `'${r}'`).join(", ") ?? "xo"})`,
			"validate req is not in recall",
		);

		const secondFound = reqCheck.data.map((r) => ({
			req: r.req.trim(),
			approvedStatus: r.approvedStatus,
		}));

		const secondFoundSet =
			new Set(reqCheck.data.map((r) => r.req.trim())) ?? [];

		const missing2Reqs = missing1Reqs.filter((req) => !secondFoundSet.has(req));

		// check if we have a po already
		const apoCheck = await gpQuery(
			`select
                SOPNUMBE
                ,PONUMBER
                ,reqStatus='converted'
                ,* 
	        from alpla.dbo.sop60100 (nolock)  where sopnumbe in (${missing2Reqs.map((r) => `'${r}'`).join(", ") ?? "xo"})`,
			"Get release info",
		);

		const thirdRound = apoCheck.data.map((r) => ({
			req: r.req.trim(),
			approvedStatus: r.approvedStatus,
		}));

		const missing3Reqs = missing2Reqs.filter((req) => !secondFoundSet.has(req));

		// remaining just got canceled or no longer exist
		const remaining = missing3Reqs.map((m) => ({
			req: m,
			approvedStatus: "canceled",
		}));

		const allFound = [
			...firstFound,
			...secondFound,
			...thirdRound,
			...remaining,
		];

		const statusMap = new Map(
			allFound.map((r: any) => [r.req, r.approvedStatus]),
		);

		const updateData = data.map((row) => ({
			id: row.id,
			//req: row.req,
			approvedStatus: statusMap.get(row.req.trim()) ?? null,
		}));

		return updateData;
	} catch (error: any) {
		return returnFunc({
			success: false,
			level: "error",
			module: "purchase",
			subModule: "gpChecks",
			message: error.message,
			data: error.stack as any,
			notify: true,
		});
	}
};
