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

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

async function getAll(params) {
  try {
    const filterConditions = {};
    if (params.doc_id) {
      filterConditions.id = params.doc_id;
    }
    const salesTargets = await dbSAPPS.SalesTarget.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.SalesTargetDetail,
          as: "salestargetdetails",
          include: [
            {
              model: dbSAPPS.Item,
              as: "item",
              attributes: ["id", "display_name"],
            },
          ]
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["id", "display_name"],
        },
        {
          model: dbSAPPS.Period,
          as: "period",
          attributes: ["id", "display_name"],
        },
        {
          model: dbSAPPS.Territory,
          as: "territory",
          attributes: ["id", "display_name"],
        }
      
      ],
    });

    return {
      salesTargets,
      success: true,
      message: "Sales Targets loaded successfully!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to load Sales Targets!";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

async function filter(params) {
  const filterConditions = {};
  if(params.period_id) {
    filterConditions.period_id = {
      [Op.like]: `%${params.period_id}%`,
    };
  }

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

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


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

  try {
    const salesTargets = await dbSAPPS.SalesTarget.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]], // Opsional: Mengurutkan hasil berdasarkan kolom 'modified'
      include: [
        {
          model: dbSAPPS.SalesTargetDetail,
          as: "salestargetdetails",
          include: [
            {
              model: dbSAPPS.Item,
              as: "item",
              attributes: ["id", "display_name"],
            },
          ]
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["id", "display_name"],
        },
        {
          model: dbSAPPS.Period,
          as: "period",
          attributes: ["id", "display_name"],
        },
        {
          model: dbSAPPS.Territory,
          as: "territory",
          attributes: ["id", "display_name"],
        }
      
      ],
      
    });

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

async function option() {
  try {
    const udks = await dbSAPPS.SalesTarget.findAll({
      attributes: ["id", "name"],
      where: { enabled: true },
      order: [["name", "ASC"]],
      include: [
        {
          model: dbSAPPS.SalesTargetDetail,
          as: "udkproducts",
          attributes: [
            "id",
            "name",
            "item_code",
            "sku_code",
            "batch",
            "principal",
            "ed_stock",
            "stock_qty",
            "arrival_date",
            "price",
            "order_qty",
            "discount",
            "disc_elr",
            "discount_price",
            "total_product",
          ],
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["name"],
        },
      ],
    });

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

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

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

async function create(params) {
  const transaction = await dbSAPPS.sequelize.transaction();
  try {

    // cek existing data
    const existingData = await dbSAPPS.SalesTarget.findOne({
      where: {
        territory_id: params.territory_id,
        period_id: params.period_id,
        company_id: params.company_id
      }
    })

    if (existingData) {
      return {
        success: false,
        message: "Data Sales Target already exists!",
      };
    }

    // Set default value untuk enabled
    if (!params.enabled) params.enabled = true;

    // Buat Target baru
    const salesTarget = await dbSAPPS.SalesTarget.create(params, {transaction,});

    // Proses target details
    if (params.salestargetdetails) {
      // Pastikan data adalah array
      if (typeof params.salestargetdetails === "string") {
        params.salestargetdetails = JSON.parse(params.salestargetdetails);
      }

      // Validasi dan persiapkan data untuk bulkCreate
      const targetDetailData = params.salestargetdetails.map((product) => {
        // Validasi field yang diperlukan
        if (!product.item_id) {
          throw new Error("Missing required fields in product list.");
        }

        return {
          ...product,
          creation: Date.now(),
          modified: Date.now(),
          modified_by: params.modified_by,
          owner: params.owner,
          salestarget_id: salesTarget.id,
        };
      });

      // Lakukan bulkCreate
      await dbSAPPS.SalesTargetDetail.bulkCreate(targetDetailData, {transaction,});  
    }

    // Commit transaksi jika semua berhasil
    await transaction.commit();

    return {
      success: true,
      message: "Data sales target has been successfully added!",
    };
  } catch (error) {
    // Rollback transaksi jika terjadi kesalahan
    await transaction.rollback();
    const errorMessage =
      error.message || "An error occurred during sales target creation.";
    console.error("Error creating sales target:", error); // Log kesalahan untuk debugging
    return {
      success: false,
      message: errorMessage,
    };
  }
}

async function update(id, params) {
  const transaction = await dbSAPPS.sequelize.transaction();
  try {
    // Check if the sales target exists
    const salesTarget = await dbSAPPS.SalesTarget.findByPk(id);
    if (!salesTarget) {
      return {
        success: false,
        message: "Sales Target not found!",
      };
    }

    // Update sales target data
    await salesTarget.update(params, { transaction });

    // Process target details
    if (params.salestargetdetails) {
      // Ensure data is an array
      if (typeof params.salestargetdetails === "string") {
        params.salestargetdetails = JSON.parse(params.salestargetdetails);
      }

      // Validate and prepare data for bulk update
      const targetDetailData = params.salestargetdetails.map((product) => {
        if (!product.item_id) {
          throw new Error("Missing required fields in product list.");
        }
        return {
          ...product,
          modified: Date.now(),
          modified_by: params.modified_by,
          owner: params.owner,
          salestarget_id: salesTarget.id,
        };
      });

      // Delete existing sales target details
      await dbSAPPS.SalesTargetDetail.destroy({
        where: { salestarget_id: salesTarget.id },
        transaction,
      });

      // Perform bulkCreate to add new details
      await dbSAPPS.SalesTargetDetail.bulkCreate(targetDetailData, {
        transaction,
      });
    }

    // Commit the transaction if all goes well
    await transaction.commit();

    return {
      success: true,
      message: "Sales target has been successfully updated!",
    };
  } catch (error) {
    // Rollback the transaction in case of errors
    await transaction.rollback();
    const errorMessage =
      error.message || "An error occurred during sales target update.";
    console.error("Error updating sales target:", error);
    return {
      success: false,
      message: errorMessage,
    };
  }
}


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

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

async function _delete(id) {
    const transaction = await dbSAPPS.sequelize.transaction();
    try {
        const salesTarget = await dbSAPPS.SalesTarget.findByPk(id, { transaction });
        if (!salesTarget) return { success: false, message: 'Sales Target not found!' };
      
        await salesTarget.destroy({ transaction });

        await transaction.commit();
        return {
            success: true,
            message: `Sales Target successfully deleted!`
        };
    } catch (error) {
        const errorMessage = error.message || `Failed to delete Sales Target!`;
        return {
            success: false,
            message: errorMessage,
        };
    }
}
