import { db } from "../../../../../database/dbclient.js";
import { tryCatch } from "../../../../globalUtils/tryCatch.js";
import { query } from "../../../sqlServer/prodSqlServer.js";
import { siloQuery } from "../../../sqlServer/querys/silo/siloQuery.js";
import { postAdjustment } from "./postAdjustment.js";
import { siloAdjustments } from "../../../../../database/schema/siloAdjustments.js";
import { greetingStuff } from "../../../../globalUtils/greetingEmail.js";
import { sendEmail } from "../../../notifications/controller/sendMail.js";
import { settings } from "../../../../../database/schema/settings.js";
import { generateOneTimeKey } from "../../../../globalUtils/singleUseKey.js";
import { eq } from "drizzle-orm";
import {
    getSettings,
    serverSettings,
} from "../../../server/controller/settings/getSettings.js";

export const createSiloAdjustment = async (
    data: any | null,
    user: any | null
) => {
    /**
     * Creates a silo adjustment based off warehouse, location, and qty.
     * qty will come from the hmi, prolink, or silo patrol
     */
    // const { data: set, error: setError } = await tryCatch(
    //     db.select().from(settings)
    // );

    // const { data: set, error: setError } = await tryCatch(getSettings());

    // if (setError) {
    //     return {
    //         success: false,
    //         message: `There was an error getting setting data to post to the server.`,
    //         data: setError,
    //     };
    // }

    const set = serverSettings.length === 0 ? [] : serverSettings;
    // getting stock data first so we have it prior to the adjustment
    const { data: s, error: stockError } = await tryCatch(
        query(siloQuery, "Silo data Query")
    );

    if (stockError) {
        return {
            success: false,
            message: `There was an error getting stock data to post to the server.`,
            data: stockError,
        };
    }
    const stock: any = s?.data as any;
    const { data: a, error: errorAdj } = await tryCatch(
        postAdjustment(data, user.prod)
    );

    if (errorAdj) {
        return {
            success: false,
            message: `There was an error doing the silo adjustment.`,
            data: errorAdj,
        };
    }
    /**
     * Checking to see the difference, and send email if +/- 5% will change later if needed
     */

    const sa: any = a;

    if (!sa.success) {
        console.log(`insde error`);
        return {
            success: sa.success,
            message: sa.message,
            data: sa.data,
        };
    }

    const stockNummy = stock.filter((s: any) => s.LocationID === data.laneId);
    const theDiff =
        ((data.quantity - stockNummy[0].Stock_Total) /
            ((data.quantity + stockNummy[0].Stock_Total) / 2)) *
        100;

    /**
     * Post the data to our db.
     */

    //console.log(stockNummy);
    const { data: postAdj, error: postAdjError } = await tryCatch(
        db
            .insert(siloAdjustments)
            .values({
                warehouseID: data.warehouseId,
                locationID: data.laneId,
                currentStockLevel: stockNummy[0].Stock_Total,
                newLevel: data.quantity,
                lastDateAdjusted: new Date(stockNummy[0].LastAdjustment),
                add_user: user.username,
            })
            .returning({ id: siloAdjustments.siloAdjust_id })
    );

    if (postAdjError) {
        //console.log(postAdjError);
        return {
            success: false,
            message: `There was an error posting the new adjustment.`,
            data: postAdjError,
        };
    }
    let adj: any = a;
    if (Math.abs(theDiff) > 5) {
        // console.log(`Send for comment due to being: ${theDiff.toFixed(2)}%`);
        const server = set.filter((n: any) => n.name === "server");

        const port = set.filter((n: any) => n.name === "serverPort");
        const key = await generateOneTimeKey();
        const updateKey = await db
            .update(siloAdjustments)
            .set({ commentKey: key })
            .where(eq(siloAdjustments.siloAdjust_id, postAdj[0].id));

        const emailSetup = {
            email: user.email,
            subject: `Alert - Siloadjustment was done with a descrepancy of 5% or greater`,
            template: "siloAdjustmentComment",
            context: {
                greeting: await greetingStuff(),
                siloName: stockNummy[0].Description,
                variance: `${theDiff.toFixed(2)}%`,
                currentLevel: stockNummy[0].Stock_Total,
                newLevel: data.quantity,
                variancePer: 5,
                adjustID: `${postAdj[0].id}&${key}`,
                server: server[0].value,
                port: port[0].value,
            },
        };

        //console.log(emailSetup);

        await sendEmail(emailSetup);
        return {
            success: adj.success,
            message: `Silo adjustmnet was completed you will also receive and email due to the adjustment having a variation of ${Math.abs(
                theDiff
            ).toFixed(2)}%`,
            data: adj.data,
        };
    } else {
        return { success: adj.success, message: adj.message, data: adj.data };
    }
};
