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

module.exports = {
  getAll,
  getDistOutlet,
  getDistItem,
  getDistBranch,

  filter,
  filterDistOutlet,
  filterDistItem,
  filterDistBranch,

  option,
  count,

  create,
  createDistOutlet,
  createDistItem,
  createDistBranch,

  update,
  updateDistOutlet,
  updateDistItem,
  updateDistBranch,

  enabled,
  distOutletenabled,
  distItemenabled,
  distBranchenabled,

  delete: _delete,
  deleteDistOutlet,
  deleteDistItem,
  deleteDistBranch,
};

// DISTRIBUTOR
async function getAll() {
  try {
    const distributors = await dbSAPPS.Distributor.findAll({
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["id", "display_name"],
        },
      ]
    });

    return {
      distributors,
      success: true,
      message: "distributors loaded successfully!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to load distributors!";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function filter(params) {
  const filterConditions = {};

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

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

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

  if (params.enabled) {
    filterConditions.enabled = {
      [Op.eq]: params.enabled === "1" ? true : false,
    };
  }
  try {
    const distributors = await dbSAPPS.Distributor.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]], 
      include: [
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["id", "display_name"],
        },
      ]
    });

    return {
      success: true,
      distributors,
      message: "distributors loaded successfully!",
    };
  } catch (error) {
    console.error("Error retrieving distributors: ", error);
    const errorMessage =
      error.message || "Failed to retrieve distributors. Please try again later.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function option() {
  try {
    const distributors = await dbSAPPS.Distributor.findAll({
      attributes: ["id", "display_name", "code"],
      where: { enabled: true },
      order: [["display_name", "ASC"]],
      include: [
          {
            model: dbSAPPS.DistributorBranch,
            as: "branches",
            attributes: ["id", "display_name", "code", "email_address1", "email_address2" ],
          },
      ]
    });

    return {
      success: true,
      distributors,
      message: "distributors loaded successfully!",
    };
  } catch (error) {
    console.error("Error retrieving distributors: ", error);
    const errorMessage =
      error.message || "Failed to retrieve distributors. Please try again later.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function count() {
  try {
    const count = await dbSAPPS.Distributor.count({
      where: { enabled: true },
    });

    return {
      success: true,
      count,
      message: "distributors loaded successfully!",
    };
  } catch (error) {
    console.error("Error counting distributors: ", error);
    return {
      success: false,
      message: "Failed to retrieve distributors count. Please try again later.",
    };
  }
}
async function create(params) {
  try {
    if (!params.display_name)
      return {
        success: false,
        message: "distributors name is required!",
      };

    const existingNameNNumber = await dbSAPPS.Distributor.findOne({
      where: {
        display_name: params.display_name,
        code: params.code,
        company_id: params.company_id,
      },
    });
    if (existingNameNNumber)
      return {
        success: false,
        message: `Distributor name "${params.display_name}", code "${params.code}",  is already taken.`,
      };

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

    const newdistributors = await dbSAPPS.Distributor.create(params);

    return {
      success: true,
      message: "Distributor data has been successfully added!",
      distributors: newdistributors,
    };
  } catch (error) {
    const errorMessage =
      error.message || "An error occurred during create distributors processing.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function update(id, params) {
  try {
    const distributors = await dbSAPPS.Distributor.findByPk(id);
    if (!distributors)
      return {
        success: false,
        message: "distributors not found!",
      };

    if (params.display_name && params.display_name !== distributors.display_name && params.code && params.code !== distributors.company_id && params.company_id && params.company_id !== distributors.company_id) {
      const existingNameNNumber = await dbSAPPS.Distributor.findOne({
        where: {
          display_name: params.display_name,
          code: params.code,
          company_id: params.company_id,
        },
      });
      if (existingNameNNumber)
        return {
          success: false,
          message: `Distributor name "${params.display_name}", code "${params.code}",  is already taken.`,
        };
      }

    await distributors.update(params);

    return {
      success: true,
      message: "Data distributors has been saved!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update distributors data.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function _delete(id) {
  try {
    const distributors = await dbSAPPS.Distributor.findByPk(id);
    if (!distributors) return { success: false, message: "distributors not found!" };

    await distributors.destroy();

    return {
      success: true,
      message: "distributors successfully deleted!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to delete distributors.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function enabled(id, params) {
  try {
    const distributors = await dbSAPPS.Distributor.findByPk(id);
    if (!distributors)
      return {
        success: false,
        message: "distributors 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 distributors.update(updateData);

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


// DISTRIBUTOR OUTLET
async function getDistOutlet() {
  try {
    const distributorOutlet = await dbSAPPS.DistributorOutlet.findAll({
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.Distributor,
          as: "distributor",
          attributes: ["id", "display_name"],
        },
        {
          model: dbSAPPS.Outlet,
          as: "outlet",
          attributes: ["id", "display_name"],
        }
      ]
    });

    return {
      distributorOutlet,
      success: true,
      message: "distributor outlet loaded successfully!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to load distributor outlet!";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function filterDistOutlet(params) {
  const filterConditions = {};

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

  if (params.enabled) {
    filterConditions.enabled = {
      [Op.eq]: params.enabled === "1" ? true : false,
    };
  }
  try {
    const distributorOutlet = await dbSAPPS.DistributorOutlet.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]], 
      include: [
        {
          model: dbSAPPS.Distributor,
          as: "distributor",
          attributes: ["id", "display_name"],
        },
        {
          model: dbSAPPS.Outlet,
          as: "outlet",
          attributes: ["id", "display_name"],
        }
      ]
    });

    return {
      success: true,
      distributorOutlet,
      message: "distributor outlet loaded successfully!",
    };
  } catch (error) {
    console.error("Error retrieving distributor outlet: ", error);
    const errorMessage =
      error.message || "Failed to retrieve distributor outlet. Please try again later.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function createDistOutlet(params) {
  try {
    const existingNameNNumber = await dbSAPPS.DistributorOutlet.findOne({
      where: {
        distributor_id: params.distributor_id,
        display_name: params.display_name,
        code: params.code,
      },
    });

    if (existingNameNNumber)
      return {
        success: false,
        message: `Distributor outlet name "${params.display_name}", code "${params.code}", is already taken.`,
      };

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

    const newdistributors = await dbSAPPS.DistributorOutlet.create(params);

    return {
      success: true,
      message: "Distributor oulet data has been successfully added!",
      distributors: newdistributors,
    };
  } catch (error) {
    const errorMessage =
      error.message || "An error occurred during create distributor outlets processing.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function updateDistOutlet(id, params) {
  try {
    const distributorOutlet = await dbSAPPS.DistributorOutlet.findByPk(id);
    if (!distributorOutlet)
      return {
        success: false,
        message: "distributor outlets not found!",
      };

    if (params.display_name && params.display_name !== distributorOutlet.display_name && params.code && params.code !== distributorOutlet.code && params.distributor_id && params.distributor_id !== distributorOutlet.distributor_id) {
      const existingNameNNumber = await dbSAPPS.Distributor.findOne({
        where: {
          display_name: params.display_name,
          code: params.code,
          distributor_id: params.distributor_id
        },
      });
      if (existingNameNNumber)
        return {
          success: false,
          message: `Distributor name "${params.display_name}", code "${params.code}",  is already taken.`,
        };
      }

    await distributorOutlet.update(params);

    return {
      success: true,
      message: "Data distributor outlet has been saved!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update distributor outlet data.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function distOutletenabled(id, params) {
  try {
    const distributorOutlet = await dbSAPPS.DistributorOutlet.findByPk(id);
    if (!distributorOutlet)
      return {
        success: false,
        message: "distributorOutlet 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 distributorOutlet.update(updateData);

    return {
      success: true,
      message: "distributor outlet has been updated!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update distributor outlet.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function deleteDistOutlet(id) {
  try {
    const distributorOutlet = await dbSAPPS.DistributorOutlet.findByPk(id);
    if (!distributorOutlet) return { success: false, message: "distributor outlet not found!" };

    await distributorOutlet.destroy();

    return {
      success: true,
      message: "distributor outlet successfully deleted!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to delete distributor outlet.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}


// DISTRIBUTOR ITEM
async function getDistItem() {
  try {
    const distributorItem = await dbSAPPS.DistributorProduct.findAll({
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.Distributor,
          as: "distributor",
          attributes: ["id", "display_name"],
        },
        {
          model: dbSAPPS.Item,
          as: "item",
          attributes: ["id", "display_name"],
        }
      ]
    });

    return {
      distributorItem,
      success: true,
      message: "distributor item loaded successfully!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to load distributor item!";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function filterDistItem(params) {
  const filterConditions = {};

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

  if (params.enabled) {
    filterConditions.enabled = {
      [Op.eq]: params.enabled === "1" ? true : false,
    };
  }
  try {
    const distributorItem = await dbSAPPS.DistributorProduct.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]], 
      include: [
        {
          model: dbSAPPS.Distributor,
          as: "distributor",
          attributes: ["id", "display_name"],
        },
        {
          model: dbSAPPS.Item,
          as: "item",
          attributes: ["id", "display_name"],
        }
      ]
    });

    return {
      success: true,
      distributorItem,
      message: "distributor item loaded successfully!",
    };
  } catch (error) {
    console.error("Error retrieving distributor item: ", error);
    const errorMessage =
      error.message || "Failed to retrieve distributor item. Please try again later.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function createDistItem(params) {
  try {
    const existingNameNNumber = await dbSAPPS.DistributorProduct.findOne({
      where: {
        distributor_id: params.distributor_id,
        display_name: params.display_name,
        code: params.code,
      },
    });

    if (existingNameNNumber)
      return {
        success: false,
        message: `Distributor item name "${params.display_name}", code "${params.code}", is already taken.`,
      };

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

    const newdistributors = await dbSAPPS.DistributorProduct.create(params);

    return {
      success: true,
      message: "Distributor item data has been successfully added!",
      distributorItems: newdistributors,
    };
  } catch (error) {
    const errorMessage =
      error.message || "An error occurred during create distributor items processing.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function updateDistItem(id, params) {
  try {
    const distributorItem = await dbSAPPS.DistributorProduct.findByPk(id);
    if (!distributorItem)
      return {
        success: false,
        message: "distributor items not found!",
      };

    if (params.display_name && params.display_name !== distributorItem.display_name && params.code && params.code !== distributorItem.code && params.distributor_id && params.distributor_id !== distributorItem.distributor_id) {
      const existingNameNNumber = await dbSAPPS.Distributor.findOne({
        where: {
          display_name: params.display_name,
          code: params.code,
          distributor_id: params.distributor_id
        },
      });
      if (existingNameNNumber)
        return {
          success: false,
          message: `Distributor item name "${params.display_name}", code "${params.code}",  is already taken.`,
        };
      }

    await distributorItem.update(params);

    return {
      success: true,
      message: "Data distributor item has been saved!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update distributor item data.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function distItemenabled(id, params) {
  try {
    const distributorItem = await dbSAPPS.DistributorProduct.findByPk(id);
    if (!distributorItem)
      return {
        success: false,
        message: "distributorItem 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 distributorItem.update(updateData);

    return {
      success: true,
      message: "distributor item has been updated!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update distributor item.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function deleteDistItem(id) {
  try {
    const distributorItem = await dbSAPPS.DistributorProduct.findByPk(id);
    if (!distributorItem) return { success: false, message: "distributor item not found!" };

    await distributorItem.destroy();

    return {
      success: true,
      message: "distributor item successfully deleted!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to delete distributor item.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

// DISTRIBUTOR BRANCH
async function getDistBranch() {
  try {
    const distributorBranch = await dbSAPPS.DistributorBranch.findAll({
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.Distributor,
          as: "distributor",
          attributes: ["id", "display_name"],
        },
      ]
    });

    return {
      distributorBranch,
      success: true,
      message: "distributor branch loaded successfully!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to load distributor branch!";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function filterDistBranch(params) {
  const filterConditions = {};

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

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

  if (params.enabled) {
    filterConditions.enabled = {
      [Op.eq]: params.enabled === "1" ? true : false,
    };
  }
  try {
    const distributorBranch = await dbSAPPS.DistributorBranch.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]], 
      include: [
        {
          model: dbSAPPS.Distributor,
          as: "distributor",
          attributes: ["id", "display_name"],
        },
      ]
    });

    return {
      success: true,
      distributorBranch,
      message: "distributor branch loaded successfully!",
    };
  } catch (error) {
    console.error("Error retrieving distributor branch: ", error);
    const errorMessage =
      error.message || "Failed to retrieve distributor branch. Please try again later.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function createDistBranch(params) {
  try {
    const existingNameNumber = await dbSAPPS.DistributorBranch.findOne({
      where: {
        distributor_id: params.distributor_id,
        display_name: params.display_name,
        code: params.code,
      },
    });

    if (existingNameNumber)
      return {
        success: false,
        message: `Distributor branch name "${params.display_name}", code "${params.code}", is already taken.`,
      };

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

    const newdistributors = await dbSAPPS.DistributorBranch.create(params);

    return {
      success: true,
      message: "Distributor branch data has been successfully added!",
      distributorBranch: newdistributors,
    };
  } catch (error) {
    const errorMessage =
      error.message || "An error occurred during create distributor branch processing.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function updateDistBranch(id, params) {
  try {
    const distributorBranch = await dbSAPPS.DistributorBranch.findByPk(id);
    if (!distributorBranch)
      return {
        success: false,
        message: "distributor branchs not found!",
      };

    if (params.display_name && params.display_name !== distributorBranch.display_name && params.code && params.code !== distributorBranch.code && params.distributor_id && params.distributor_id !== distributorBranch.distributor_id) {
      const existingNameNNumber = await dbSAPPS.Distributor.findOne({
        where: {
          display_name: params.display_name,
          code: params.code,
          distributor_id: params.distributor_id
        },
      });
      if (existingNameNNumber)
        return {
          success: false,
          message: `Distributor branch name "${params.display_name}", code "${params.code}",  is already taken.`,
        };
      }

    await distributorBranch.update(params);

    return {
      success: true,
      message: "Data distributor branch has been saved!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update distributor branch data.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function distBranchenabled(id, params) {
  try {
    const distributorBranch = await dbSAPPS.DistributorBranch.findByPk(id);
    if (!distributorBranch)
      return {
        success: false,
        message: "distributor branch 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 distributorBranch.update(updateData);

    return {
      success: true,
      message: "distributor branch has been updated!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to update distributor branch.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
async function deleteDistBranch(id) {
  try {
    const distributorBranch = await dbSAPPS.DistributorBranch.findByPk(id);
    if (!distributorBranch) return { success: false, message: "distributor branch not found!" };

    await distributorBranch.destroy();

    return {
      success: true,
      message: "distributor branch successfully deleted!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to delete distributor branch.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}
