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

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

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

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

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

  try {
    const comments = await dbSAPPS.Comment.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.DocType,
          as: "doctype",
          attributes: ["id", "name", "display_name"],
        },
        {
          model: dbSAPPS.User,
          as: "user",
          include: [
            {
              model: dbSAPPS.Employee,
              as: "employee",
              attributes: ["employee_name"],
              include: [
                {
                  model: dbSAPPS.Designation,
                  as: "designation",
                  attributes: ["display_name"],
                },
              ],
            },
          ],
        },
      ],
    });

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

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

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

  try {
    const comment = await dbSAPPS.Comment.findAll({
      where: filterConditions,
      order: [["modified", "DESC"]],
      include: [
        {
          model: dbSAPPS.DocType,
          as: "doctype",
          attributes: ["id", "name", "display_name"],
        },
        {
          model: dbSAPPS.User,
          as: "user",
          include: [
            {
              model: dbSAPPS.Employee,
              as: "employee",
              attributes: ["employee_name"],
              include: [
                {
                  model: dbSAPPS.Designation,
                  as: "designation",
                  attributes: ["display_name"],
                },
              ],
            },
          ],
        },
      ],
    });

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

async function option() {
  try {
    const comment = await dbSAPPS.Comment.findAll({
      attributes: ["id", "doctype_id", "status", "doc_id"],
      order: [["modified", "ASC"]],
      include: [
        {
          model: dbSAPPS.DocType,
          as: "doctype",
          attributes: ["id", "name", "display_name"],
        },
        {
          model: dbSAPPS.User,
          as: "user",
          include: [
            {
              model: dbSAPPS.Employee,
              as: "employee",
              attributes: ["employee_name"],
              include: [
                {
                  model: dbSAPPS.Designation,
                  as: "designation",
                  attributes: ["display_name"],
                },
              ],
            },
          ],
        },
      ],
    });

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

async function count() {
  try {
    const count = await dbSAPPS.Comment.count();

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

async function create(params) {
  const transaction = await dbSAPPS.sequelize.transaction();
  try {
    if (!params.doctype_id || !params.doc_id)
      return {
        success: false,
        message: "doctype_id and doc_id are required!",
      };

    const comment = await dbSAPPS.Comment.create(params, { transaction });



    await transaction.commit();
    return {
      success: true,
      message: "comment data has been successfully added!",
    };
  } catch (error) {
    await transaction.rollback();
    const errorMessage =
      error.message || "An error occurred during create comment processing.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

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

    if (
      params.doctype_id &&
      params.doctype_id !== comment.doctype_id &&
      params.doc_id &&
      params.doc_id !== comment.doc_id
    ) {
      const existing = await dbSAPPS.Comment.findOne({
        where: {
          doctype_id: params.doctype_id,
          doc_id: params.doc_id,
        },
      });

      if (existing) {
        return {
          success: false,
          message: `workfolw doctype_id "${params.doctype_id}" and doc_id "${params.doc_id}" is already taken. Try again!`,
        };
      }
    }

    await comment.update(params, { transaction });
    
    await transaction.commit();
    return {
      success: true,
      message: "Data comment has been saved!",
    };
  } catch (error) {
    await transaction.rollback();
    const errorMessage = error.message || "Failed to update comment data.";
    return {
      success: false,
      message: errorMessage,
    };
  }
}

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

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