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

// Map tool types to entity types for ID formatting
const getEntityTypeForTool = (toolType) => {
  const typeMap = {
    "toolbox-talk": "toolbox-talk",
    "job-safety-analysis": "job-safety-analysis",
    "pre-task-checklist": "pre-task-checklist",
    "equipment-control": "equipment-control",
    "minutes-of-meeting": "minutes-of-meeting",
  };
  return typeMap[toolType] || toolType;
};

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

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

    const response = safetyTools.map(({ data, Project, id }) => {
      const parsedData = JSON.parse(data);

      const convertedData = Object.fromEntries(
        Object.entries(parsedData).map(([key, value]) => [
          key,
          typeof value === "boolean" ? (value ? "Yes" : "No") : value,
        ]),
      );

      return {
        ...convertedData,
        id,
        project: Project.name,
      };
    });

    // Add formatted IDs based on tool type
    const entityType = getEntityTypeForTool(toolType);
    res.json(addFormattedIds(entityType, response));
  } catch (err) {
    res.status(500).json({ message: "Failed to fetch" });
  }
};

const getSafetyTool = async (req, res) => {
  const { id: idFromURL } = req.params;

  try {
    const safetyTool = await SafetyTools.findByPk(idFromURL, {
      include: [Projects],
    });

    if (!safetyTool)
      return res.status(404).json({ message: "Safety tool not found" });

    const { data, Project, id, toolType } = safetyTool;

    const parsedData = JSON.parse(data);

    const convertedData = Object.fromEntries(
      Object.entries(parsedData).map(([key, value]) => [
        key,
        typeof value === "boolean" ? (value ? "Yes" : "No") : value,
      ]),
    );

    const response = {
      ...convertedData,
      id,
      project: Project.name,
    };

    // Add formatted IDs based on tool type
    const entityType = getEntityTypeForTool(toolType);
    res.json({ data: addFormattedIds(entityType, response) });
  } catch (err) {
    res.status(500).json({ message: "Failed to fetch" });
  }
};

const createSafetyTool = async (req, res) => {
  const { projectId, toolType } = req.query;
  if (!projectId)
    return res.status(400).json({ message: "Project id is required" });
  if (!toolType)
    return res.status(400).json({ message: "Tool type 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;
    }

    const createdTool = await SafetyTools.create({
      toolType,
      data,
      ProjectId: projectId,
    });

    // Get formatted ID
    const entityType = getEntityTypeForTool(toolType);
    const formattedTool = addFormattedId(entityType, {
      id: createdTool.id,
    });

    // Map tool type to display name
    const toolTypeDisplayMap = {
      "toolbox-talk": "Toolbox Meeting",
      "toolbox-meeting": "Toolbox Meeting",
      "job-safety-analysis": "Job Safety Analysis",
      "pre-task-checklist": "Pre-Task Checklist",
      "equipment-control": "Equipment Control",
      "equipment-controller": "Equipment Control",
      "minutes-of-meeting": "Minutes of Meeting",
    };
    const displayName = toolTypeDisplayMap[toolType] || "Safety Tools";

    // Log safety tool creation activity
    await logActivity({
      userId: req.user.id,
      companyId: req.user.companyId,
      projectId: projectId,
      action: "create",
      entityType: displayName,
      entityId: createdTool.id,
      description: `New ${displayName.toLowerCase()} report created`,
      metadata: {
        toolId: formattedTool.formattedId,
        toolType: toolType,
      },
      ipAddress: getIpAddress(req),
      userAgent: getUserAgent(req),
    });

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

const updateSafetyTool = async (req, res) => {
  const { editId } = req.query;
  if (!editId)
    return res.status(400).json({ message: "Safety tool id is required" });

  try {
    const safetyTool = await SafetyTools.findByPk(editId, {
      include: [Projects],
    });
    if (!safetyTool)
      return res.status(404).json({ message: "Safety tool 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 SafetyTools.update(
      {
        data,
      },
      {
        where: {
          id: editId,
        },
      },
    );

    // Get formatted ID
    const entityType = getEntityTypeForTool(safetyTool.toolType);
    const formattedTool = addFormattedId(entityType, {
      id: safetyTool.id,
    });

    // Map tool type to display name
    const toolTypeDisplayMap = {
      "toolbox-talk": "Toolbox Meeting",
      "toolbox-meeting": "Toolbox Meeting",
      "job-safety-analysis": "Job Safety Analysis",
      "pre-task-checklist": "Pre-Task Checklist",
      "equipment-control": "Equipment Control",
      "equipment-controller": "Equipment Control",
      "minutes-of-meeting": "Minutes of Meeting",
    };
    const displayName = toolTypeDisplayMap[safetyTool.toolType] || "Safety Tools";

    // Log safety tool edit activity
    await logActivity({
      userId: req.user.id,
      companyId: req.user.companyId,
      projectId: safetyTool.ProjectId,
      action: "edit",
      entityType: displayName,
      entityId: safetyTool.id,
      description: `${displayName} report updated`,
      metadata: {
        toolId: formattedTool.formattedId,
        toolType: safetyTool.toolType,
      },
      ipAddress: getIpAddress(req),
      userAgent: getUserAgent(req),
    });

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

module.exports = {
  getSafetyTools,
  createSafetyTool,
  getSafetyTool,
  updateSafetyTool,
};
