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

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

async function getAll(params) {
  try {
    const filterConditions = {};
    if (params.doc_id) {
      filterConditions.id = params.doc_id;
    }
    const udks = await dbSAPPS.Udk.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.UdkProduct,
          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.User,
          as: "user",
          attributes: ["id", "email", "full_name", "phone_number"],
          include: [
            {
              model: dbSAPPS.Employee,
              as: "employee",
              attributes: ["employee_name"],
              include: [
                {
                  model: dbSAPPS.Designation,
                  as: "designation",
                  attributes: ["display_name"],
                },
              ],
            },
          ],
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["name", "display_name", "abbr"],
        },
      ],
    });

    const workflows = await dbSAPPS.Workflow.findAll({
      where: {
        doc_id: {
          [Op.in]: udks.map((item) => item.id),
        },
        doctype_id: 107,
      },
      attributes: [
        "id",
        "doc_id",
        "doctype_id",
        "status",
        "modified_by",
        "modified",
      ],
      include: [
        {
          model: dbSAPPS.WorkflowApprover,
          as: "workflowapprovers",
          attributes: [
            "id",
            "workflow_id",
            "designation_id",
            "territory_id",
            "status",
            "modified",
          ],
          include: [
            {
              model: dbSAPPS.Designation,
              as: "designation",
              attributes: ["id", "name", "display_name"],
              include: [
                {
                  model: dbSAPPS.Employee,
                  as: "employee",
                  attributes: ["id", "employee_name"],
                },
              ],
            },
            {
              model: dbSAPPS.Territory,
              as: "territory",
              attributes: ["id", "name", "display_name"],
              include: [
                {
                  model: dbSAPPS.Employee,
                  as: "employees",
                  attributes: ["id", "employee_name"],
                  include: [
                    {
                      model: dbSAPPS.Designation,
                      as: "designation",
                      attributes: ["display_name"],
                    },
                  ],
                },
              ],
            },
          ],
        },
      ],
    });

    const data = udks.map((item) => {
      const workflow = workflows.find((wf) => wf.doc_id === item.id);
      return {
        ...item.dataValues,
        workflow: workflow ? workflow.dataValues : null,
      };
    });

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

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

  if (params?.month && params?.year) {
    // Konversi bulan dan tahun menjadi rentang tanggal
    const startDate = new Date(
      `${params.year}-${params.month}-01T00:00:00.000Z`
    );
    const endDate = new Date(startDate);
    endDate.setMonth(endDate.getMonth() + 1); // Naik ke bulan berikutnya

    filterConditions.creation = {
      [Op.gte]: startDate, // Lebih besar atau sama dengan awal bulan
      [Op.lt]: endDate, // Kurang dari awal bulan berikutnya
    };
  }

  try {
    const udks = await dbSAPPS.Udk.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]], // Opsional: Mengurutkan hasil berdasarkan kolom 'modified'
      include: [
        {
          model: dbSAPPS.UdkProduct,
          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.User,
          as: "user",
          attributes: ["id", "email", "full_name", "phone_number"],
          include: [
            {
              model: dbSAPPS.Employee,
              as: "employee",
              attributes: ["employee_name"],
              include: [
                {
                  model: dbSAPPS.Designation,
                  as: "designation",
                  attributes: ["display_name"],
                },
              ],
            },
          ],
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["name", "display_name", "abbr"],
        },
      ],
    });

    const workflows = await dbSAPPS.Workflow.findAll({
      where: {
        doc_id: {
          [Op.in]: udks.map((item) => item.id),
        },
        doctype_id: 107,
      },
      attributes: [
        "id",
        "doc_id",
        "doctype_id",
        "status",
        "modified_by",
        "modified",
      ],
      include: [
        {
          model: dbSAPPS.WorkflowApprover,
          as: "workflowapprovers",
          attributes: [
            "id",
            "workflow_id",
            "designation_id",
            "territory_id",
            "status",
            "modified",
          ],
          include: [
            {
              model: dbSAPPS.Designation,
              as: "designation",
              attributes: ["id", "name", "display_name"],
              include: [
                {
                  model: dbSAPPS.Employee,
                  as: "employee",
                  attributes: ["id", "employee_name"],
                },
              ],
            },
            {
              model: dbSAPPS.Territory,
              as: "territory",
              attributes: ["id", "name", "display_name"],
              include: [
                {
                  model: dbSAPPS.Employee,
                  as: "employees",
                  attributes: ["id", "employee_name"],
                  include: [
                    {
                      model: dbSAPPS.Designation,
                      as: "designation",
                      attributes: ["display_name"],
                    },
                  ],
                },
              ],
            },
          ],
        },
      ],
    });

    let data = udks.map((item) => {
      const workflow = workflows.find((wf) => wf.doc_id === item.id);
      return {
        ...item.dataValues,
        workflow: workflow ? workflow.dataValues : null,
      };
    });

    if (params.workflowStat === "") {
      return data;
    } else if (params.workflowStat === "Approved") {
      data = data.filter((item) => {
        if (!item.workflow) {
          console.warn(`Item dengan id ${item.id} tidak memiliki workflow.`);
          return false;
        }
        return item.workflow.status === "Approved";
      });
    } else {
      // Untuk nilai selain "Approved" (dan bukan string kosong)
      data = data.filter((item) => {
        if (!item.workflow) {
          console.warn(`Item dengan id ${item.id} tidak memiliki workflow.`);
          return true;
        }
        return item.workflow.status !== "Approved";
      });
    }

    return {
      success: true,
      udks: data,
      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 filterByID(params) {
  const filterConditions = {};

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

  try {
    const udks = await dbSAPPS.Udk.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]], // Opsional: Mengurutkan hasil berdasarkan kolom 'modified'
      include: [
        {
          model: dbSAPPS.UdkProduct,
          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.User,
          as: "user",
          attributes: ["id", "email", "full_name", "phone_number"],
          include: [
            {
              model: dbSAPPS.Employee,
              as: "employee",
              attributes: ["employee_name"],
              include: [
                {
                  model: dbSAPPS.Designation,
                  as: "designation",
                  attributes: ["display_name"],
                },
              ],
            },
          ],
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["name", "display_name", "abbr"],
        },
      ],
    });

    const workflows = await dbSAPPS.Workflow.findAll({
      where: {
        doc_id: {
          [Op.in]: udks.map((item) => item.id),
        },
        doctype_id: 107,
      },
      attributes: [
        "id",
        "doc_id",
        "doctype_id",
        "status",
        "modified_by",
        "modified",
      ],
      include: [
        {
          model: dbSAPPS.WorkflowApprover,
          as: "workflowapprovers",
          attributes: [
            "id",
            "workflow_id",
            "designation_id",
            "territory_id",
            "status",
            "modified",
          ],
          include: [
            {
              model: dbSAPPS.Designation,
              as: "designation",
              attributes: ["id", "name", "display_name"],
              include: [
                {
                  model: dbSAPPS.Employee,
                  as: "employee",
                  attributes: ["id", "employee_name"],
                },
              ],
            },
            {
              model: dbSAPPS.Territory,
              as: "territory",
              attributes: ["id", "name", "display_name"],
              include: [
                {
                  model: dbSAPPS.Employee,
                  as: "employees",
                  attributes: ["id", "employee_name"],
                  include: [
                    {
                      model: dbSAPPS.Designation,
                      as: "designation",
                      attributes: ["display_name"],
                    },
                  ],
                },
              ],
            },
          ],
        },
      ],
    });

    const data = udks.map((item) => {
      const workflow = workflows.find((wf) => wf.doc_id === item.id);
      return {
        ...item.dataValues,
        workflow: workflow ? workflow.dataValues : null,
      };
    });

    // Filter data berdasarkan kondisi yang ditentukan
    const filteredData = data.filter((item) => {
      const isOwnerMatch = parseInt(item.owner) === parseInt(params.user_id);
      const hasDesignationMatch =
        item.workflow?.workflowapprovers?.some((approver) => {
          return (
            parseInt(approver.territory_id) === parseInt(params.territory_id)
          );
        }) || false;
      return isOwnerMatch || hasDesignationMatch;
    });

    return {
      success: true,
      udks: filteredData,
      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 option() {
  try {
    const udks = await dbSAPPS.Udk.findAll({
      attributes: ["id", "name"],
      where: { enabled: true },
      order: [["name", "ASC"]],
      include: [
        {
          model: dbSAPPS.UdkProduct,
          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.Udk.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 {
    // Validasi parameter yang diperlukan
    if (!params.company_id) {
      return {
        success: false,
        message: "Company is required!",
      };
    }

    // Generate NO UDK
    const toRoman = (month) => {
      const romanNumerals = [
        "I",
        "II",
        "III",
        "IV",
        "V",
        "VI",
        "VII",
        "VIII",
        "IX",
        "X",
        "XI",
        "XII",
      ];
      return romanNumerals[month - 1];
    };
    // Tentukan prefix berdasarkan company abbr (dinamis)
    const company = await dbSAPPS.Company.findByPk(params.company_id, {
      attributes: ["id", "abbr", "display_name"],
      transaction,
    });
    const prefix = company?.abbr || "UDK";

    // Generate next UDK number
    const generateNextUDK = async () => {
      const now = new Date();
      const currentMonth = now.getMonth() + 1;
      const currentYear = now.getFullYear();
      const monthRoman = toRoman(currentMonth);
      const yearShort = currentYear.toString().slice(-2); // Ambil dua digit terakhir dari tahun

      // Find all UDKs in current month/year, regardless of prefix
      const existingUDKs = await dbSAPPS.Udk.findAll({
        where: {
          name: {
            // [Op.like]: `%/UDK/${yearShort}/${monthRoman}/%`, // Menggunakan wildcard di depan untuk mencocokkan semua prefix
            [Op.like]: `%/UDK/${yearShort}/%/%`, // Menggunakan wildcard di depan untuk mencocokkan semua prefix
          },
        },
        transaction,
      });

      // Extract and find max sequence number
      let maxNumber = 0;
      existingUDKs.forEach((udk) => {
        const parts = udk.name.split("/");
        if (parts.length === 5) {
          const numberPart = parseInt(parts[4], 10);
          if (!isNaN(numberPart)) {
            maxNumber = Math.max(maxNumber, numberPart);
          }
        }
      });

      // Increment and format with leading zeros
      const nextNumber = (maxNumber + 1).toString().padStart(4, "0");
      return `${prefix}/UDK/${yearShort}/${monthRoman}/${nextNumber}`;
    };

    // Generate the new UDK number
    const newUDKNumber = await generateNextUDK();

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

    const newParams = {
      ...params,
      name: newUDKNumber,
    };

    // Buat UDK baru
    const newUdk = await dbSAPPS.Udk.create(newParams, {
      transaction,
    });

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

      // Validasi dan persiapkan data untuk bulkCreate
      const udkProductData = params.udkproducts.map((product) => {
        // Validasi field yang diperlukan
        if (!product.name) {
          throw new Error("Missing required fields in address child.");
        }

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

      // Lakukan bulkCreate
      try {
        const createdUDKProduct = await dbSAPPS.UdkProduct.bulkCreate(
          udkProductData,
          {
            transaction,
          }
        );

        // Mencari max discount
        let findMaxDiscount = 0;
        if (createdUDKProduct && createdUDKProduct.length > 0) {
          createdUDKProduct.forEach((product) => {
            // Convert discount to number, default to 0 if invalid
            const discount = parseFloat(product.discount) || 0;
            if (discount > findMaxDiscount) {
              findMaxDiscount = discount;
            }
          });
        }

        const maxDiscount = findMaxDiscount + newUdk?.other_discount

        // Atur workflow berdasarkan maksimal discount
        let excludeDesignationIds = [];
        if (maxDiscount <= 15) {
          excludeDesignationIds = [106, 129, 93];
        } else if (maxDiscount > 15 && maxDiscount <= 20) {
          excludeDesignationIds = [106, 129];
        } else if (maxDiscount > 20 && maxDiscount <= 25) {
          excludeDesignationIds = [106];
        }

        // Filter workflowterritories if present
        if (
          params.workflowterritories &&
          params.workflowterritories.length > 0
        ) {
          params.workflowterritories = params.workflowterritories.filter(
            (territory) =>
              !excludeDesignationIds.includes(territory.designation_id)
          );
        }
      } catch (bulkCreateError) {
        await transaction.rollback();
        return {
          success: false,
          message: "Failed to create udk product: " + bulkCreateError.message,
        };
      }
    }

    if (params.workflowterritories) {
      if (params.workflowterritories.length === 0) {
        const workflowData = {
          creation: Date.now(),
          modified: Date.now(),
          modified_by: parseInt(params.modified_by) || 1,
          owner: parseInt(params.owner) || 1,
          doctype_id: parseInt(params.doctype_id),
          doc_id: newUdk.id,
          status: "Draft",
        };

        const workflow = await dbSAPPS.Workflow.create(workflowData, {
          transaction,
        });

        // Buat user menjadi approver namun sudah auto terapprove
        if (workflow) {
          const workflowApproversData = {
            creation: Date.now(),
            modified: Date.now(),
            modified_by: parseInt(params.modified_by) || 1,
            owner: parseInt(params.owner) || 1,
            workflow_id: workflow.id,
            territory_id: parseInt(params.user_territory),
            status: null,
          };
          await dbSAPPS.WorkflowApprover.bulkCreate([workflowApproversData], {
            transaction,
          });
        }
      } else if (
        Array.isArray(params.workflowterritories) &&
        params.workflowterritories.length > 0
      ) {
        const workflowSettings = await dbSAPPS.WorkflowSetting.findAll(
          {
            where: {
              doctype_id: parseInt(params.doctype_id),
              enabled: true,
            },
          },
          { transaction }
        );
        const limitWorkflowTerritories = workflowSettings[0]?.limit || 0;
        const workflowTerritories = params.workflowterritories.slice(
          0,
          limitWorkflowTerritories
        );

        if (workflowTerritories.length === 0) {
          await transaction.rollback();
          return {
            success: false,
            message: "You must have at least one workflow territory.",
          };
        }

        const workflowData = {
          creation: Date.now(),
          modified: Date.now(),
          modified_by: parseInt(params.modified_by) || 1,
          owner: parseInt(params.owner) || 1,
          doctype_id: parseInt(params.doctype_id),
          doc_id: newUdk.id,
          status: "Draft",
        };

        const workflow = await dbSAPPS.Workflow.create(workflowData, {
          transaction,
        });
        if (workflow) {
          const workflowApproversData = workflowTerritories.map(
            (workflowTerritory) => ({
              creation: Date.now(),
              modified: Date.now(),
              modified_by: parseInt(params.modified_by) || 1,
              owner: parseInt(params.owner) || 1,
              workflow_id: workflow.id,
              territory_id: parseInt(workflowTerritory.territory_id),
              status: null,
            })
          );
          const approvers = await dbSAPPS.WorkflowApprover.bulkCreate(
            workflowApproversData,
            { transaction }
          );
          if (
            approvers?.length !== workflowTerritories.length ||
            !approvers.every(
              (approver) =>
                approver.workflow_id === workflow.id &&
                approver.territory_id !== null
            )
          ) {
            await transaction.rollback();
            return {
              success: false,
              message:
                "Failed to create workflow approvers. Please try again later.",
            };
          }
        }
      }
    }

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

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

async function update(id, params) {
  const transaction = await dbSAPPS.sequelize.transaction();
  try {
    const udk = await dbSAPPS.Udk.findByPk(id);
    if (!udk) {
      await transaction.rollback();
      return { success: false, message: "UDK not found!" };
    }

    // Validasi nama UDK
    if (params.name && params.name !== udk.name) {
      const existingUdk = await dbSAPPS.Udk.findOne({
        where: { name: params.name },
      });
      if (existingUdk) {
        await transaction.rollback();
        return {
          success: false,
          message: `UDK name "${params.name}" already exists!`,
        };
      }
    }

    // Proses UDK products
    let previousMaxDiscount = 0;
    let newMaxDiscount = 0;

    if (params.udkproducts) {
      // Parsing dan validasi products
      let products;
      try {
        products =
          typeof params.udkproducts === "string"
            ? JSON.parse(params.udkproducts)
            : params.udkproducts;

        if (!Array.isArray(products)) {
          throw new Error("Invalid products format");
        }
      } catch (e) {
        await transaction.rollback();
        return {
          success: false,
          message: `Invalid products data: ${e.message}`,
        };
      }

      // Hitung max discount sebelumnya
      const existingProducts = await dbSAPPS.UdkProduct.findAll({
        where: { udk_id: id },
        transaction,
      });

      previousMaxDiscount = existingProducts.reduce(
        (max, product) => Math.max(max, parseFloat(product.discount) || 0),
        0
      ) + (parseFloat(udk?.other_discount) || 0);

      // Hapus dan recreate products
      await dbSAPPS.UdkProduct.destroy({ where: { udk_id: id }, transaction });

      const productData = products.map((product) => {
        const discount = parseFloat(product.discount) || 0;
        newMaxDiscount = Math.max(newMaxDiscount, discount);

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

      newMaxDiscount += parseFloat(params?.other_discount) || 0;
      await dbSAPPS.UdkProduct.bulkCreate(productData, { transaction });
    }

    // Update data utama UDK
    await udk.update(params, { transaction });

    // Handle perubahan discount dan workflow
    if (newMaxDiscount !== previousMaxDiscount) {
      // Tentukan designation yang di-exclude
      let excludeDesignationIds = [];
      if (newMaxDiscount <= 15) {
        excludeDesignationIds = [106, 129, 93];
      } else if (newMaxDiscount > 15 && newMaxDiscount <= 20) {
        excludeDesignationIds = [106, 129];
      } else if (newMaxDiscount > 20 && newMaxDiscount <= 25) {
        excludeDesignationIds = [106];
      }

      // Cari workflow yang ada
      const workflow = await dbSAPPS.Workflow.findOne({
        where: { doctype_id: 107, doc_id: id },
        include: [
          {
            model: dbSAPPS.WorkflowApprover,
            as: "workflowapprovers",
            include: [
              {
                model: dbSAPPS.Territory,
                as: "territory",
                attributes: ["id", "name", "display_name"],
                include: [
                  {
                    model: dbSAPPS.Employee,
                    as: "employees",
                    attributes: ["id", "employee_name"],
                    include: [
                      {
                        model: dbSAPPS.Designation,
                        as: "designation",
                        attributes: ["display_name"],
                      },
                    ],
                  },
                ],
              },
            ],
          },
        ],
        transaction,
      });

      if (workflow) {
        // Pisahkan approver approved dan pending
        const [approvedApprovers, pendingApprovers] =
          workflow.workflowapprovers.reduce(
            ([approved, pending], approver) => {
              approver.status === "Approved"
                ? approved.push(approver)
                : pending.push(approver);
              return [approved, pending];
            },
            [[], []]
          );

        // Filter territories baru
        const filteredTerritories = (params.workflowterritories || []).filter(
          (t) => !excludeDesignationIds.includes(t.designation_id)
        );

        if (filteredTerritories.length === 0) {
          await dbSAPPS.WorkflowApprover.destroy({
            where: { workflow_id: workflow.id },
            transaction,
          });

          const noApprovers = {
            creation: Date.now(),
            modified: Date.now(),
            modified_by: parseInt(params.modified_by) || 1,
            owner: parseInt(params.owner) || 1,
            workflow_id: workflow.id,
            territory_id: parseInt(params.user_territory),
            status: null,
          };

          await dbSAPPS.WorkflowApprover.bulkCreate([noApprovers], {
            transaction,
          });
        } else {
          // Handle pending approver
          const pendingToDelete = pendingApprovers.filter(
            (a) =>
              !filteredTerritories.some(
                (t) => t.territory_id === a.territory_id
              )
          );

          // Hapus pending approver yang tidak relevan
          if (pendingToDelete.length > 0) {
            await dbSAPPS.WorkflowApprover.destroy({
              where: { id: pendingToDelete.map((a) => a.id) },
              transaction,
            });
          }

          // Tambahkan approver baru
          const newApprovers = filteredTerritories
            .filter(
              (t) =>
                ![...approvedApprovers, ...pendingApprovers].some(
                  (a) => a.territory_id === t.territory_id
                )
            )
            .map((t) => ({
              creation: Date.now(),
              modified: Date.now(),
              modified_by: params.modified_by,
              owner: params.owner,
              workflow_id: workflow.id,
              territory_id: t.territory_id,
              status: null,
            }));

          if (newApprovers.length > 0) {
            await dbSAPPS.WorkflowApprover.bulkCreate(newApprovers, {
              transaction,
            });
          }
        }

        // Dapatkan semua approver terbaru
        const updatedApprovers = await dbSAPPS.WorkflowApprover.findAll({
          where: { workflow_id: workflow.id },
          transaction,
        });


        // Cek status terakhir
        const lastApproverStatus = updatedApprovers[0]?.status;
        let newStatus = "Draft";

        if (lastApproverStatus === "Approved") {
          const allApproved = updatedApprovers.every(
            (a) => a.status === "Approved"
          );
          newStatus = allApproved ? "Approved" : "Need Approval";
        } else if (lastApproverStatus === "Rejected") {
          newStatus = "Rejected";
        }

        // Update status workflow
        await dbSAPPS.Workflow.update(
          { status: newStatus },
          { where: { id: workflow.id }, transaction }
        );
      }
    }

    await transaction.commit();
    return { success: true, message: "UDK updated successfully!" };
  } catch (error) {
    await transaction.rollback();
    console.error("Update error:", error);
    return { success: false, message: error.message || "Failed to update UDK" };
  }
}

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

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

async function _delete(id) {
  const transaction = await dbSAPPS.sequelize.transaction();
  try {
    const udk = await dbSAPPS.Udk.findByPk(id);
    if (!udk) return { success: false, message: "Udk not found!" };

    const workflows = await dbSAPPS.Workflow.findAll({
      where: {
        doc_id: {
          [Op.eq]: udk.id,
        },
        doctype_id: 107,
      },
      attributes: [
        "id",
        "doc_id",
        "doctype_id",
        "status",
        "modified_by",
        "modified",
      ],
      include: [
        {
          model: dbSAPPS.WorkflowApprover,
          as: "workflowapprovers",
          attributes: [
            "id",
            "workflow_id",
            "designation_id",
            "territory_id",
            "status",
            "modified",
          ],
          include: [
            {
              model: dbSAPPS.Designation,
              as: "designation",
              attributes: ["id", "name", "display_name"],
              include: [
                {
                  model: dbSAPPS.Employee,
                  as: "employee",
                  attributes: ["id", "employee_name"],
                },
              ],
            },
            {
              model: dbSAPPS.Territory,
              as: "territory",
              attributes: ["id", "name", "display_name"],
              include: [
                {
                  model: dbSAPPS.Employee,
                  as: "employees",
                  attributes: ["id", "employee_name"],
                },
              ],
            },
          ],
        },
      ],
    });
    if (!workflows)
      return {
        success: false,
        message: "Workflows udk not found!",
      };
    for (const workflow of workflows) {
      if (workflow) {
        await dbSAPPS.WorkflowApprover.destroy({
          where: { workflow_id: workflow.id },
          transaction,
        });
        await dbSAPPS.Workflow.destroy({
          where: { id: workflow.id },
          transaction,
        });
      }
    }
    await new Promise((resolve) => setTimeout(resolve, 500));

    await udk.destroy({ transaction });
    await transaction.commit();

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