const { Op } = require("sequelize");
const dbSAPPS = require("../../helpers/db");
require("dotenv").config();

module.exports = {
    getAll,
    filter,
    option,
    count,
    create,
    update,
    enabled,
    delete: _delete,
};

async function getAll() {
    try {
        const receiptOfGoods = await dbSAPPS.ReceiptOfGood.findAll({
            order: [["modified", "DESC"]],
            include: [{
                model: dbSAPPS.Company,
                as: 'company',
                required: false,
            }],
        });

        return {
            receiptOfGoods,
            success: true,
            message: "receipt of goods loaded successfully!",
        };
    } catch (error) {
        const errorMessage = error.message || "Failed to load receipt of goods!";
        return {
            success: false,
            message: errorMessage,
        };
    }
}

async function filter(params) {
    const filterConditions = {};

    if (params.code) {
        filterConditions.code = {
            [Op.like]: `%${params.code}%`,
        };
    }

    if (params.display_name) {
        filterConditions.display_name = {
            [Op.like]: `%${params.display_name}%`,
        };
    }

    if (params.enabled) {
        filterConditions.enabled = {
            [Op.eq]: params.enabled === "1" ? true : false,
        };
    }

    try {
        const receiptOfGoods = await dbSAPPS.ReceiptOfGood.findAll({
            where: filterConditions,
            order: [["modified", "DESC"]],
        });

        return {
            success: true,
            receiptOfGoods,
            message: "receipt of goods loaded successfully!",
        };
    } catch (error) {
        const errorMessage = error.message || "Failed to retrieve receipt of goods. Please try again later.";
        return {
            success: false,
            message: errorMessage,
        };
    }
}

async function option() {
    try {
        const receiptOfGoods = await dbSAPPS.ReceiptOfGood.findAll({
            attributes: ["id", "code", "display_name"],
            where: { enabled: true },
            order: [["display_name", "ASC"]],
        });

        return {
            success: true,
            receiptOfGoods,
            message: "receipt of goods loaded successfully!",
        };
    } catch (error) {
        const errorMessage = error.message || "Failed to retrieve receipt of goods. Please try again later.";
        return {
            success: false,
            message: errorMessage,
        };
    }
}

async function count() {
    try {
        const count = await dbSAPPS.ReceiptOfGood.count({
            where: { enabled: true },
        });

        return {
            success: true,
            count,
            message: "receipt of goods loaded successfully!",
        };
    } catch (error) {
        const errorMessage = error.message || "Failed to retrieve receipt of goods. Please try again later.";
        return {
            success: false,
            message: errorMessage,
        };
    }
}

async function create(params) {
    try {
        if (!params.material_request_name || !params.purchase_order_name || !params.received_date || !params.item_code || !params.item_name)
            return {
                success: false,
                message: "material request name, purchase order name, received date, item code, and item name are required!",
            };

        const existing = await dbSAPPS.ReceiptOfGood.findOne({
            where: {
                material_request_name: params.material_request_name,
                purchase_order_name: params.purchase_order_name,
                received_date: params.received_date,
                item_code: params.item_code,
                item_name: params.item_name
            },
        });

        if (existing)
            return {
                success: false,
                message: `receipt of goods with material request name "${params.material_request_name}", purchase order name "${params.purchase_order_name}", received date "${params.received_date}", item code "${params.item_code}", and item name "${params.item_name}" is already taken.`,
            };

        if (!params.enabled) params.enabled = true;
        await dbSAPPS.ReceiptOfGood.create(params);
        return {
            success: true,
            message: "receipt of goods data has been successfully added!",
        };
    } catch (error) {
        const errorMessage = error.message || "An error occurred during create receipt of goods processing.";
        return {
            success: false,
            message: errorMessage,
        };
    }
}

async function update(id, params) {
    try {
        const receiptOfGood = await dbSAPPS.ReceiptOfGood.findByPk(id);
        if (!receiptOfGood)
            return {
                success: false,
                message: "receipt of goods not found!",
            };


        const existing = await dbSAPPS.ReceiptOfGood.findOne({
            where: {
                material_request_name: params.material_request_name,
                purchase_order_name: params.purchase_order_name,
                received_date: params.received_date,
                item_code: params.item_code,
                item_name: params.item_name
            }
        });
        
        if (existing) {
            if (existing.id != params.id) {
                return {
                    success: false,
                    message: `receipt of goods with material request name "${params.material_request_name}", purchase order name "${params.purchase_order_name}", received date "${params.received_date}", item code "${params.item_code}", and item name "${params.item_name}" is already taken.`,
                };
            }
        }

        await receiptOfGood.update(params);
        return {
            success: true,
            message: "Data receipt of goods has been saved!",
        };
    } catch (error) {
        const errorMessage = error.message || "Failed to update receipt of goods data.";
        return {
            success: false,
            message: errorMessage,
        };
    }
}

async function enabled(id, params) {
    try {
        const receiptOfGood = await dbSAPPS.ReceiptOfGood.findByPk(id);
        if (!receiptOfGood)
            return {
                success: false,
                message: "receipt of goods not found!",
            };

        const updateData = {};
        updateData.enabled = params.enabled;
        if (params.modified_by) updateData.modified_by = params.modified_by;
        if (params.modified) updateData.modified = params.modified;

        await receiptOfGood.update(updateData);

        return {
            success: true,
            message: "receipt of goods has been updated!",
        };
    } catch (error) {
        const errorMessage = error.message || "Failed to update receipt of goods.";
        return {
            success: false,
            message: errorMessage,
        };
    }
}

async function _delete(id) {
    try {
        const receiptOfGood = await dbSAPPS.ReceiptOfGood.findByPk(id);
        if (!receiptOfGood) return { success: false, message: "receipt of goods not found!" };

        await receiptOfGood.destroy();
        return {
            success: true,
            message: "Receipt of goods successfully deleted!",
        };
    } catch (error) {
        const errorMessage = error.message || "Failed to delete receipt of goods.";
        return {
            success: false,
            message: errorMessage,
        };
    }
}

