import XLSX from "xlsx";
import { excelDateStuff } from "../../../../utils/excelDateStuff.js";
import { tryCatch } from "../../../../../../globalUtils/tryCatch.js";
import { db } from "../../../../../../../database/dbclient.js";
import { settings } from "../../../../../../../database/schema/settings.js";
import { query } from "../../../../../sqlServer/prodSqlServer.js";
import { bulkOrderArticleInfo } from "../../../../../sqlServer/querys/dm/bulkOrderArticleInfo.js";
import { addDays, addHours, isAfter, parse } from "date-fns";
import { orderState } from "../../../../../sqlServer/querys/dm/orderState.js";
import { postOrders } from "../postOrders.js";

// customeris/articles stuff will be in basis once we move to iowa
let customerID = 8;
let invoiceID = 9;
let 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.
     */

    const { data: s, error: e } = await tryCatch(db.select().from(settings));

    if (e) {
        return {
            sucess: false,
            message: `Error getting settings`,
            data: e,
        };
    }

    // articleInfo
    const { data: article, error: ae } = await tryCatch(
        query(
            bulkOrderArticleInfo.replace("[articles]", articles),
            "Get Article data for bulk orders"
        )
    );
    const a: any = article?.data;
    if (ae) {
        return {
            sucess: false,
            message: `Error getting article data`,
            data: ae,
        };
    }

    // order state
    const { data: o, error: oe } = await tryCatch(
        query(orderState, "Gets the next 500 orders that have not been started")
    );

    const openOrders: any = o?.data;

    if (oe) {
        return {
            sucess: false,
            message: `Error getting article data`,
            data: oe,
        };
    }

    const plantToken = s.filter((s) => s.name === "plantToken");

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

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

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

    // 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: plantToken[0].value,
        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;

    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:
                o.newton8oz.replace(/\s+/g, "") !== ""
                    ? o.newton8oz.replace(/\s+/g, "")
                    : o.newton10oz.replace(/\s+/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,
        }));

    // 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(o.date, new Date().toISOString());
    });

    // last map to remove orders that have already been started
    // correctedOrders = correctedOrders.filter((oo: any) =>
    //     oOrders.some((o: any) => o.CustomerOrderNumber === oo.po)
    // );
    let postedOrders: any = [];
    const filterOrders: any = correctedOrders;
    filterOrders.forEach((oo: any) => {
        const isMatch = openOrders.some(
            (o: any) => String(o.po).trim() === String(oo.po).trim()
        );
        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) => {
        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: 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
                },
            ],
        };
    });

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

    //console.log(updatedPredefinedObject);
    // post the orders to the server
    const posting = await postOrders(updatedPredefinedObject, user);
    //console.log(posting);

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