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

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

async function getAll() {
  try {
    const dmsLegals = await dbSAPPS.DMSLegal.findAll({
      order: [["type", "ASC"]],
      include: [
        {
          model: dbSAPPS.DMSLegalChild,
          as: "dmslegalchilds",
          attributes: [
            "id",
            "dmslegal_id",
            "name",
            "document_number",
            "counter_part",
            "date",
            "exp_date",
            "original",
            "copy",
            "remark",
            "softfile",
            "registration_number",
            "status",
            "owner_doc",
            "class",
            "pic",
            "enabled"
          ],
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["name"],
        },
      ],
    });

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

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

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

  try {
    const dmsLegals = await dbSAPPS.DMSLegal.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.DMSLegalChild,
          as: "dmslegalchilds",
          attributes: [
            "id",
            "dmslegal_id",
            "name",
            "document_number",
            "counter_part",
            "date",
            "exp_date",
            "original",
            "copy",
            "remark",
            "softfile",
            "registration_number",
            "status",
            "owner_doc",
            "class",
            "pic",
            "enabled",
          ],
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["name"],
        },
      ],
    });

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

async function getByEmpID(params) {
  try {
    // Ambil semua data dmsLegals beserta relasi dmslegalchilds dan company
    const dmsLegals = await dbSAPPS.DMSLegal.findAll({
      order: [["type", "ASC"]],
      include: [
        {
          model: dbSAPPS.DMSLegalChild,
          as: "dmslegalchilds",
          attributes: [
            "id",
            "dmslegal_id",
            "name",
            "document_number",
            "counter_part",
            "date",
            "exp_date",
            "original",
            "copy",
            "remark",
            "softfile",
            "registration_number",
            "status",
            "owner_doc",
            "class",
            "pic",
            "enabled"
          ],
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["name"],
        },
      ],
    });

    // Jika terdapat params.employee_id maka lakukan filtering data
    if (params.employee_id) {
      const empID = String(params.employee_id); // pastikan tipe data string untuk perbandingan
      // Proses filter data dmsLegals
      const filteredDmsLegals = dmsLegals
        .map((dmsLegal) => {
          // Filter child yang memiliki properti 'pic'
          const filteredChilds = dmsLegal.dmslegalchilds.filter((child) => {
            // Pastikan field pic tidak kosong
            if (child.pic) {
              try {
                // Karena field pic berupa string JSON, kita harus parse terlebih dahulu
                const picArray = JSON.parse(child.pic);
                // Cek apakah salah satu objek di picArray memiliki property id yang sama
                return picArray.some((picObj) => String(picObj.id) === empID);
              } catch (e) {
                // Jika parsing gagal, abaikan data tersebut
                return false;
              }
            }
            return false;
          });
          // Jika terdapat minimal 1 child yang cocok, kembalikan dmsLegal dengan dmslegalchilds yang sudah difilter
          if (filteredChilds.length > 0) {
            // Jika menggunakan Sequelize, untuk menghindari masalah instance atau dataValues, kita bisa cloning data
            return {
              ...dmsLegal.dataValues,
              dmslegalchilds: filteredChilds,
            };
          }
          // Jika tidak ada child yang cocok, data dmsLegal tersebut tidak ditampilkan
          return null;
        })
        .filter((item) => item !== null);

      return {
        dmsLegals: filteredDmsLegals,
        success: true,
        message: "DMS Legals loaded successfully!",
      };
    }

    // Jika tidak terdapat params.employee_id, kembalikan semua data
    return {
      dmsLegals,
      success: true,
      message: "DMS Legals loaded successfully!",
    };
  } catch (error) {
    const errorMessage = error.message || "Failed to load DMS Legals!";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

async function option() {
  try {
    const dmsLegals = await dbSAPPS.DMSLegal.findAll({
      where: { enabled: true },
      order: [["type", "ASC"]],
      include: [
        {
          model: dbSAPPS.DMSLegalChild,
          as: "dmslegalchilds",
          attributes: [
            "id",
            "dmslegal_id",
            "name",
            "document_number",
            "counter_part",
            "date",
            "exp_date",
            "original",
            "copy",
            "remark",
            "softfile",
            "registration_number",
            "status",
            "owner_doc",
            "class",
            "pic",
            "enabled"
          ],
        },
        {
          model: dbSAPPS.Company,
          as: "company",
          attributes: ["name"],
        },
      ],
    });

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

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

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

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

    const existing = await dbSAPPS.DMSLegal.findOne({
      where: {
        type: params.type,
        sub_type: params.sub_type,
        category: params.category,
        sub_category: params.sub_category,
        company_id: params.company_id,
      },
    });
    if (existing)
      return {
        success: false,
        message: `This folder has already been created.`,
      };
    // History log
    let chatHistory = [];
    try {
      let parsed = dmsLegal.history;
      if (typeof parsed === "string") parsed = JSON.parse(parsed); // parse sekali
      if (typeof parsed === "string") parsed = JSON.parse(parsed); // kalau masih string, parse lagi
      if (Array.isArray(parsed)) chatHistory = parsed;
    } catch (err) {
      chatHistory = [];
    }

    // ADD NEW LOG ENTRY
    const newLogEntry = {
      id: params.modified_by,
      status: params.updateStatus || "update data",
      modified: params.modified,
      name: params.modifiedname_by,
    };

    chatHistory.push(newLogEntry);
    params.history = JSON.stringify(chatHistory);
    // Buat DMS Legal baru
    const newDMSLegal = await dbSAPPS.DMSLegal.create(params, { transaction });

    // Proses child data jika ada
    if (params.dmslegalchilds) {
      if (typeof params.dmslegalchilds === "string") {
        params.dmslegalchilds = JSON.parse(params.dmslegalchilds);
      }

      // Tambahkan file softfile ke child data
      params.dmslegalchilds = params.dmslegalchilds.map((child, index) => ({
        ...child,
        softfile: params[`softfile_${index}`] || null, // Simpan file jika ada
        creation: Date.now(),
        modified: Date.now(),
        modified_by: params.modified_by,
        owner: params.owner,
        dmslegal_id: newDMSLegal.id,
      }));

      await dbSAPPS.DMSLegalChild.bulkCreate(params.dmslegalchilds, {
        transaction,
      });
    }

    await transaction.commit();
    return {
      success: true,
      message: "Data DMS Legal has been successfully added!",
      dmsLegals: newDMSLegal,
    };
  } catch (error) {
    await transaction.rollback();
    return {
      success: false,
      message: error.message || "An error occurred during DMS legal creation.",
    };
  }
}

// async function update(id, params) {
//   const transaction = await dbSAPPS.sequelize.transaction();
//   try {
//     const dmsLegal = await dbSAPPS.DMSLegal.findByPk(id);
//     if (!dmsLegal) {
//       return { success: false, message: "DMS legal not found!" };
//     }

//     // Update DMS Legal
//     await dmsLegal.update(params, { transaction });

//     // Update atau tambahkan child data
//     if (params.dmslegalchilds) {
//       if (typeof params.dmslegalchilds === "string") {
//         params.dmslegalchilds = JSON.parse(params.dmslegalchilds);
//       }

//       // Ambil data child lama
//       const existingChildren = await dbSAPPS.DMSLegalChild.findAll({
//         where: { dmslegal_id: id },
//       });

//       const updatedChildren = params.dmslegalchilds.map((child, index) => {
//         const existingChild = existingChildren.find((c) => c.id === child.id);
//         return {
//           ...child,
//           softfile:
//             params[`softfile_${index}`] ||
//             (existingChild ? existingChild.softfile : null),
//           modified: Date.now(),
//           modified_by: params.modified_by,
//         };
//       });

//       // Hapus child lama & masukkan data baru
//       await dbSAPPS.DMSLegalChild.destroy({
//         where: { dmslegal_id: id },
//         transaction,
//       });

//       // Persiapkan data untuk bulkCreate
//       const dmsLegalChildData = params.dmslegalchilds.map((dmsLegalChild) => {
//         // Validasi field yang diperlukan
//         if (!dmsLegalChild.name) {
//           throw new Error("Missing required fields in delivery trip child.");
//         }

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

//       await dbSAPPS.DMSLegalChild.bulkCreate(dmsLegalChildData, {
//         transaction,
//       });
//     }

//     await transaction.commit();
//     return { success: true, message: "Your data DMS Legal has been updated!" };
//   } catch (error) {
//     await transaction.rollback();
//     return {
//       success: false,
//       message: error.message || "Failed to update DMS legal data.",
//     };
//   }
// }

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

    // History log
    let chatHistory = [];
    try {
      let parsed = dmsLegal.history;
      if (typeof parsed === "string") parsed = JSON.parse(parsed); // parse sekali
      if (typeof parsed === "string") parsed = JSON.parse(parsed); // kalau masih string, parse lagi
      if (Array.isArray(parsed)) chatHistory = parsed;
    } catch (err) {
      chatHistory = [];
    }

    // --------------------------
    // ADD NEW LOG ENTRY
    const newLogEntry = {
      id: params.modified_by,
      status: params.updateStatus || "update data",
      modified: params.modified,
      name: params.modifiedname_by,
    };

    chatHistory.push(newLogEntry);
    params.history = JSON.stringify(chatHistory); // simpan hanya sekali stringify

    await dmsLegal.update(params, { transaction });

    if (params.dmslegalchilds) {
      if (typeof params.dmslegalchilds === "string") {
        params.dmslegalchilds = JSON.parse(params.dmslegalchilds);
      }

      // ✅ Hapus jika ada deleted_ids
      if (params.deleted_ids) {
        if (typeof params.deleted_ids === "string") {
          params.deleted_ids = JSON.parse(params.deleted_ids);
        }
        if (
          Array.isArray(params.deleted_ids) &&
          params.deleted_ids.length > 0
        ) {
          await dbSAPPS.DMSLegalChild.destroy({
            where: {
              id: params.deleted_ids,
              dmslegal_id: id,
            },
            transaction,
          });
        }
      }

      for (const [index, child] of params.dmslegalchilds.entries()) {
        const softfile = params[`softfile_${index}`] || child.softfile;

        if (child.id) {
          // Update
          await dbSAPPS.DMSLegalChild.update(
            {
              ...child,
              softfile,
              modified: Date.now(),
              modified_by: params.modified_by,
            },
            { where: { id: child.id }, transaction }
          );
        } else {
          // Create
          await dbSAPPS.DMSLegalChild.create(
            {
              ...child,
              softfile,
              creation: Date.now(),
              modified: Date.now(),
              modified_by: params.modified_by,
              owner: params.owner,
              dmslegal_id: id,
              enabled: true,
            },
            { transaction }
          );
        }
      }
    }

    await transaction.commit();
    return { success: true, message: "Your data DMS Legal has been updated!" };
  } catch (error) {
    await transaction.rollback();
    return {
      success: false,
      message: error.message || "Failed to update DMS legal data.",
    };
  }
}

// Update dengan hapus
// async function update(id, params) {
//   const transaction = await dbSAPPS.sequelize.transaction();
//   try {
//     const dmsLegal = await dbSAPPS.DMSLegal.findByPk(id);
//     if (!dmsLegal) {
//       return { success: false, message: "DMS legal not found!" };
//     }

//     // Update record utama DMS Legal
//     await dmsLegal.update(params, { transaction });

//     // Jika ada payload untuk child data
//     if (params.dmslegalchilds) {
//       // Pastikan params.dmslegalchilds berbentuk array object (jika berbentuk string, parse terlebih dahulu)
//       if (typeof params.dmslegalchilds === "string") {
//         params.dmslegalchilds = JSON.parse(params.dmslegalchilds);
//       }

//       // Proses setiap child dari payload
//       for (const [index, childData] of params.dmslegalchilds.entries()) {
//         // Tentukan nilai softfile dari payload file atau gunakan nilai dari childData jika tidak ada file baru
//         const softfile = params[`softfile_${index}`] || childData.softfile;

//         if (childData.id) {
//           // Jika child sudah ada, lakukan update terhadap record tersebut
//           await dbSAPPS.DMSLegalChild.update(
//             {
//               ...childData,
//               softfile, // update softfile jika ada
//               modified: Date.now(),
//               modified_by: params.modified_by,
//             },
//             {
//               where: { id: childData.id },
//               transaction,
//             }
//           );
//         } else {
//           // Jika child merupakan data baru, buat record baru
//           await dbSAPPS.DMSLegalChild.create(
//             {
//               ...childData,
//               softfile, // set nama file jika ada file yang diupload
//               creation: Date.now(),
//               modified: Date.now(),
//               modified_by: params.modified_by,
//               owner: params.owner,
//               enabled:true,
//               dmslegal_id: id, // kaitkan dengan record DMS Legal utama
//             },
//             { transaction }
//           );
//         }
//       }
//     }

//     // Commit transaction jika semuanya berjalan lancar
//     await transaction.commit();
//     return { success: true, message: "Your data DMS Legal has been updated!" };
//   } catch (error) {
//     await transaction.rollback();
//     return {
//       success: false,
//       message: error.message || "Failed to update DMS legal data.",
//     };
//   }
// }

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

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

async function _delete(id) {
  try {
    const dmsLegal = await dbSAPPS.DMSLegal.findByPk(id);
    if (!dmsLegal) return { success: false, message: "DMS Legal not found!" };

    await dmsLegal.destroy();

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