import { isBefore } from "date-fns";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { query } from "../../../sqlServer/prodSqlServer.js";
import { currentInv } from "../../../sqlServer/querys/notifications/fifoIndex/currentInv.js";
import { shippedPallets } from "../../../sqlServer/querys/notifications/fifoIndex/shippedPallets.js";
import { db } from "../../../../../database/dbclient.js";
import { fifoIndex } from "../../../../../database/schema/fifoIndex.js";

export default async function fifoIndexCheck() {
    /**
     * getting the shipped pallets
     */
    const { data: shipped, error: eShipped } = await tryCatch(
        query(shippedPallets, "notify shipped pallets")
    );

    const { data: currentStuff, error: eCurrentInv } = await tryCatch(
        query(currentInv, "notify shipped pallets")
    );

    // console.log(shipped?.data[2]);
    // console.log(currentStuff?.data[2]);

    /**
     * We want to check if the each shippened pallet is out of fifo
     */
    const check = shipped?.data.map((n: any) => {
        /**
         * Returns all data so we know if we are in or out.
         */
        //check if there are pallets older than the current one we are mapped on.
        const fifoCheck = currentStuff?.data.filter(
            (i: any) => isBefore(i.prodDate, n.prodDate) && i.av === n.av
        );
        //console.log(fifoCheck.length);
        if (fifoCheck.length > 0) {
            // console.log("Out of fifo", {
            //     av: n.av,
            //     rn: n.runningNr,
            //     fRn: fifoCheck[0].runningNr,
            //     dates: [fifoCheck[0].prodDate, n.prodDate],
            // });
        }

        return {
            ...n,
            // currentInv: fifoCheck[0],
            fifoFollowed: fifoCheck.length === 0 ? true : false,
        };
    });

    /**
     * lets see just the av that is our or in
     */

    const avCheck = (check: any) => {
        /**
         * This will only return the data based on out of fifo.
         */
        // check how many times each av showed up
        const avCounts = check.reduce((a: any, c: any) => {
            if (c.fifoFollowed === false) {
                const avValue = c.av;
                a[avValue] = (a[avValue] || 0) + 1;
            }
            return a;
        }, {});

        // transform them back to an avCount Object
        const result = Object.keys(avCounts).map((av) => ({
            av: parseInt(av, 10),
            count: avCounts[av],
        }));

        return result;
    };

    const outOfFifo: any = avCheck(check);
    const totalOut = outOfFifo.reduce((sum: any, c: any) => {
        return sum + c.count;
    }, 0);

    /**
     * add the data to the db
     */
    for (let i = 0; i < check.length; i++) {
        const { data: dbInsert, error: dbE } = await tryCatch(
            db
                .insert(fifoIndex)
                .values({
                    lot: check[i].lot,
                    av: check[i].av,
                    runningNr: check[i].runningNr,
                    prodDate: check[i].prodDate,
                    fifoFollowed: check[i].fifoFollowed,
                    add_Date: check[i].add_Date,
                })
                .onConflictDoNothing()
        );
    }

    return {
        success: true,
        message: "Fifo index data",
        data: {
            palletsOut: check,
            totalShipped: shipped?.data.length,
            inFifo: shipped?.data.length - totalOut,
            outOfFifoData: outOfFifo,
        },
    };
}
