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

module.exports = {
  getAll,
  option,
  count,
  create,
  update,
  enabled,
  delete: _delete,
};
const formatWithModifier = async (tenderPaymentTerms) => {
  return Promise.all(
    tenderPaymentTerms.map(async (tenderPaymentTerm) => {
      const modifier = await dbSAPPS.User.findOne({
        where: {
          id: tenderPaymentTerm.modified_by,
        },
        attributes: ["full_name"],
      });

      return {
        ...tenderPaymentTerm,
        modifier: modifier?.full_name,
      };
    })
  );
};

async function getAll(params) {
  try {
    // filter
    const filterConditions = {};
    let tenderPaymentTerms = [];
    tenderPaymentTerms = await dbSAPPS.TenderPaymentTerm.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]],
    });

    tenderPaymentTerms = tenderPaymentTerms.map((tenderPaymentTerm) => {
      return {
        ...tenderPaymentTerm.dataValues
      };
    });

    tenderPaymentTerms = await formatWithModifier(tenderPaymentTerms);

    return {
      tenderPaymentTerms,
      success: true,
      message: "Tender payment terms loaded successfully!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to load tender payment terms!";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

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

    return {
      success: true,
      tenderPaymentTerms,
      message: "Tender Payment Terms loaded successfully!",
    };
  } catch (error) {
    console.error("Error retrieving Tender Payment Terms: ", error);
    const errorMessage =
      error.message || "Failed to retrieve Tender Payment Terms. Please try again later.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

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

    return {
      success: true,
      count,
      message: "Tender Payment Terms count loaded successfully!",
    };
  } catch (error) {
    console.error("Error counting Tender Payment Terms: ", error);
    return {
      success: false,
      message: "Failed to retrieve tenderPaymentTerms count. Please try again later.",
    };
  }
}

async function create(params) {
  const transaction = await dbSAPPS.sequelize.transaction();
  try {
    // validate existing
    const existingDisplayName = await dbSAPPS.TenderPaymentTerm.findOne({
      where: { display_name: params.display_name },
      transaction,
    });
    if (existingDisplayName) {
      return {
        success: false,
        message: `"${params.display_name}" is already taken.`,
      };
    }

    if (!params.enabled) params.enabled = true;

    // save
    await dbSAPPS.TenderPaymentTerm.create(params, { transaction });

    await transaction.commit();
    return {
      success: true,
      message: "Saved successfully!",
    };
  } catch (error) {
    await transaction.rollback();
    const errorMessage = error?.message || "Failed to save, please try again!";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

async function update(id, params) {
  try {
    const tenderPaymentTerm = await dbSAPPS.TenderPaymentTerm.findByPk(id);
    if (!tenderPaymentTerm)
      return {
        success: false,
        message: "Tender Payment Term not found!",
      };

    if (params.display_name && params.display_name !== tenderPaymentTerm.display_name) {
      const existingTenderPaymentTermName = await dbSAPPS.TenderPaymentTerm.findOne({
        where: { display_name: params.display_name },
      });
      if (existingTenderPaymentTermName) {
        return {
          success: false,
          message: `Tender Payment Term name "${params.display_name}" is already taken. Try again!`,
        };
      }
    }

    await tenderPaymentTerm.update(params);

    return {
      success: true,
      message: "Data tender payment term has been saved!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update tender payment term data.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

async function enabled(id, params) {
  try {
    const tenderPaymentTerm = await dbSAPPS.TenderPaymentTerm.findByPk(id);
    if (!tenderPaymentTerm)
      return {
        success: false,
        message: "Tender Payment Term 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 tenderPaymentTerm.update(updateData);

    return {
      success: true,
      message: "Tender Payment Term has been updated!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update tender payment term.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

async function _delete(id) {
  try {
    const tenderPaymentTerm = await dbSAPPS.TenderPaymentTerm.findByPk(id);
    if (!tenderPaymentTerm) return { success: false, message: "Tender Payment Term not found!" };

    await tenderPaymentTerm.destroy();

    return {
      success: true,
      message: "Tender Payment Term successfully deleted!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to delete tender payment term.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
