const { RiskAssessment, Projects, Users } = require("../models");
const { addFormattedIds, addFormattedId } = require("../utils/idFormatter");
const {
  createRiskAssessmentNotification,
} = require("../utils/notificationHelper");
const uploadFile = require("../utils/uploadFile");
const { logActivity, getIpAddress, getUserAgent } = require("../utils/activityLogger");

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

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

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

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

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

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

    if (!riskAssessment) {
      return res.status(404).json({ message: "Risk assessment not found" });
    }

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

    const response = {
      data: addFormattedId("risk-assessment", responseData),
    };

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

const createRiskAssessment = 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 createdRiskAssessment = await RiskAssessment.create({
      data: data,
      ProjectId: projectId,
    });

    // Get formatted ID
    const formattedData = addFormattedId("risk-assessment", {
      id: createdRiskAssessment.id,
    });

    // Extract participant user IDs from the data
    // Participants are stored in the data JSON - adjust based on your actual structure
    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 is just a user ID
        else if (typeof participant === "number") {
          participantIds.push(participant);
        }
      }
    }

    // Calculate priority based on highest risk score in sheets
    let notificationPriority = "medium"; // default
    if (data.sheets && Array.isArray(data.sheets)) {
      let maxRiskScore = 0;
      for (const sheet of data.sheets) {
        if (sheet.rows && Array.isArray(sheet.rows)) {
          for (const row of sheet.rows) {
            const likelihood = Number(row.likelihood) || 0;
            const severity = Number(row.severity) || 0;
            const riskScore = likelihood * severity;
            if (riskScore > maxRiskScore) {
              maxRiskScore = riskScore;
            }
          }
        }
      }
      
      // Map risk score to priority
      // Risk score ranges: 1-4 = low, 5-9 = medium, 10-16 = high, 20-25 = urgent
      if (maxRiskScore >= 20) {
        notificationPriority = "urgent";
      } else if (maxRiskScore >= 10) {
        notificationPriority = "high";
      } else if (maxRiskScore >= 5) {
        notificationPriority = "medium";
      } else {
        notificationPriority = "low";
      }
    }

    // Create notifications for all participants
    if (participantIds.length > 0) {
      await createRiskAssessmentNotification({
        userIds: participantIds,
        assignedBy: req.user.id,
        companyId: req.user.companyId,
        projectId: projectId,
        riskAssessmentId: createdRiskAssessment.id,
        title: data.title || "Risk Assessment",
        formattedId: formattedData.formattedId,
        priority: notificationPriority,
      });
    }

    // Log risk assessment creation activity
    await logActivity({
      userId: req.user.id,
      companyId: req.user.companyId,
      projectId: projectId,
      action: "create",
      entityType: "Risk Assessment",
      entityId: createdRiskAssessment.id,
      description: `New risk assessment report created`,
      metadata: {
        riskAssessmentId: formattedData.formattedId,
        title: data.title || "Risk Assessment",
      },
      ipAddress: getIpAddress(req),
      userAgent: getUserAgent(req),
    });

    res.status(201).json({ message: "Risk assessment created successfully" });
  } catch (err) {
    console.error("Error creating risk assessment:", err);
    res.status(500).json({ message: "Failed to create" });
  }
};

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

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

  try {
    const riskAssessment = await RiskAssessment.findByPk(editId, {
      include: [Projects],
    });

    if (!riskAssessment) {
      return res.status(404).json({ message: "Risk assessment not found" });
    }

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

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

    // Get formatted ID
    const formattedData = addFormattedId("risk-assessment", {
      id: riskAssessment.id,
    });

    // Log risk assessment edit activity
    await logActivity({
      userId: req.user.id,
      companyId: req.user.companyId,
      projectId: riskAssessment.ProjectId,
      action: "edit",
      entityType: "Risk Assessment",
      entityId: riskAssessment.id,
      description: `Risk assessment report updated`,
      metadata: {
        riskAssessmentId: formattedData.formattedId,
        title: data.title || "Risk Assessment",
      },
      ipAddress: getIpAddress(req),
      userAgent: getUserAgent(req),
    });

    res.status(201).json({
      message: "Risk assessment updated successfully",
    });
  } catch (err) {
    console.error("Error updating risk assessment:", err);
    res.status(500).json({ message: "Failed to update", err: err.message });
  }
};

module.exports = {
  getRiskAssessments,
  getSingleRiskAssessment,
  createRiskAssessment,
  updateRiskAssessment,
};
