const { MinutesOfMeeting, Projects, Users } = require("../models");
const { addFormattedIds, addFormattedId } = require("../utils/idFormatter");
const {
  createRiskAssessmentNotification,
} = require("../utils/notificationHelper");
const { sendMinutesOfMeetingEmail } = require("../utils/emailService");
const uploadFile = require("../utils/uploadFile");

const getMinutesOfMeetings = async (req, res) => {
  const { projectId } = req.query;

  try {
    const minutesOfMeetings = await MinutesOfMeeting.findAll({
      where: {
        ProjectId: projectId,
      },
      include: [Projects],
    });

    const response = minutesOfMeetings.map(({ data, Project, id }) => {
      return {
        ...JSON.parse(data),
        id,
        project: Project.name,
      };
    });

    res.json(addFormattedIds("minutes-of-meeting", response));
  } catch (err) {
    res.status(500).json({ message: "Failed to fetch" });
  }
};

const getSingleMinutesOfMeeting = async (req, res) => {
  const { id } = req.params;

  try {
    const minutesOfMeeting = await MinutesOfMeeting.findByPk(id, {
      include: [Projects],
    });

    if (!minutesOfMeeting) {
      return res.status(404).json({ message: "Minutes of meeting not found" });
    }

    const responseData = {
      ...JSON.parse(minutesOfMeeting.data),
      id: minutesOfMeeting.id,
      project: minutesOfMeeting.Project.name,
    };

    const response = {
      data: addFormattedId("minutes-of-meeting", responseData),
    };

    res.json(response);
  } catch (err) {
    res.status(500).json({ message: "Failed to fetch" });
  }
};

const createMinutesOfMeeting = async (req, res) => {
  const { projectId } = req.query;

  if (!projectId)
    return res.status(400).json({ message: "Project id is required" });

  try {
    const filesData = await uploadFile(req.files);
    const data = { ...JSON.parse(req.body.data), ...filesData };

    const createdMinutesOfMeeting = await MinutesOfMeeting.create({
      data: data,
      ProjectId: projectId,
    });

    // Get formatted ID
    const formattedData = addFormattedId("minutes-of-meeting", {
      id: createdMinutesOfMeeting.id,
    });

    // Get project and assigned by user info for email
    const project = await Projects.findByPk(projectId);
    const assignedByUser = await Users.findByPk(req.user.id);

    // Extract participant user IDs from the data
    const participantIds = [];
    if (data.participants && Array.isArray(data.participants)) {
      for (const participant of data.participants) {
        // If participant has a userId field
        if (participant.userId) {
          participantIds.push(participant.userId);
        }
        // If participant has a name field (which is the user ID)
        else if (participant.name) {
          participantIds.push(parseInt(participant.name));
        }
        // If participant is just a user ID
        else if (typeof participant === "number") {
          participantIds.push(participant);
        }
      }
    }

    // Extract responsible user IDs from discussion items
    const responsibleIds = [];
    if (data.discussionItems && Array.isArray(data.discussionItems)) {
      for (const item of data.discussionItems) {
        if (item.responsible) {
          const responsibleId = parseInt(item.responsible);
          if (!isNaN(responsibleId) && !responsibleIds.includes(responsibleId)) {
            responsibleIds.push(responsibleId);
          }
        }
      }
    }

    // Combine all user IDs (participants + responsible users) and remove duplicates
    const allUserIds = [...new Set([...participantIds, ...responsibleIds])];

    // Send emails and create notifications for all users
    if (allUserIds.length > 0) {
      for (const userId of allUserIds) {
        const user = await Users.findByPk(userId);
        if (!user) continue;

        // Determine the role of this user
        const isParticipant = participantIds.includes(userId);
        const isResponsible = responsibleIds.includes(userId);
        
        let roleDescription = "";
        if (isParticipant && isResponsible) {
          roleDescription = "participant and responsible person";
        } else if (isParticipant) {
          roleDescription = "participant";
        } else if (isResponsible) {
          roleDescription = "responsible person";
        }

        // Send email to user
        try {
          if (user.email) {
            await sendMinutesOfMeetingEmail({
              to: user.email,
              participantName: user.fullname,
              projectName: project ? project.name : "Unknown Project",
              momId: formattedData.formattedId,
              meetingTitle: data.meeting_title || "Minutes of Meeting",
              meetingDate: data.meeting_date || new Date(),
              assignedBy: assignedByUser ? assignedByUser.fullname : "System",
              role: roleDescription,
            });
          }
        } catch (emailError) {
          console.error("❌ Error sending MOM email:", emailError);
          // Continue even if email fails
        }
      }

      // Create notifications for all users
      await createRiskAssessmentNotification({
        userIds: allUserIds,
        assignedBy: req.user.id,
        companyId: req.user.companyId,
        projectId: projectId,
        riskAssessmentId: createdMinutesOfMeeting.id,
        title: data.meeting_title || "Minutes of Meeting",
        formattedId: formattedData.formattedId,
        priority: "medium",
      });
    }

    res.status(201).json({ message: "Minutes of meeting created successfully" });
  } catch (err) {
    console.error("Error creating minutes of meeting:", err);
    res.status(500).json({ message: "Failed to create" });
  }
};

const updateMinutesOfMeeting = async (req, res) => {
  const { editId } = req.query;

  if (!editId)
    return res.status(400).json({ message: "Minutes of meeting id is required" });

  try {
    let data;
    if (req.files) {
      const filesData = await uploadFile(req.files);
      data = { ...JSON.parse(req.body.data), ...filesData };
    } else {
      data = req.body;
    }

    await MinutesOfMeeting.update(
      {
        data,
      },
      {
        where: {
          id: editId,
        },
      },
    );

    res.status(201).json({
      message: "Minutes of meeting updated successfully",
    });
  } catch (err) {
    res.status(500).json({ message: "Failed to update", err: err.message });
  }
};

module.exports = {
  getMinutesOfMeetings,
  getSingleMinutesOfMeeting,
  createMinutesOfMeeting,
  updateMinutesOfMeeting,
};
