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

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

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

	if (params.doc_id) {
		filterConditions.id = params.doc_id;
	}
	try {
		const ncProducts = await dbSAPPS.NcProduct.findAll({
			where: filterConditions,
			order: [["modified", "DESC"]],
			include: [
				{
					model: dbSAPPS.NcProductChild,
					as: "ncproductchilds",
					attributes: ["id", "product_name", "quantity", "uom", "batch_no", "expiry_date", "noncomformity", "description", "status", "status_date"],
				},
				{
					model: dbSAPPS.NcProductFU,
					as: "ncproductfus",
					attributes: ["id", "date", "description", "pic_id"],
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
						},
					],
				},
				{
					model: dbSAPPS.User,
					as: "user",
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
							include: [
								{
									model: dbSAPPS.Designation,
									as: "designation",
									attributes: ["display_name"],
								},
							],
						},
					],
				},
				{
					model: dbSAPPS.Company,
					as: "company",
					attributes: ["id", "display_name", "name"],
				},
			],
		});

		const workflows = await dbSAPPS.Workflow.findAll({
			where: {
				doc_id: {
					[Op.in]: ncProducts.map((item) => item.id),
				},
				doctype_id: 149,
			},
			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"],
										},
									],
								},
							],
						},
					],
				},
			],
		});

		// Get comments
		const comments = await dbSAPPS.Comment.findAll({
			where: {
				doc_id: {
					[Op.in]: ncProducts.map((item) => item.id),
				},
				doctype_id: 149,
			},
			order: [["creation", "DESC"]],
			attributes: ["id", "doc_id", "doctype_id", "edited", "comment", "modified_by", "modified", "owner"],
			include: [
				{
					model: dbSAPPS.User,
					as: "user",
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
							include: [
								{
									model: dbSAPPS.Designation,
									as: "designation",
									attributes: ["display_name"],
								},
							],
						},
					],
				},
			],
		});

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

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

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

	if (params.company_id) {
		filterConditions.company_id = {
			[Op.eq]: params.company_id,
		};
	}

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

	try {
		const ncProducts = await dbSAPPS.NcProduct.findAll({
			where: filterConditions,
			order: [["modified", "DESC"]],
			include: [
				{
					model: dbSAPPS.NcProductChild,
					as: "ncproductchilds",
					attributes: ["id", "product_name", "quantity", "uom", "batch_no", "expiry_date", "noncomformity", "description", "status", "status_date"],
				},
				{
					model: dbSAPPS.NcProductFU,
					as: "ncproductfus",
					attributes: ["id", "date", "description", "pic_id"],
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
						},
					],
				},
				{
					model: dbSAPPS.User,
					as: "user",
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
							include: [
								{
									model: dbSAPPS.Designation,
									as: "designation",
									attributes: ["display_name"],
								},
							],
						},
					],
				},
				{
					model: dbSAPPS.Company,
					as: "company",
					attributes: ["id", "display_name", "name"],
				},
			],
		});

		const workflows = await dbSAPPS.Workflow.findAll({
			where: {
				doc_id: {
					[Op.in]: ncProducts.map((item) => item.id),
				},
				doctype_id: 149,
			},
			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"],
										},
									],
								},
							],
						},
					],
				},
			],
		});

		// Get comments
		const comments = await dbSAPPS.Comment.findAll({
			where: {
				doc_id: {
					[Op.in]: ncProducts.map((item) => item.id),
				},
				doctype_id: 149,
			},
			order: [["creation", "DESC"]],
			attributes: ["id", "doc_id", "doctype_id", "edited", "comment", "modified_by", "modified", "owner"],
			include: [
				{
					model: dbSAPPS.User,
					as: "user",
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
							include: [
								{
									model: dbSAPPS.Designation,
									as: "designation",
									attributes: ["display_name"],
								},
							],
						},
					],
				},
			],
		});

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

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

async function filterByYear(params) {
	let filterConditions = {};

	if (params.year || params.month) {
		filterConditions.nc_date = {};
		filterConditions.nc_date[Op.and] = [];

		if (params.year) {
			filterConditions.nc_date[Op.and].push(Sequelize.where(Sequelize.fn("YEAR", Sequelize.col("nc_date")), params.year));
		}

		if (params.month) {
			filterConditions.nc_date[Op.and].push(Sequelize.where(Sequelize.fn("MONTH", Sequelize.col("nc_date")), params.month));
		}

		// Kalau `Op.and` kosong, hapus dari kondisi
		if (filterConditions.nc_date[Op.and].length === 0) {
			delete filterConditions.nc_date[Op.and];
		}
	}

	try {
		const ncProducts = await dbSAPPS.NcProduct.findAll({
			where: filterConditions,
			order: [["modified", "DESC"]],
			include: [
				{
					model: dbSAPPS.NcProductChild,
					as: "ncproductchilds",
					attributes: ["id", "product_name", "quantity", "uom", "batch_no", "expiry_date", "noncomformity", "description", "status", "status_date"],
				},
				{
					model: dbSAPPS.NcProductFU,
					as: "ncproductfus",
					attributes: ["id", "date", "description", "pic_id"],
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
						},
					],
				},
				{
					model: dbSAPPS.User,
					as: "user",
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
							include: [
								{
									model: dbSAPPS.Designation,
									as: "designation",
									attributes: ["display_name"],
								},
							],
						},
					],
				},
				{
					model: dbSAPPS.Company,
					as: "company",
					attributes: ["id", "display_name", "name"],
				},
			],
		});

		const workflows = await dbSAPPS.Workflow.findAll({
			where: {
				doc_id: {
					[Op.in]: ncProducts.map((item) => item.id),
				},
				doctype_id: 149,
			},
			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 comments = await dbSAPPS.Comment.findAll({
			where: {
				doc_id: {
					[Op.in]: ncProducts.map((item) => item.id),
				},
				doctype_id: 149,
			},
			order: [["creation", "DESC"]],
			attributes: ["id", "doc_id", "doctype_id", "edited", "comment", "modified_by", "modified", "owner"],
			include: [
				{
					model: dbSAPPS.User,
					as: "user",
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
							include: [
								{
									model: dbSAPPS.Designation,
									as: "designation",
									attributes: ["display_name"],
								},
							],
						},
					],
				},
			],
		});

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

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

async function option() {
	try {
		const ncProducts = await dbSAPPS.NcProduct.findAll({
			attributes: ["id", "nc_no"],
			where: { enabled: true },
			order: [["id", "ASC"]],
			include: [
				{
					model: dbSAPPS.NcProductChild,
					as: "ncproductchilds",
					attributes: ["id", "product_name", "quantity", "uom", "batch_no", "expiry_date", "noncomformity", "description", "status", "status_date"],
				},
				{
					model: dbSAPPS.NcProductFU,
					as: "ncproductfus",
					attributes: ["id", "date", "description", "pic_id"],
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
						},
					],
				},
				{
					model: dbSAPPS.User,
					as: "user",
					include: [
						{
							model: dbSAPPS.Employee,
							as: "employee",
							attributes: ["employee_name"],
							include: [
								{
									model: dbSAPPS.Designation,
									as: "designation",
									attributes: ["display_name"],
								},
							],
						},
					],
				},
				{
					model: dbSAPPS.Company,
					as: "company",
					attributes: ["id", "display_name", "name"],
				},
			],
		});

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

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

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

async function create(params) {
	const transaction = await dbSAPPS.sequelize.transaction();
	try {
		// Generate NO UDK
		const toNumber = (month) => {
			return month.toString().padStart(2, "0");
		};

		// Generate next UDK number
		const generateNextNC = async () => {
			const now = new Date();
			const currentMonth = now.getMonth() + 1;
			const currentYear = now.getFullYear();
			const month = toNumber(currentMonth);
			const year = currentYear.toString();

			// Prefix untuk disimpan di nc_no (dengan bulan)
			const prefix = `NC.${currentYear}${currentMonth}`;

			// Tapi pencarian hanya berdasarkan tahun saja
			const yearPrefix = `NC.${currentYear}`;

			// Cari semua dokumen dengan prefix yang sama
			const existingNCProducts = await dbSAPPS.NcProduct.findAll({
				where: {
					nc_no: {
						[Op.like]: `${yearPrefix}%`,
					},
				},
				transaction,
			});

			// Ambil urutan terakhir dan hitung nomor berikutnya
			let maxNumber = 0;
			existingNCProducts.forEach((nc) => {
				const match = nc.nc_no.match(/^NC\.\d{6}(\d{4})$/); // Format NC.2025060001
				if (match) {
					const numberPart = parseInt(match[1], 10);
					if (!isNaN(numberPart)) {
						maxNumber = Math.max(maxNumber, numberPart);
					}
				}
			});

			// Tambahkan 1 dan format ke 4 digit
			const nextNumber = (maxNumber + 1).toString().padStart(4, "0");

			// Gabungkan prefix bulan dan nomor urut
			return `${prefix}${nextNumber}`;
		};

		// Contoh pemanggilan:
		const newNCNumber = await generateNextNC();
		const newParams = {
			...params,
			nc_no: newNCNumber,
		};
		// Buat NC Product baru
		const newNCProduct = await dbSAPPS.NcProduct.create(newParams, {
			transaction,
		});

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

			// Validasi dan persiapkan data untuk bulkCreate
			const ncProductsChildData = params.ncproductchilds.map((ncProductChild) => {
				// Validasi field yang diperlukan
				if (!ncProductChild.product_name) {
					throw new Error("Missing required fields in nc child.");
				}

				return {
					...ncProductChild,
					creation: Date.now(),
					modified: Date.now(),
					modified_by: params.modified_by,
					owner: params.owner,
					ncproduct_id: newNCProduct.id,
				};
			});

			// Lakukan bulkCreate
			try {
				await dbSAPPS.NcProductChild.bulkCreate(ncProductsChildData, {
					transaction,
				});
			} catch (bulkCreateError) {
				await transaction.rollback();
				return {
					success: false,
					message: "Failed to create data child: " + bulkCreateError.message,
				};
			}
		}

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

			// Validasi dan persiapkan data untuk bulkCreate
			const ncProductsFUData = params.ncproductfus.map((ncProductFU) => {
				// Validasi field yang diperlukan
				if (!ncProductFU.description) {
					throw new Error("Missing required fields in nc child.");
				}

				return {
					...ncProductFU,
					creation: Date.now(),
					modified: Date.now(),
					modified_by: params.modified_by,
					owner: params.owner,
					ncproduct_id: newNCProduct.id,
				};
			});

			// Lakukan bulkCreate
			try {
				await dbSAPPS.NcProductFU.bulkCreate(ncProductsFUData, {
					transaction,
				});
			} catch (bulkCreateError) {
				await transaction.rollback();
				return {
					success: false,
					message: "Failed to create data fu: " + bulkCreateError.message,
				};
			}
		}

		if (params.workflowterritories && params.workflowterritories.length !== 0) {
			if (params.workflowterritories) {
				if (typeof params.workflowterritories === "string") {
					params.workflowterritories = JSON.parse(params.workflowterritories);
				}

				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: newNCProduct.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.",
							};
						}
					}
				}
			}
		} else {
			if (params.workflowdesignations) {
				if (typeof params.workflowdesignations === "string") {
					params.workflowdesignations = JSON.parse(params.workflowdesignations);
				}
				if (Array.isArray(params.workflowdesignations) && params.workflowdesignations.length > 0) {
					const workflowSettings = await dbSAPPS.WorkflowSetting.findAll(
						{
							where: {
								doctype_id: params.doctype_id,
								type: "Designation",
								enabled: true,
							},
						},
						{ transaction }
					);
					const limitWorkflowDesignations = workflowSettings[0]?.limit || 0;
					const workflowDesignations = params.workflowdesignations.slice(0, limitWorkflowDesignations);

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

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

					const workflow = await dbSAPPS.Workflow.create(workflowData, {
						transaction,
						lock: transaction.LOCK.UPDATE,
					});
					if (workflow) {
						const workflowApproversData = workflowDesignations.map((workflowDesignation) => ({
							creation: Date.now(),
							modified: Date.now(),
							modified_by: params.modified_by || 1,
							owner: params.owner || 1,
							workflow_id: workflow.id,
							designation_id: workflowDesignation.designation_id,
							status: null,
						}));
						const approvers = await dbSAPPS.WorkflowApprover.bulkCreate(workflowApproversData, { transaction, lock: transaction.LOCK.UPDATE });
						if (
							approvers?.length !== workflowDesignations.length ||
							!approvers.every((approver) => approver.workflow_id === workflow.id && approver.designation_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 has been successfully adeded!",
			ncProducts: newNCProduct,
		};
	} catch (error) {
		const errorMessage = error || "An error occurred during data creation.";
		return {
			success: false,
			message: errorMessage,
		};
	}
}

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

		await ncProduct.update(params);

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

			// Hapus child yang ada sebelum menambahkan yang baru
			await dbSAPPS.NcProductChild.destroy({
				where: { ncproduct_id: id },
				transaction,
			});

			// Persiapkan data untuk bulkCreate
			const ncProductsChildData = params.ncproductchilds.map((child) => {
				// Validasi field yang diperlukan
				if (!child.product_name) {
					throw new Error("Missing required fields in data child.");
				}

				return {
					...child,
					creation: Date.now(),
					modified: Date.now(),
					modified_by: params.modified_by,
					owner: params.owner,
					ncproduct_id: id, // Mengaitkan dengan ID Delivery Trip yang diupdate
				};
			});

			// Lakukan bulkCreate untuk child yang baru
			await dbSAPPS.NcProductChild.bulkCreate(ncProductsChildData, {
				transaction,
			});
		}

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

			// Hapus child yang ada sebelum menambahkan yang baru
			await dbSAPPS.NcProductFU.destroy({
				where: { ncproduct_id: id },
				transaction,
			});

			// Persiapkan data untuk bulkCreate
			const ncProductsFUData = params.ncproductfus.map((child) => {
				// Validasi field yang diperlukan
				if (!child.description) {
					throw new Error("Missing required fields in data child.");
				}

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

			// Lakukan bulkCreate untuk child yang baru
			await dbSAPPS.NcProductFU.bulkCreate(ncProductsFUData, {
				transaction,
			});
		}

		// Commit transaksi jika semua berhasil
		await transaction.commit();
		return {
			success: true,
			message: "Your data has been saved!",
		};
	} catch (error) {
		const errorMessage = error || "Failed to update nc product data.";
		return {
			success: false,
			message: errorMessage,
		};
	}
}

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

async function _delete(id) {
	const transaction = await dbSAPPS.sequelize.transaction();
	try {
		const ncProduct = await dbSAPPS.NcProduct.findByPk(id);
		if (!ncProduct) return { success: false, message: "nc product not found!" };
		const workflows = await dbSAPPS.Workflow.findAll({
			where: {
				doc_id: {
					[Op.eq]: ncProduct.id,
				},
				doctype_id: 149,
			},
			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 employee request 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 ncProduct.destroy();
		await transaction.commit();
		return {
			success: true,
			message: "NC Product successfully deleted!",
		};
	} catch (error) {
		const errorMessage = error || "Failed to delete nc product.";
		return {
			success: false,
			message: errorMessage,
		};
	}
}
