const boom = require("boom");
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken'); 
const customJwtAuth = require("../customAuthJwt");
const { Deparments } = require("../models/Department");
const { Install, SensorStock, SensorQuotation, Order, Insensors, MasterSlaveData, ElectrictyWorkPictures, PlumbingWorkPictures, MaterialRecievedPictures, Support } = require("../models/store");
const { Counter, User } = require("../models/User");
const { IotData, Tank } = require("../models/tanks");
const moment = require('moment-timezone');

const fastify = require("fastify")({
  logger: true,
  //disableRequestLogging: true,
  genReqId(req) {
    // you get access to the req here if you need it - must be a synchronous function
    return uuidv4();
  },
});


const generateTeamMemberId = async () => {
    var result = await Counter.findOneAndUpdate(
      { _id: 'teamMemberId_id' },
      { $inc: { seq: 1 } },
      { upsert: true, new: true }
    );
  
    return result.seq;
  };


exports.createTeamMember = async (request, reply) => {
    try {
      const { departmentId, firstName, phone, password,email,alternativePhone ,status} = request.body;
  
      // Check if installation exists
      const installation = await Deparments.findOne({ departmentId });
  
      if (!installation) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "Installation not found",
          },
        });
      }
  
      // Check if phone number already exists in the team
      const existingMember = installation.team_member.team_member.find(
        (member) => member.phone === phone
      );
  
      if (existingMember) {
        return reply.status(400).send({
          simplydata: {
            error: true,
            message: "Phone number already exists in the team",
          },
        });
      }
  
      // Hash password
      const hashedPassword = await bcrypt.hash(password, 10);

      const c_id = await generateTeamMemberId();
      const teamMemberId = `AWTM${c_id}`;
      // Create new team member
      const newTeamMember = {
        teamMemberId,
        firstName,
        phone,
        email,
        alternativePhone,
        installationTeamMemId: departmentId,
        password: hashedPassword,
        status,
      };
  
      // Add to team members array
      installation.team_member.team_member.push(newTeamMember);
      await installation.save();
  
      return reply.send({
        simplydata: {
          error: false,
          message: "Team member created successfully",
          teamMemberId: newTeamMember.teamMemberId,
        },
      });
  
    } catch (err) {
      console.error("Error creating team member:", err);
      reply.status(500).send({
        simplydata: {
          error: true,
          message: "Internal server error",
        },
      });
    }
  };
  

  exports.getTeamMembers = async (request, reply) => {
    try {
      const { departmentId } = request.params; // ✅ Get departmentId from request params
  
      // ✅ Find the department using departmentId
      const department = await Deparments.findOne({ departmentId });
  
      if (!department) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "Department not found",
          },
        });
      }
  
      // ✅ Extract team members from department schema
      const teamMembers = department.team_member.team_member;
  
      return reply.send({
        simplydata: {
          error: false,
          message: "Team members retrieved successfully",
          teamMembers, // ✅ Return the list of team members
        },
      });
  
    } catch (err) {
      console.error("Error fetching team members:", err);
      reply.status(500).send({
        simplydata: {
          error: true,
          message: "Internal server error",
        },
      });
    }
  };

//   exports.assignTeamMemberToQuotation = async (request, reply) => {
//     try {
//         const { installationId } = request.params; // Get installationId from URL params
//         const { teamMemberId } = request.body; // Get teamMemberId from request body

//         if (!teamMemberId) {
//             return reply.status(400).send({
//                 simplydata: {
//                     error: true,
//                     message: "teamMemberId is required",
//                 },
//             });
//         }

//         // Find installation by installationId
//         const installation = await Install.findOne({ installationId });

//         if (!installation) {
//             return reply.status(404).send({
//                 simplydata: {
//                     error: true,
//                     message: "Installation not found",
//                 },
//             });
//         }

//         // Extract team members list
//         const teamMembers = installation.team_member.team_member;

//         // Check if provided teamMemberId exists in the installation's team
//         const assignedTeamMember = teamMembers.find(member => member.teamMemberId === teamMemberId);

//         if (!assignedTeamMember) {
//             return reply.status(404).send({
//                 simplydata: {
//                     error: true,
//                     message: "Team member not found in this installation",
//                 },
//             });
//         }

//         // Here, you would save the assigned team member to the quotation (modify as needed)
//         const quotation = {
//             installationId,
//             assignedTeamMember
//         };

//         return reply.send({
//             simplydata: {
//                 error: false,
//                 message: "Team member assigned to quotation successfully",
//                 quotation
//             },
//         });

//     } catch (err) {
//         console.error("Error assigning team member to quotation:", err);
//         reply.status(500).send({
//             simplydata: {
//                 error: true,
//                 message: "Internal server error",
//             },
//         });
//     }
// };

exports.assignTeamMemberToQuotation = async (request, reply) => {
  try {
    const { installationId } = request.params;
    const { teamMemberId, quotationId } = request.body;

    if (!teamMemberId || !quotationId) {
      return reply.status(400).send({
        simplydata: {
          error: true,
          message: "Both teamMemberId and quotationId are required",
        },
      });
    }

    // 🔹 Find installation by installationId
    const installation = await Install.findOne({ installationId });

    if (!installation) {
      return reply.status(404).send({
        simplydata: {
          error: true,
          message: "Installation not found",
        },
      });
    }

    // 🔹 Extract team members list
    const teamMembers = installation.team_member?.team_member || [];

    // 🔹 Check if the provided teamMemberId exists in the installation's team
    const assignedTeamMember = teamMembers.find(
      (member) => member.teamMemberId === teamMemberId
    );

    if (!assignedTeamMember) {
      return reply.status(404).send({
        simplydata: {
          error: true,
          message: "Team member not found in this installation",
        },
      });
    }

    // 🔹 Find or create the quotation for the given installationId
    let quotation = await Order.findOne({ installationId, quatationId: quotationId });

    if (!quotation) {
      quotation = new Order({
        installationId,
        quatationId: quotationId,
        assignedTeamMembers: [], // Ensure assignedTeamMembers array is initialized
        quatation_status: "Pending", // Default status when created
      });
    }

    // 🔹 Assign the team member to the quotation
    if (!quotation.assignedTeamMembers) {
      quotation.assignedTeamMembers = [];
    }

    if (!quotation.assignedTeamMembers.includes(teamMemberId)) {
      quotation.assignedTeamMembers.push(teamMemberId);
    }

    // 🔹 Update order status when a team member is assigned
    quotation.quatation_status = "Assigned"; // Update status

    // 🔹 Save the updated quotation in the Order schema
    await quotation.save();

    // 🔹 Update Installation schema with quotationId
    installation.quatationId = quotationId;
    await installation.save();

    return reply.send({
      simplydata: {
        error: false,
        message: "Team member assigned to quotation successfully",
        quotation,
      },
    });

  } catch (err) {
    console.error("Error assigning team member to quotation:", err);
    reply.status(500).send({
      simplydata: {
        error: true,
        message: "Internal server error",
      },
    });
  }
};

  exports.getAllInstallers = async (request, reply) => {
    try {
      const { departmentName } = request.params; // Get installationId from request params
  
      // Check if installation exists
      const installationList = await Deparments.find({ departmentName });
  
      if (!installationList) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "Installation not found",
          },
        });
      }
  
     
  
      return reply.send({
        simplydata: {
          error: false,
          installationList, // Return the list of team members
        },
      });
  
    } catch (err) {
      console.error("Error fetching team members:", err);
      reply.status(500).send({
        simplydata: {
          error: true,
          message: "Internal server error",
        },
      });
    }
  };
  
  exports.editTeamMember = async (request, reply) => {
    try {
      const { installationId, teamMemberId } = request.params;
      const updateData = request.body;
  
      // Find the installation
      const installation = await Install.findOne({ installationId });
  
      if (!installation) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "Installation not found",
          },
        });
      }
  
      // Find the team member
      let teamMember = installation.team_member.team_member.find(
        (member) => member.teamMemberId === teamMemberId
      );
  
      if (!teamMember) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "Team member not found",
          },
        });
      }
  
      // Update fields
      Object.assign(teamMember, updateData);
  
      // Save changes
      await installation.markModified("team_member.team_member");
      await installation.save();
  
      return reply.send({
        simplydata: {
          error: false,
          message: "Team member updated successfully",
        },
      });
  
    } catch (err) {
      console.error("Error updating team member:", err);
      reply.status(500).send({
        simplydata: {
          error: true,
          message: "Internal server error",
        },
      });
    }
  };

  exports.deleteTeamMember = async (request, reply) => {
    try {
      const { installationId, teamMemberId } = request.params;
  
      // Find the installation
      const installation = await Install.findOne({ installationId });
  
      if (!installation) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "Installation not found",
          },
        });
      }
  
      // Find index of the team member
      const memberIndex = installation.team_member.team_member.findIndex(
        (member) => member.teamMemberId === teamMemberId
      );
  
      if (memberIndex === -1) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "Team member not found",
          },
        });
      }
  
      // Remove the team member from the array
      installation.team_member.team_member.splice(memberIndex, 1);
  
      // Save changes
      await installation.markModified("team_member.team_member");
      await installation.save();
  
      return reply.send({
        simplydata: {
          error: false,
          message: "Team member deleted successfully",
        },
      });
  
    } catch (err) {
      console.error("Error deleting team member:", err);
      reply.status(500).send({
        simplydata: {
          error: true,
          message: "Internal server error",
        },
      });
    }
  };
  

  exports.getQuotationsByInstallationId = async (request, reply) => {
    try {
      const { installationId } = request.params;
  
      if (!installationId) {
        return reply.status(400).send({
          simplydata: {
            error: true,
            message: "Installation ID is required",
          },
        });
      }
  
      // 🔹 Fetch quotations based on installationId
      const quotations = await Order.find({ installationId });
  
      if (!quotations || quotations.length === 0) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "No quotations found for this installation ID",
          },
        });
      }
  
      return reply.send({
        simplydata: {
          error: false,
          message: "Quotations fetched successfully",
          quotations,
        },
      });
    } catch (err) {
      console.error("Error fetching quotations:", err);
      reply.status(500).send({
        simplydata: {
          error: true,
          message: "Internal server error",
        },
      });
    }
  };
  
  exports.getQuotationsByInstallationAndTeamMember = async (request, reply) => {
    try {
      const { installationId, teamMemberId } = request.params;
  
      if (!installationId || !teamMemberId) {
        return reply.status(400).send({
          simplydata: {
            error: true,
            message: "Both installationId and teamMemberId are required",
          },
        });
      }
  
      // 🔹 Fetch quotations where installationId matches and teamMemberId is assigned
      const quotations = await Order.find({
        installationId,
        assignedTeamMembers: teamMemberId,
      });
  
      if (!quotations || quotations.length === 0) {
        return reply.status(404).send({
          simplydata: {
            error: true,
            message: "No quotations found for this installation and team member",
          },
        });
      }
  
      return reply.send({
        simplydata: {
          error: false,
          message: "Quotations fetched successfully",
          quotations,
        },
      });
    } catch (err) {
      console.error("Error fetching quotations:", err);
      reply.status(500).send({
        simplydata: {
          error: true,
          message: "Internal server error",
        },
      });
    }
  };

  exports.getDepartmentByFirstName = async (req, reply) => {
    try {
      let { firstName } = req.params;
  
      if (!firstName) {
        return reply.status(400).send({
          simplydata: { error: true, message: "firstName is required" },
        });
      }
  
      // Trim and convert to lowercase
      firstName = firstName.trim().toLowerCase();
      console.log("Searching for firstName:", firstName); // Debugging log
  
      // Search for the department with case-insensitive and space-tolerant regex
      const department = await Deparments.findOne({
        firstName: { $regex: `^\\s*${firstName}\\s*$`, $options: "i" }
      }).lean();
  
      console.log("Department found:", department); // Debugging log
  
      if (!department) {
        return reply.status(404).send({
          simplydata: { error: true, message: "Department not found" },
        });
      }
  
      return reply.send({
        simplydata: {
          error: false,
          message: "Department details fetched successfully",
          firstName: department.firstName,
          phone: department.phone,
        },
      });
  
    } catch (err) {
      console.error("Error fetching department details:", err);
      return reply.status(500).send({
        simplydata: { error: true, message: "Internal server error" },
      });
    }
  };

 // const moment = require('moment-timezone');

 exports.getByHardwareId = async (req, reply) => {
  try {
    const { hardwareId } = req.params;

    if (!hardwareId) {
      return reply.status(400).send({ error: "hardwareId is required" });
    }

    console.log("Fetching details for hardwareId:", hardwareId);

    const iotData = await IotData.find({ hardwareId })
      .sort({ date: -1 })
      .limit(3)
      .lean();

    if (!iotData || iotData.length === 0) {
      return reply.send({ status_code: 404, message: "IoT Data not found", data: null });
    }

    const latestRecord = iotData[0];
    const indiaTime = moment.tz(latestRecord.date, "Asia/Kolkata");
    const connected_gsm_date = indiaTime.format("DD-MM-YYYY");
    const connected_gsm_time = indiaTime.format("HH:mm:ss");

    const now = moment.tz("Asia/Kolkata");
    const diffInMinutes = now.diff(indiaTime, "minutes");
    const isGSMConnected = diffInMinutes <= 1;
    const gsmStatus = isGSMConnected ? "connected" : "disconnected";
    const gsmLastCheckTime = now.format("DD-MM-YYYY HH:mm:ss");

    await Insensors.findOneAndUpdate(
      { hardwareId },
      {
        $set: {
          connected_gsm_date,
          connected_gsm_time,
          connected_status: gsmStatus,
          gsm_last_check_time: gsmLastCheckTime
        }
      }
    );

    const tanksWithConnectionStatus = latestRecord.tanks.map(tank => {
      const tankMoment = moment.tz(tank.date, "Asia/Kolkata");
      const tankDiff = now.diff(tankMoment, "minutes");

      return {
        ...tank,
        connected_status: tankDiff <= 1 ? "connected" : "disconnected"
      };
    });

    // 🔁 Raise ticket if applicable
    const sensor = await Insensors.findOne({ hardwareId }).lean();
    if (sensor?.customerId) {
      //await raiseATicketLikeLogic(sensor.customerId, hardwareId);
    }

    return reply.send({
      status_code: 200,
      message: "Success",
      data: {
        hardwareId,
        gsm_connected_status: gsmStatus,
        gsmStatus: isGSMConnected ? "GSM Connected" : "GSM Not Connected",
        connected_gsm_date,
        connected_gsm_time,
        gsm_last_check_time: gsmLastCheckTime,
        tanks: tanksWithConnectionStatus,
        date: latestRecord.date,
        time: latestRecord.time
      }
    });
  } catch (err) {
    console.error("Error in getByHardwareId:", err);
    return reply.status(500).send({ error: "Internal Server Error" });
  }
};



exports.getByHardwareIdSupport = async (req, reply) => {
  try {
    const { hardwareId } = req.params;

    if (!hardwareId) {
      return reply.status(400).send({ error: "hardwareId is required" });
    }

    console.log("Fetching details for hardwareId:", hardwareId);

    const iotData = await IotData.find({ hardwareId })
      .sort({ date: -1 })
      .limit(3)
      .lean();

    if (!iotData || iotData.length === 0) {
      return reply.send({ status_code: 404, message: "IoT Data not found", data: null });
    }

    const latestRecord = iotData[0];
    const indiaTime = moment.tz(latestRecord.date, "Asia/Kolkata");
    const connected_gsm_date = indiaTime.format("DD-MM-YYYY");
    const connected_gsm_time = indiaTime.format("HH:mm:ss");

    const now = moment.tz("Asia/Kolkata");
    const diffInMinutes = now.diff(indiaTime, "minutes");
    const isGSMConnected = diffInMinutes <= 1;
    const gsmStatus = isGSMConnected ? "connected" : "disconnected";
    const gsmLastCheckTime = now.format("DD-MM-YYYY HH:mm:ss");

    await Insensors.findOneAndUpdate(
      { hardwareId },
      {
        $set: {
          connected_gsm_date,
          connected_gsm_time,
          connected_status: gsmStatus,
          support_gsm_last_check_time: gsmLastCheckTime
        }
      }
    );

    const tanksWithConnectionStatus = latestRecord.tanks.map(tank => {
      const tankMoment = moment.tz(tank.date, "Asia/Kolkata");
      const tankDiff = now.diff(tankMoment, "minutes");

      return {
        ...tank,
        connected_status: tankDiff <= 1 ? "connected" : "disconnected"
      };
    });

    // 🔁 Raise ticket if applicable
    const sensor = await Insensors.findOne({ hardwareId }).lean();
    if (sensor?.customerId) {
      //await raiseATicketLikeLogic(sensor.customerId, hardwareId);
    }

    return reply.send({
      status_code: 200,
      message: "Success",
      data: {
        hardwareId,
        gsm_connected_status: gsmStatus,
        gsmStatus: isGSMConnected ? "GSM Connected" : "GSM Not Connected",
        connected_gsm_date,
        connected_gsm_time,
        support_gsm_last_check_time: gsmLastCheckTime,
        tanks: tanksWithConnectionStatus,
        date: latestRecord.date,
        time: latestRecord.time
      }
    });
  } catch (err) {
    console.error("Error in getByHardwareId:", err);
    return reply.status(500).send({ error: "Internal Server Error" });
  }
};


exports.getByHardwareIdSupportTeamMember = async (req, reply) => {
  try {
    const { hardwareId } = req.params;

    if (!hardwareId) {
      return reply.status(400).send({ error: "hardwareId is required" });
    }

    console.log("Fetching details for hardwareId:", hardwareId);

    const iotData = await IotData.find({ hardwareId })
      .sort({ date: -1 })
      .limit(3)
      .lean();

    if (!iotData || iotData.length === 0) {
      return reply.send({ status_code: 404, message: "IoT Data not found", data: null });
    }

    const latestRecord = iotData[0];

    const indiaTime = moment.tz(latestRecord.date, "Asia/Kolkata");
    const connected_gsm_date = indiaTime.format("DD-MM-YYYY");
    const connected_gsm_time = indiaTime.format("HH:mm:ss");

    const now = moment.tz("Asia/Kolkata");
    const diffInMinutes = now.diff(indiaTime, "minutes");
    const isGSMConnected = diffInMinutes <= 1;
    const gsmStatus = isGSMConnected ? "connected" : "disconnected";

    const gsmLastCheckTime = now.format("DD-MM-YYYY HH:mm:ss"); // formatted current time

    // ✅ Update slaves connected to this master hardwareId
    await Insensors.updateMany(
      { connected_to: hardwareId },
      {
        $set: {
          connected_gsm_date,
          connected_gsm_time,
          connected_status: gsmStatus,
          team_member_support_gsm_last_check_time: gsmLastCheckTime
        }
      }
    );

    // ✅ Update the master device itself (if it's a master)
    await Insensors.updateOne(
      { hardwareId },
      {
        $set: {
          connected_gsm_date,
          connected_gsm_time,
          connected_status: gsmStatus,
          team_member_support_gsm_last_check_time: gsmLastCheckTime
        }
      }
    );

    // ✅ Annotate tanks with LoRa connection status
    const tanksWithConnectionStatus = latestRecord.tanks.map(tank => {
      const tankMoment = moment.tz(tank.date, "Asia/Kolkata");
      const tankDiff = now.diff(tankMoment, "minutes");

      return {
        ...tank,
        connected_status: tankDiff <= 1 ? "connected" : "disconnected"
      };
    });

    // ✅ Response
    return reply.send({
      status_code: 200,
      message: "Success",
      data: {
        hardwareId,
        gsm_connected_status: gsmStatus,
        gsmStatus: isGSMConnected ? "GSM Connected" : "GSM Not Connected",
        connected_gsm_date,
        connected_gsm_time,
        team_member_support_gsm_last_check_time: gsmLastCheckTime,
        tanks: tanksWithConnectionStatus,
        date: latestRecord.date,
        time: latestRecord.time
      }
    });

  } catch (err) {
    console.error("Error in getByHardwareIdSupport:", err);
    return reply.status(500).send({ error: "Internal Server Error" });
  }
};

exports.getByHardwareAndTankId = async (req, reply) => {
  try {
    const { hardwareId, tankhardwareId } = req.params;

    if (!hardwareId || !tankhardwareId) {
      return reply.status(400).send({ error: "Both hardwareId and tankhardwareId are required" });
    }

    console.log("📡 Fetching data for:", { hardwareId, tankhardwareId });

    // Get the latest IoT data for the master hardwareId
    const latestData = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();

    if (!latestData || !Array.isArray(latestData.tanks)) {
      return reply.code(404).send({ message: "No data found for given hardwareId and tankhardwareId" });
    }

    const now = new Date();
    const dataDate = new Date(latestData.date);

    // Check master GSM connection (threshold 60 sec)
    const isGSMConnected = now - dataDate <= 60000;

    // Find the tank for the slave
    const matchedTank = latestData.tanks.find(tank => tank.tankhardwareId === tankhardwareId);
    if (!matchedTank) {
      return reply.code(404).send({ message: "Tank not found in latest record" });
    }

    const tankHeight = parseFloat(matchedTank.tankHeight || "0");

    // If master is disconnected => slave is disconnected too
    let isLoraConnected = false;
    if (!isGSMConnected) {
      isLoraConnected = false;
    } else {
      // Otherwise use tankHeight to determine LoRa connection
      isLoraConnected = tankHeight > 0;
    }

    // Format tank date/time to IST
    const matchedTankDateObj = new Date(matchedTank.date);
    const formattedDate = moment(matchedTankDateObj).tz("Asia/Kolkata").format("DD-MM-YYYY");
    const formattedTime = matchedTank.time || moment(matchedTankDateObj).tz("Asia/Kolkata").format("HH:mm:ss");

    matchedTank.date = formattedDate;
    matchedTank.time = formattedTime;

    // Prepare update object for Insensors collection
    const updateFields = {
      connected_status: isLoraConnected ? "connected" : "disconnected",
      connected_lora_date: formattedDate,
      connected_lora_time: formattedTime,
      lora_last_check_time: moment().tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm:ss")
    };
    const sensorDoc = await Insensors.findOne({
      tankhardwareId: tankhardwareId,
      connected_to: hardwareId
    });
    
    if (!sensorDoc) {
      console.warn("⚠️ No Insensors doc found for LoRa update:", { tankhardwareId, connected_to: hardwareId });
    
      const fallbackDoc = await Insensors.findOne({ tankhardwareId: tankhardwareId });
      if (fallbackDoc) {
        await Insensors.updateOne({ _id: fallbackDoc._id }, { $set: updateFields });
        console.log("⚠️ Fallback Insensors updated by tankhardwareId:", fallbackDoc._id);
      }
    } else {
      await Insensors.updateOne({ _id: sensorDoc._id }, { $set: updateFields });
      console.log("✅ Insensors LoRa status updated:", sensorDoc._id);
    }
    
    return reply.send({
      status_code: 200,
      message: isLoraConnected ? "LoRa connected" : "LoRa not connected",
      data: matchedTank,
      lora_connected_status: updateFields.connected_status,
      connected_lora_date: updateFields.connected_lora_date,
      connected_lora_time: updateFields.connected_lora_time,
      lora_last_check_time: updateFields.lora_last_check_time
    });

  } catch (err) {
    console.error("❌ Error in getByHardwareAndTankId:", err);
    return reply.status(500).send({ error: "Internal Server Error" });
  }
};




exports.getByHardwareAndTankIdSupport = async (req, reply) => {
  try {
    const { hardwareId, tankhardwareId } = req.params;

    if (!hardwareId || !tankhardwareId) {
      return reply.status(400).send({ error: "Both hardwareId and tankhardwareId are required" });
    }

    console.log("Fetching tank data for:", { hardwareId, tankhardwareId });

    const latestData = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();

    if (!latestData || !Array.isArray(latestData.tanks)) {
      return reply.code(404).send({ message: "No data found for given hardwareId and tankhardwareId" });
    }

    const now = new Date();
    const dataDate = new Date(latestData.date);
    const diffInMs = now - dataDate;
    const isGSMConnected = diffInMs <= 60000;

    const matchedTank = latestData.tanks.find(tank => tank.tankhardwareId === tankhardwareId);

    if (!matchedTank) {
      return reply.code(404).send({ message: "Tank not found in latest record" });
    }

    const tankHeight = parseFloat(matchedTank.tankHeight || "0");
    const isLoraConnected = isGSMConnected && tankHeight > 0;

    const matchedTankDateObj = new Date(matchedTank.date);
    const day = String(matchedTankDateObj.getDate()).padStart(2, '0');
    const month = String(matchedTankDateObj.getMonth() + 1).padStart(2, '0');
    const year = matchedTankDateObj.getFullYear();
    const formattedDate = `${day}-${month}-${year}`;
    matchedTank.date = formattedDate;

    const support_lora_last_check_time = moment.tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm:ss");

    const updateFields = {
      connected_status: isLoraConnected ? "connected" : "disconnected",
      support_lora_last_check_time
    };

    let connected_lora_date = null;
    let connected_lora_time = null;

    if (isLoraConnected) {
      connected_lora_date = formattedDate;
      connected_lora_time = matchedTank.time || matchedTankDateObj.toTimeString().split(" ")[0];
      updateFields.connected_lora_date = connected_lora_date;
      updateFields.connected_lora_time = connected_lora_time;
    }

    // Support both slave and master structure
    const updatedSensor = await Insensors.findOneAndUpdate(
      {
        $or: [
          { connected_to: hardwareId, tankhardwareId: tankhardwareId }, // slave
          { hardwareId: tankhardwareId } // master
        ]
      },
      { $set: updateFields },
      { new: true }
    );

    if (!updatedSensor) {
      console.warn("No matching Insensors document found for update");
    } else {
      console.log("Updated support_lora_last_check_time for:", updatedSensor.hardwareId);
    }

    const displayMessage = isLoraConnected ? "LoRa connected" : "LoRa not connected";

    return reply.send({
      status_code: 200,
      message: displayMessage,
      data: matchedTank,
      lora_connected_status: updateFields.connected_status,
      connected_lora_date,
      connected_lora_time,
      support_lora_last_check_time
    });

  } catch (err) {
    console.error("Error in getByHardwareAndTankIdSupport:", err);
    return reply.status(500).send({ error: "Internal Server Error" });
  }
};


exports.getByHardwareAndTankIdSupportTeamMember = async (req, reply) => {
  try {
    const { hardwareId, tankhardwareId } = req.params;

    if (!hardwareId || !tankhardwareId) {
      return reply.status(400).send({ error: "Both hardwareId and tankhardwareId are required" });
    }

    console.log("Fetching tank data for:", { hardwareId, tankhardwareId });

    const latestData = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();

    if (!latestData || !Array.isArray(latestData.tanks)) {
      return reply.code(404).send({ message: "No data found for given hardwareId and tankhardwareId" });
    }

    const now = new Date();
    const dataDate = new Date(latestData.date);
    const diffInMs = now - dataDate;
    const isGSMConnected = diffInMs <= 60000;

    const matchedTank = latestData.tanks.find(tank => tank.tankhardwareId === tankhardwareId);

    if (!matchedTank) {
      return reply.code(404).send({ message: "Tank not found in latest record" });
    }

    const tankHeight = parseFloat(matchedTank.tankHeight || "0");
    const isLoraConnected = isGSMConnected && tankHeight > 0;

    const matchedTankDateObj = new Date(matchedTank.date);
    const day = String(matchedTankDateObj.getDate()).padStart(2, '0');
    const month = String(matchedTankDateObj.getMonth() + 1).padStart(2, '0');
    const year = matchedTankDateObj.getFullYear();
    const formattedDate = `${day}-${month}-${year}`;
    matchedTank.date = formattedDate;

    const team_member_support_lora_last_check_time = moment.tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm:ss");

    const updateFields = {
      connected_status: isLoraConnected ? "connected" : "disconnected",
      team_member_support_lora_last_check_time
    };

    let connected_lora_date = null;
    let connected_lora_time = null;

    if (isLoraConnected) {
      connected_lora_date = formattedDate;
      connected_lora_time = matchedTank.time || matchedTankDateObj.toTimeString().split(" ")[0];
      updateFields.connected_lora_date = connected_lora_date;
      updateFields.connected_lora_time = connected_lora_time;
    }

    // Support both slave and master structure
    const updatedSensor = await Insensors.findOneAndUpdate(
      {
        $or: [
          { connected_to: hardwareId, tankhardwareId: tankhardwareId }, // slave
          { hardwareId: tankhardwareId } // master
        ]
      },
      { $set: updateFields },
      { new: true }
    );

    if (!updatedSensor) {
      console.warn("No matching Insensors document found for update");
    } else {
      console.log("Updated support_lora_last_check_time for:", updatedSensor.hardwareId);
    }

    const displayMessage = isLoraConnected ? "LoRa connected" : "LoRa not connected";

    return reply.send({
      status_code: 200,
      message: displayMessage,
      data: matchedTank,
      lora_connected_status: updateFields.connected_status,
      connected_lora_date,
      connected_lora_time,
      team_member_support_lora_last_check_time
    });

  } catch (err) {
    console.error("Error in getByHardwareAndTankIdSupport:", err);
    return reply.status(500).send({ error: "Internal Server Error" });
  }
};

  
  
exports.getAllocatedSensorsByTank = async (req, reply) => {
  try {
    let { customerId, tankName } = req.params;

    if (!customerId || !tankName) {
      return reply.status(400).send({ error: "customerId and tankName are required" });
    }

    tankName = tankName.trim(); // Trim spaces

    console.log("Querying MongoDB with:", { customerId, tankName, status: "blocked" });

    const allocatedSensors = await Insensors.find({
      customerId,
      tankName: { $regex: `^${tankName}$`, $options: "i" }, // Case-insensitive search
      status: "blocked",
    }).lean();

    if (!allocatedSensors.length) {
      return reply.send({
        status_code: 200,
        message: "No allocated sensors found for this tank",
        allocatedSensors: [],
      });
    }

    return reply.send({
      status_code: 200,
      message: "Allocated sensors fetched successfully",
      allocatedSensors,
    });

  } catch (err) {
    console.error("Error fetching allocated sensors:", err);
    return reply.status(500).send({ error: "Internal server error" });
  }
};


exports.createMasterSlaveData = async (req, reply) => {
  try {
    const { installationId } = req.params;
    const {
      type,
      customerId,
      hardwareId,
      batchno,
      masterId,
      tankName,
      tankLocation,
      materialRecived,
      electricityWork,
      plumbingWork,
      loraCheck
    } = req.body;

    if (!installationId || !hardwareId || !masterId) {
      return reply.status(400).send({ message: "installationId, hardwareId, and masterId are required." });
    }

    // 🔹 Fetch stored electricity work pictures
    const electricityWorkData = await ElectrictyWorkPictures.findOne({
      installationId,
      customerId
    });

    const electricityWorkPictures = electricityWorkData
      ? electricityWorkData.pictureUrl.map(pic => ({ url: pic.url, uploadedAt: new Date() }))
      : [];

    // 🔹 Fetch stored plumbing work pictures
    const plumbingWorkData = await PlumbingWorkPictures.findOne({
      installationId,
      customerId
    });

    const plumbingWorkPictures = plumbingWorkData
      ? plumbingWorkData.pictureUrl.map(pic => ({ url: pic.url, uploadedAt: new Date() }))
      : [];

      const materialRecievedData = await MaterialRecievedPictures.findOne({
        installationId,
        customerId
      });
  
      const materialRecievedPictures = materialRecievedData
        ? materialRecievedData.pictureUrl.map(pic => ({ url: pic.url, uploadedAt: new Date() }))
        : [];

    // 🔹 Save all data to MasterSlaveData
    const newData = new MasterSlaveData({
      installationId,
      type,
      customerId,
      hardwareId,
      batchno,
      masterId,
      tankName,
      tankLocation,
      materialRecived,
      electricityWork,
      plumbingWork,
      loraCheck,
      electricityWorkPictures,
      plumbingWorkPictures,
      materialRecievedPictures
    });

    await newData.save();

    reply.status(201).send({
      message: "Master-Slave data created successfully",
      data: newData
    });

  } catch (err) {
    reply.status(500).send({ message: err.message });
  }
};
exports.masterConnectedSlaveList = async (req, reply) => {
  try {
    const { connectedTo } = req.params;

    // Step 1: Find all slave tanks where connected_to matches
    const slaveTanks = await Insensors.find({ connected_to: connectedTo }).lean();
    console.log(slaveTanks, "slaveTanks");

    if (!slaveTanks || slaveTanks.length === 0) {
      return reply.status(404).send({
        success: false,
        message: "No tanks found for the given connected_to value"
      });
    }

    // Step 2: Fetch `tankLocation` and `typeOfWater` from the Tank schema (for master device display)
    const tankDetails = await Tank.findOne(
      { hardwareId: connectedTo },
      { tankLocation: 1, typeOfWater: 1 }
    );

    if (!tankDetails) {
      return reply.status(404).send({
        success: false,
        message: "Tank details not found for the given connectedTo"
      });
    }

    // Step 3: Count the number of connected slaves
    const slaveCount = slaveTanks.length;

    // Step 4: Fetch latest IotData for the master to extract tankHeight for each slave
    const latestIotData = await IotData.findOne({ hardwareId: connectedTo }).sort({ date: -1 }).lean();

    // Step 5: Prepare processed response for each tank
    const processedSlaves = slaveTanks.map(slave => {
      if (slave.type === 'slave') {
        // Find matching tank data for this slave in IotData
        const matchingTankData = latestIotData?.tanks?.find(tank => tank.tankhardwareId === slave.hardwareId);

        return {
          ...slave,
          tankHeight: matchingTankData?.tankHeight ?? null // Add tankHeight if found
        };
      } else {
        // Remove unnecessary fields for master type
        const {
          tankName,
          tankLocation,
          typeOfWater,
          ...rest
        } = slave;
        return rest;
      }
    });

    return reply.send({
      success: true,
      tankLocation: tankDetails.tankLocation,
      typeOfWater: tankDetails.typeOfWater,
      connectedSlaveCount: slaveCount,
      data: processedSlaves
    });

  } catch (error) {
    console.error("Error fetching master connected slave data:", error);
    return reply.status(500).send({
      success: false,
      message: "Internal Server Error"
    });
  }
};





exports.mastrerList = async (req, reply) => {
  try {
    const { customerId, installationId } = req.params;

    // Step 1: Get User and extract buildingName
    const user = await User.findOne({ customerId  , installationId 
    });

    if (!user) {
      return reply.status(404).send({ success: false, message: "User not found" });
    }

    const { buildingName } = user;

    // Step 2: Get Tanks with matching customerId
    const tanks = await Tank.find({ customerId });

    if (!tanks.length) {
      return reply.status(404).send({ success: false, message: "No tanks found for this customer" });
    }

    const {tankLocation,typeOfWater} = tanks
    //console.log(tanks)
    // Step 3: Extract hardwareId from tanks
    const hardwareIds = tanks.map(tank => tank.hardwareId);

    // Step 4: Find master tanks in InSensors with both customerId and installationId
    const masterTanks = await Insensors.find({
      customerId, 
      connected_to: { $in: hardwareIds },
      type: "master"
    });

    if (!masterTanks.length) {
      return reply.status(404).send({ success: false, message: "No master tanks found" });
    }

    return reply.send({ success: true,tankLocation,typeOfWater ,buildingName, data: masterTanks, user });

  } catch (error) {
    console.error("Error fetching master tanks:", error);
    return reply.status(500).send({ success: false, message: "Internal Server Error" });
  }
};



//const Insensor = mongoose.model('insensors', insensorsSchema); // if not already defined

// exports.getMasterSlaveSummary = async (req, reply) => {
//   const { customerId } = req.params;

//   try {
//     const masters = await Insensors.aggregate([
//       {
//         $match: {
//           customerId,
//           type: "master"
//         }
//       },
//       {
//         $lookup: {
//           from: 'Insensors', // collection name should match MongoDB collection
//           let: { masterId: '$hardwareId' },
//           pipeline: [
//             {
//               $match: {
//                 $expr: {
//                   $and: [
//                     { $eq: ['$type', 'slave'] },
//                     { $eq: ['$customerId', customerId] },
//                     { $eq: ['$connected_to', '$$masterId'] }
//                   ]
//                 }
//               }
//             },
//             {
//               $project: {
//                 _id: 1,
//                 hardwareId: 1,
//                 tankName: 1,
//                 tankLocation: 1,
//                 model: 1,
//                 status: 1,
//                 indate: 1
//               }
//             }
//           ],
//           as: 'connected_slaves'
//         }
//       },
//       {
//         $addFields: {
//           connected_slave_count: { $size: '$connected_slaves' }
//         }
//       },
//       {
//         $project: {
//           _id: 1,
//           hardwareId: 1,
//           tankName: 1,
//           tankLocation: 1,
//           model: 1,
//           status: 1,
//           indate: 1,
//           connected_slave_count: 1,
//           connected_slaves: 1
//         }
//       }
//     ]);

//     const totalMasters = await Insensors.countDocuments({ customerId, type: 'master' });
//     const totalSlaves = await Insensors.countDocuments({ customerId, type: 'slave' });

//     reply.code(200).send({
//       totalMasters,
//       totalSlaves,
//       masters
//     });
//   } catch (err) {
//     console.error(err);
//     reply.code(500).send({ error: 'Server error', details: err.message });
//   }
// }




// exports.getMasterSlaveSummary = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.status(400).send({ message: "Missing customerId" });
//     }

//     const allDevices = await Insensors.find({ customerId });

//     const masters = allDevices.filter(device => device.type === 'master');
//     const slaves = allDevices.filter(device => device.type === 'slave');

//     const enrichDeviceWithTimestamp = async (device) => {
//       const hardwareId = device.hardwareId?.trim();
//       if (!hardwareId) return device.toObject();

//       const latestData = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();
//       const enriched = device.toObject();

//       if (latestData?.date) {
//         const indiaTime = moment.tz(latestData.date, "Asia/Kolkata");
//         const date = indiaTime.format("DD-MM-YYYY");
//         const time = indiaTime.format("HH:mm:ss");
//         const now = moment.tz("Asia/Kolkata");
//         const diffInMinutes = now.diff(indiaTime, "minutes");
//         const isGSMConnected = diffInMinutes <= 1;
//         const gsmStatus = isGSMConnected ? "connected" : "disconnected";

//         if (device.type === 'master') {
//           enriched.connected_gsm_date = date;
//           enriched.connected_gsm_time = time;
//           enriched.gsm_connected_status = gsmStatus;
//           enriched.gsm_last_check_time = indiaTime.format("YYYY-MM-DD HH:mm:ss");
//         }
//       }

//       if (latestData?.tanks && Array.isArray(latestData.tanks)) {
//         const enrichedTanks = latestData.tanks.map(tank => {
//           const tankMoment = moment.tz(tank.date, "Asia/Kolkata");
//           const tankDiff = moment.tz("Asia/Kolkata").diff(tankMoment, "minutes");
//           const loraStatus = tankDiff <= 1 ? "connected" : "disconnected";
//           return {
//             ...tank,
//             connected_status: loraStatus
//           };
//         });

//         enriched.tanks = enrichedTanks;

//         if (device.type === 'slave') {
//           const connectedTank = enrichedTanks.find(tank => tank.tankhardwareId === device.hardwareId);
//           enriched.lora_connected_status = connectedTank ? connectedTank.connected_status : "disconnected";
//           enriched.connected_lora_date = connectedTank ? moment(connectedTank.date).tz("Asia/Kolkata").format("DD-MM-YYYY") : null;
//           enriched.connected_lora_time = connectedTank ? connectedTank.time : null;
//           enriched.lora_last_check_time = connectedTank ? moment(connectedTank.date).tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss") : null;
//         }
//       }

//       if (device.type === 'slave') {
//         delete enriched.connected_gsm_date;
//         delete enriched.connected_gsm_time;
//         delete enriched.gsm_connected_status;
//         delete enriched.gsm_last_check_time;
//       }

//       if (device.type === 'master') {
//         delete enriched.connected_lora_date;
//         delete enriched.connected_lora_time;
//         delete enriched.lora_connected_status;
//         delete enriched.lora_last_check_time;
//         delete enriched.tanks; // ✅ Remove tanks for master
//       }

//       return enriched;
//     };

//     const enrichedMasters = await Promise.all(masters.map(enrichDeviceWithTimestamp));
//     const enrichedSlaves = await Promise.all(slaves.map(enrichDeviceWithTimestamp));

//     const masterSummary = enrichedMasters.map(master => {
//       const connectedSlaves = enrichedSlaves.filter(slave => slave.connected_to === master.connected_to);
//       return {
//         ...master,
//         connected_slave_count: connectedSlaves.length,
//         connected_slaves: connectedSlaves
//       };
//     });

//     return reply.send({
//       status_code: 200,
//       message: "Success",
//       master_count: enrichedMasters.length,
//       slave_count: enrichedSlaves.length,
//       data: masterSummary
//     });

//   } catch (err) {
//     console.error("Error in getMasterSlaveSummary:", err);
//     return reply.status(500).send({
//       status_code: 500,
//       message: "Internal Server Error"
//     });
//   }
// };




// exports.getMasterSlaveSummary = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.status(400).send({ message: "Missing customerId" });
//     }

//     const allDevices = await Insensors.find({ customerId });
//     const masters = allDevices.filter(d => d.type === 'master');
//     const slaves = allDevices.filter(d => d.type === 'slave');

//     const enrichDevice = async (device) => {
//       const enriched = device.toObject();
//       const hardwareId = device.hardwareId?.trim();

//       if (!hardwareId) return enriched;

//       // Fetch latest IotData blindly for this device
//       const latestData = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();

//       if (latestData?.date) {
//         const indiaTime = moment.tz(latestData.date, "Asia/Kolkata");
//         const now = moment.tz("Asia/Kolkata");
//         const diffMins = now.diff(indiaTime, "minutes");
//         const isConnected = diffMins <= 1;

//         enriched.connected_gsm_date = indiaTime.format("DD-MM-YYYY");
//         enriched.connected_gsm_time = indiaTime.format("HH:mm:ss");
//         enriched.gsm_connected_status = isConnected ? "connected" : "disconnected";
//         enriched.gsm_last_check_time = indiaTime.format("YYYY-MM-DD HH:mm:ss");
//       }

//       // Only apply LoRa logic for slaves
//       if (device.type === 'slave' && latestData?.tanks?.length) {
//         const matchingTank = latestData.tanks.find(
//           tank => tank.tankhardwareId?.trim() === hardwareId
//         );

//         if (matchingTank) {
//           const loraTime = moment.tz(matchingTank.date, "Asia/Kolkata");
//           const loraDiff = moment.tz("Asia/Kolkata").diff(loraTime, "minutes");
//           const isLoraConnected = loraDiff <= 1;

//           enriched.connected_lora_date = loraTime.format("DD-MM-YYYY");
//           enriched.connected_lora_time = matchingTank.time;
//           enriched.lora_connected_status = isLoraConnected ? "connected" : "disconnected";
//           enriched.lora_last_check_time = loraTime.format("YYYY-MM-DD HH:mm:ss");
//         } else {
//           enriched.connected_lora_date = null;
//           enriched.connected_lora_time = null;
//           enriched.lora_connected_status = "disconnected";
//           enriched.lora_last_check_time = null;
//         }
//       }

//       // Remove irrelevant fields
//       if (device.type === 'slave') {
//         delete enriched.tanks;
//       }
//       if (device.type === 'master') {
//         delete enriched.connected_lora_date;
//         delete enriched.connected_lora_time;
//         delete enriched.lora_connected_status;
//         delete enriched.lora_last_check_time;
//         delete enriched.tanks;
//       }

//       return enriched;
//     };

//     const enrichedMasters = await Promise.all(masters.map(enrichDevice));
//     const enrichedSlaves = await Promise.all(slaves.map(enrichDevice));

//     const masterSummary = enrichedMasters.map(master => {
//       const connectedSlaves = enrichedSlaves.filter(
//         slave => slave.connected_to === master.connected_to
//       );
//       return {
//         ...master,
//         connected_slave_count: connectedSlaves.length,
//         connected_slaves: connectedSlaves
//       };
//     });

//     return reply.send({
//       status_code: 200,
//       message: "Success",
//       master_count: enrichedMasters.length,
//       slave_count: enrichedSlaves.length,
//       data: masterSummary
//     });

//   } catch (err) {
//     console.error("Error in getMasterSlaveSummary:", err);
//     return reply.status(500).send({
//       status_code: 500,
//       message: "Internal Server Error"
//     });
//   }
// };

// exports.getMasterSlaveSummary = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.status(400).send({ error: 'customerId is required' });
//     }

//     // Fetch all devices for the customer
//     const allDevices = await Insensors.find({ customerId }).lean();

//     // Group devices
//     const masters = allDevices.filter(dev => dev.type === 'master');
//     const slaves = allDevices.filter(dev => dev.type === 'slave');

//     // Create a map of slaves by connected_to hardwareId
//     const slaveMap = {};
//     for (const slave of slaves) {
//       const masterId = slave.connected_to;
//       if (!slaveMap[masterId]) {
//         slaveMap[masterId] = [];
//       }

//       const loraTime = slave.connected_lora_time || null;
//       const loraDate = slave.connected_lora_date || null;

//       slaveMap[masterId].push({
//         hardwareId: slave.hardwareId,
//         tankName: slave.tankName || null,
//         location: slave.tankLocation || null,
//         connected_status: slave.connected_status || 'disconnected',
//         connected_lora_time: loraTime,
//         connected_lora_date: loraDate
//       });
//     }

//     const response = [];

//     for (const master of masters) {
//       // Fetch latest IoT data for this master
//       const latestData = await IotData.findOne({ hardwareId: master.hardwareId })
//         .sort({ date: -1 })
//         .lean();

//       const enriched = {
//         ...master,
//         connected_status: master.connected_status || 'disconnected',
//         connected_slave_count: slaveMap[master.hardwareId]?.length || 0,
//         connected_slaves: slaveMap[master.hardwareId] || []
//       };

//       // Use saved GSM fields from Insensors
//       if (master.gsm_last_check_time) {
//         enriched.gsm_last_check_time = master.gsm_last_check_time;

//         const indiaTime = moment.tz(master.gsm_last_check_time, 'Asia/Kolkata');
//         enriched.connected_gsm_date = indiaTime.format('DD-MM-YYYY');
//         enriched.connected_gsm_time = indiaTime.format('HH:mm:ss');
//       }

//       // If LoRa timestamps are available from master (some masters act like slaves too)
//       if (master.connected_lora_date && master.connected_lora_time) {
//         enriched.connected_lora_date = master.connected_lora_date;
//         enriched.connected_lora_time = master.connected_lora_time;
//       }

//       response.push(enriched);
//     }

//     return reply.send({
//       status_code: 200,
//       message: 'Master-slave summary retrieved successfully',
//       data: response
//     });
//   } catch (err) {
//     console.error('Error in getMasterSlaveSummary:', err);
//     return reply.status(500).send({ error: 'Internal Server Error' });
//   }
// };


// exports.getMasterSlaveSummary = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.status(400).send({ error: 'customerId is required' });
//     }

//     // Fetch all devices for the customer
//     const allDevices = await Insensors.find({ customerId }).lean();

//     // Group devices
//     const masters = allDevices.filter(dev => dev.type === 'master');
//     const slaves = allDevices.filter(dev => dev.type === 'slave');

//     // Create a map of slaves by connected_to hardwareId
//     const slaveMap = {};
//     for (const slave of slaves) {
//       const masterId = slave.connected_to;
//       if (!slaveMap[masterId]) {
//         slaveMap[masterId] = [];
//       }

//       const loraTime = slave.connected_lora_time || null;
//       const loraDate = slave.connected_lora_date || null;

//        // Fetch masterName using the connected_to masterId
//        const master = masters.find(m => m.hardwareId === masterId);
//        const masterName = master ? master.masterName : 'Unknown';

//       slaveMap[masterId].push({
//         hardwareId: slave.hardwareId,
//         tankName: slave.tankName || null,
//         location: slave.tankLocation || null,
//         connected_status: slave.connected_status || 'disconnected',
//         connected_lora_time: loraTime,
//         connected_lora_date: loraDate,
//         type: slave.type || 'N/A',  // Add 'type' field
//         typeOfWater: slave.typeOfWater || 'N/A', // Add 'typeOfWater' field
//         lora_last_check_time: slave.lora_last_check_time && slave.lora_last_check_time 
//           ? `${slave.lora_last_check_time}` 
//           : null, // Add 'lora_last_check_time' field
//           connected_to: slave.connected_to,  // Add 'connected_to' field
//           masterName: masterName  // Add 'masterName' field
//       });
//     }

//     const response = [];

//     for (const master of masters) {
//       // Fetch latest IoT data for this master
//       const latestData = await IotData.findOne({ hardwareId: master.hardwareId })
//         .sort({ date: -1 })
//         .lean();

//       const enriched = {
//         ...master,
//         connected_status: master.connected_status || 'disconnected',
//         connected_slave_count: slaveMap[master.hardwareId]?.length || 0,
//         connected_slaves: slaveMap[master.hardwareId] || []
//       };

//       // Use saved GSM fields from Insensors
//       if (master.gsm_last_check_time) {
//         enriched.gsm_last_check_time = master.gsm_last_check_time;

//         const indiaTime = moment.tz(master.gsm_last_check_time, 'Asia/Kolkata');
//         enriched.connected_gsm_date = indiaTime.format('DD-MM-YYYY');
//         enriched.connected_gsm_time = indiaTime.format('HH:mm:ss');
//       }

//       // If LoRa timestamps are available from master (some masters act like slaves too)
//       if (master.connected_lora_date && master.connected_lora_time) {
//         enriched.connected_lora_date = master.connected_lora_date;
//         enriched.connected_lora_time = master.connected_lora_time;
//       }

//       response.push(enriched);
//     }

//     return reply.send({
//       status_code: 200,
//       message: 'Master-slave summary retrieved successfully',
//       data: response
//     });
//   } catch (err) {
//     console.error('Error in getMasterSlaveSummary:', err);
//     return reply.status(500).send({ error: 'Internal Server Error' });
//   }
// };
// exports.getMasterSlaveSummary = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.status(400).send({ error: 'customerId is required' });
//     }

//     // Fetch all masters for the customer from the Insensors schema
//     const masters = await Insensors.find({ customerId, type: 'master' }).lean();

//     // Fetch orders for the customer to map master connections
//     const orders = await Order.find({ customerId }).lean();

//     const orderMap = {};
//     // Mapping master hardwareId from the orders schema to masterName and location
//     orders.forEach(order => {
//       order.master_connections.forEach(connection => {
//         orderMap[connection.hardwareId] = {
//           masterName: connection.master_name || 'Unknown',
//           location: connection.location || 'Unknown'
//         };
//       });
//     });

//     const result = [];

//     // Loop through each master and enrich it with data
//     for (const master of masters) {
//       const orderInfo = orderMap[master.hardwareId] || {}; // Get order info based on hardwareId
//       const masterName = orderInfo.masterName || 'Unknown';
//       const location = orderInfo.location || 'Unknown';

//       const latestGsmData = await IotData.findOne({ hardwareId: master.hardwareId })
//         .sort({ date: -1, time: -1 })
//         .lean();

//       let connectedGsmDate = null;
//       let connectedGsmTime = null;
//       if (latestGsmData?.date && latestGsmData?.time) {
//         const indiaTime = moment.tz(latestGsmData.date, 'Asia/Kolkata');
//         connectedGsmDate = indiaTime.format('DD-MM-YYYY');
//         connectedGsmTime = latestGsmData.time;
//       }

//       let gsmLastDisconnect = master.gsm_last_disconnect_time;
//       if (master.connected_status === 'disconnected' && connectedGsmDate && connectedGsmTime) {
//         const disconnectTime = `${connectedGsmDate} ${connectedGsmTime}`;
//         await Insensors.updateOne({ hardwareId: master.hardwareId }, { $set: { gsm_last_disconnect_time: disconnectTime } });
//         gsmLastDisconnect = disconnectTime;
//       }

//       const connectedSlaves = [];
//       const slaves = await Insensors.find({ connected_to: master.hardwareId, type: 'slave' }).lean();

//       for (const slave of slaves) {
//         const slaveIot = await IotData.findOne({ hardwareId: slave.hardwareId }).sort({ date: -1, time: -1 }).lean();

//         const loraDate = slave.connected_lora_date || (slaveIot?.date ? moment.tz(slaveIot.date, 'Asia/Kolkata').format('DD-MM-YYYY') : null);
//         const loraTime = slave.connected_lora_time || slaveIot?.time || null;

//         let loraLastDisconnect = slave.lora_last_disconnect_time;
//         if (slave.connected_status === 'disconnected' && loraDate && loraTime) {
//           const disconnectTime = `${loraDate} ${loraTime}`;
//           await Insensors.updateOne({ hardwareId: slave.hardwareId }, { $set: { lora_last_disconnect_time: disconnectTime } });
//           loraLastDisconnect = disconnectTime;
//         }

//         connectedSlaves.push({
//           hardwareId: slave.hardwareId,
//           tankName: slave.tankName,
//           location: slave.tankLocation,
//           connected_status: slave.connected_status,
//           connected_lora_date: loraDate,
//           connected_lora_time: loraTime,
//           lora_last_disconnect_time: loraLastDisconnect,
//           type: slave.type || 'slave'
//         });
//       }

//       result.push({
//         hardwareId: master.hardwareId,
//         masterName,
//         location,
//         type: master.type || 'master',
//         connected_status: master.connected_status,
//         connected_slave_count: connectedSlaves.length,
//         connected_slaves: connectedSlaves,
//         connected_gsm_date: connectedGsmDate,
//         connected_gsm_time: connectedGsmTime,
//         gsm_last_check_time: master.gsm_last_check_time || null,
//         gsm_last_disconnect_time: gsmLastDisconnect,
//         connected_lora_date: master.connected_lora_date || null,
//         connected_lora_time: master.connected_lora_time || null
//       });
//     }

//     return reply.send({
//       status_code: 200,
//       message: 'Master-slave summary retrieved successfully',
//       data: result
//     });

//   } catch (error) {
//     console.error('Error in getMasterSlaveSummary:', error);
//     return reply.status(500).send({ error: 'Internal Server Error' });
//   }
// };



exports.getMasterSlaveSummary = async (req, reply) => {
  try {
    const { customerId } = req.params;

    if (!customerId) {
      return reply.status(400).send({ error: "customerId is required" });
    }

    // Fetch all master devices for the customer
    const masters = await Insensors.find({ customerId, type: "master" }).lean();

    // Fetch orders to map hardwareId to masterName/location
    const orders = await Order.find({ customerId }).lean();
    const orderMap = {};
    orders.forEach(order => {
      order.master_connections.forEach(connection => {
        orderMap[connection.hardwareId] = {
          masterName: connection.master_name || null,
          location: connection.location || null,
        };
      });
    });

    const result = [];

    for (const master of masters) {
      const orderInfo = orderMap[master.hardwareId] || {};

      // Prefer Insensors info, fallback to order info
      const masterName = master.masterName || orderInfo.masterName || null;
      const location = master.location || orderInfo.location || null;

      // Fetch the latest GSM data for the master device
      const latestGsmData = await IotData.findOne({ hardwareId: master.hardwareId })
        .sort({ date: -1, time: -1 })
        .lean();

      let connectedGsmDate = null;
      let connectedGsmTime = null;
      let gsmStatus = "unknown";
      let gsmLastCheckTime = null;
      let gsmLastDisconnect = master.gsm_last_disconnect_time || null;

      if (latestGsmData?.date && latestGsmData?.time) {
        // Combine date + time and parse as Asia/Kolkata timezone
        const indiaTime = moment.tz(
          `${moment(latestGsmData.date).format("YYYY-MM-DD")} ${latestGsmData.time}`,
          "YYYY-MM-DD HH:mm:ss",
          "Asia/Kolkata"
        );

        connectedGsmDate = indiaTime.format("DD-MM-YYYY");
        connectedGsmTime = indiaTime.format("HH:mm:ss");

        const now = moment.tz("Asia/Kolkata");
        const diffInMinutes = now.diff(indiaTime, "minutes");

        gsmStatus = diffInMinutes <= 1 ? "connected" : "disconnected";
        gsmLastCheckTime =master.gsm_last_check_time;

        if (gsmStatus === "disconnected") {
          // Update disconnect time with latest disconnect timestamp
          gsmLastDisconnect = `${connectedGsmDate} ${connectedGsmTime}`;
        }

        // Update master device with latest GSM info
        await Insensors.updateOne(
          { hardwareId: master.hardwareId },
          {
            $set: {
              connected_status: gsmStatus,
              connected_gsm_date: connectedGsmDate,
              connected_gsm_time: connectedGsmTime,
              gsm_last_check_time: gsmLastCheckTime,
              gsm_last_disconnect_time: gsmLastDisconnect,
            },
          }
        );
      }

      // Process connected slave devices for the master
      const connectedSlaves = [];
      const slaves = await Insensors.find({ connected_to: master.hardwareId, type: "slave" }).lean();
      console.log("slaves",slaves)

     
      for (const slave of slaves) {
        const now = moment.tz("Asia/Kolkata");
        let connectedLoraDate = null;
        let connectedLoraTime = null;
        let loraStatus = "disconnected";
        let loraLastDisconnect = slave.lora_last_disconnect_time || null;
        let loraLastCheckTime = slave.lora_last_check_time;
        let tankHeight = null;
      
        // Fetch latest IotData for slave's hardwareId (NOT master's)
        const slaveIot = await IotData.findOne({ hardwareId: slave.connected_to })
          .sort({ date: -1, time: -1 })
          .lean();
      
        if (slaveIot?.tanks?.length && slave.tankhardwareId) {
          const matchedTank = slaveIot.tanks.find(
            t => t.tankhardwareId === slave.tankhardwareId
          );
      
          if (matchedTank) {
            const indiaTime = moment.tz(
              `${moment(matchedTank.date).format("YYYY-MM-DD")} ${matchedTank.time}`,
              "YYYY-MM-DD HH:mm:ss",
              "Asia/Kolkata"
            );
      
            connectedLoraDate = indiaTime.format("DD-MM-YYYY");
            connectedLoraTime = indiaTime.format("HH:mm:ss");
      
            tankHeight = parseFloat(matchedTank.tankHeight) || 0;
      
            const diffMinutes = now.diff(indiaTime, "minutes");
      
            // Connected if tankHeight > 0 and data not older than 5 mins
            loraStatus = (tankHeight > 0 && diffMinutes <= 1) ? "connected" : "disconnected";
      
            if (loraStatus === "disconnected") {
              loraLastDisconnect = `${connectedLoraDate} ${connectedLoraTime}`;
            }
          }
        }
        const matchedTankDetails = await Tank.findOne({
          customerId,
          tankhardwareId: slave.tankhardwareId,
        }).lean();
      
        if (matchedTankDetails?.typeOfWater) {
          typeOfWater = matchedTankDetails.typeOfWater;
        }
        // Update DB with new status and timestamps
        await Insensors.updateOne(
          { hardwareId: slave.hardwareId },
          {
            $set: {
              connected_status: loraStatus,
              connected_lora_date: connectedLoraDate,
              connected_lora_time: connectedLoraTime,
              lora_last_check_time: loraLastCheckTime,
              lora_last_disconnect_time: loraLastDisconnect,
            },
          }
        );
      
        connectedSlaves.push({
          hardwareId: slave.hardwareId,
          tankhardwareId: slave.tankhardwareId || null,
          tankName: slave.tankName || null,
          location: slave.tankLocation || null,
          connected_status: loraStatus,
          connected_lora_date: connectedLoraDate,
          connected_lora_time: connectedLoraTime,
          lora_last_check_time: loraLastCheckTime,
          lora_last_disconnect_time: loraLastDisconnect,
          type: slave.type || "slave",
          typeOfWater,
          connected_to: slave.connected_to || null,
        });
      }
      
      
      
      result.push({
        hardwareId: master.hardwareId,
        masterName,
        location,
        type: master.type || "master",
        connected_status: gsmStatus,
        connected_slave_count: connectedSlaves.length,
        connected_slaves: connectedSlaves,
        connected_gsm_date: connectedGsmDate,
        connected_gsm_time: connectedGsmTime,
        gsm_last_check_time: gsmLastCheckTime,
        gsm_last_disconnect_time: gsmLastDisconnect,
        connected_lora_date: master.connected_lora_date || null,
        connected_lora_time: master.connected_lora_time || null,
      });
    }

    return reply.send({
      status_code: 200,
      message: "Master-slave summary retrieved successfully",
      data: result,
    });
  } catch (error) {
    console.error("Error in getMasterSlaveSummary:", error);
    return reply.status(500).send({ error: "Internal Server Error" });
  }
};




// 🔍 Helper to get tankHeight from latest IotData record
async function getTankHeight(tankhardwareId) {
  const iotData = await IotData.findOne({ 'tanks.tankhardwareId': tankhardwareId })
    .sort({ date: -1 })
    .lean();

  if (!iotData) return null;

  const matchedTank = iotData.tanks.find(t => t.tankhardwareId === tankhardwareId);
  return matchedTank?.tankHeight || null;
}

// exports.getIotDataByCustomer = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.code(400).send({ error: "customerId is required" });
//     }

//     // 1. Fetch all tanks by customerId
//     const tanks = await Tank.find({ customerId });
//     console.log("Tanks found:", tanks.length);

//     if (!tanks || tanks.length === 0) {
//       return reply.code(404).send({ message: "No tanks found for this customer." });
//     }

//     // 2. Collect all motor_ids from input & output connections
//     const motorIdSet = new Set();

//     for (const tank of tanks) {
//       const { inputConnections = [], outputConnections = [] } = tank.connections || {};

//       inputConnections.forEach(conn => {
//         if (conn.motor_id) motorIdSet.add(conn.motor_id.trim());
//       });

//       outputConnections.forEach(conn => {
//         if (conn.motor_id) motorIdSet.add(conn.motor_id.trim());
//       });
//     }

//     const motorIds = Array.from(motorIdSet);
//     console.log("Unique motorIds collected:", motorIds);

//     if (motorIds.length === 0) {
//       return reply.send({ status_code: 200, message: "No motors connected", data: [] });
//     }

//     // 3. Fetch the latest IotData for each unique hardwareId
//     const latestIotDataPromises = motorIds.map(hardwareId =>
//       IotData.findOne({ hardwareId }).sort({ date: -1 }).lean()
//     );

//     const iotDataResults = await Promise.all(latestIotDataPromises);
//     const filteredData = iotDataResults.filter(doc => doc); // remove nulls

//     console.log("Latest IotData entries found:", filteredData.length);

//     return reply.send({
//       status_code: 200,
//       message: "Success",
//       data: filteredData
//     });

//   } catch (err) {
//     console.error("Error fetching IoT data by customerId:", err);
//     return reply.code(500).send({ error: "Internal Server Error" });
//   }
// };

// exports.getIotDataByCustomer = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.code(400).send({ error: "customerId is required" });
//     }

//     // Fetch all sensors of the customer
//     const sensors = await Insensors.find({ customerId });

//     if (!sensors || sensors.length === 0) {
//       return reply.code(404).send({ message: "No sensors found for this customer." });
//     }

//     // Extract unique hardwareIds
//     const hardwareIds = [
//       ...new Set(
//         sensors.map(sensor => sensor.connected_to?.trim()).filter(Boolean)
//       )
//     ];

//     if (hardwareIds.length === 0) {
//       return reply.send({ status_code: 200, message: "No connected hardwareIds found", data: [] });
//     }

//     // Fetch latest IoT data and enrich it
//     const latestDataPromises = hardwareIds.map(async hardwareId => {
//       const latestRecord = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();

//       const relatedSensors = sensors.filter(sensor => sensor.connected_to?.trim() === hardwareId);

//       let message = "GSM is not connected";
//       if (latestRecord?.tanks?.some(tank => parseFloat(tank.tankHeight || 0) > 0)) {
//         message = "GSM is connected";
//       }

//       // Prepare individual tank connection status
//       const tanksStatus = relatedSensors.map(sensor => {
//         const tankhardwareId = sensor.hardwareId?.trim();

//         const matchedTank = latestRecord?.tanks?.find(
//           tank => tank.tankhardwareId === tankhardwareId
//         );

//         const loraMessage =
//           matchedTank && parseFloat(matchedTank.tankHeight || 0) > 0
//             ? "LORA is connected"
//             : "LORA is not connected";

//         return {
//           tankhardwareId,
//           tankName: sensor.tankName ?? null,
//           tankLocation: sensor.tankLocation ?? null,
//           masterName: sensor.masterName ?? null,
//           location: sensor.location ?? null,
//           loraMessage,
//           latestTankData: matchedTank || null
//         };
//       });

//       return {
//         hardwareId,
//         message,
//         masterName: relatedSensors[0]?.masterName ?? null,
//         location: relatedSensors[0]?.location ?? null,
//         tanks: tanksStatus.slice(1) // 👈 Skip the first tank
//       };
//     });

//     const iotDataGrouped = await Promise.all(latestDataPromises);

//     return reply.send({
//       status_code: 200,
//       message: "Success",
//       data: iotDataGrouped
//     });

//   } catch (err) {
//     console.error("Error fetching IoT data by customerId:", err);
//     return reply.code(500).send({ error: "Internal Server Error" });
//   }
// };


// exports.getIotDataByCustomer = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.code(400).send({ error: "customerId is required" });
//     }

//     // Fetch all sensors for the customer
//     const sensors = await Insensors.find({ customerId });

//     if (!sensors || sensors.length === 0) {
//       return reply.code(404).send({ message: "No sensors found for this customer." });
//     }

//     // Extract unique hardwareIds that are connected to sensors
//     const hardwareIds = [
//       ...new Set(
//         sensors.map(sensor => sensor.connected_to?.trim()).filter(Boolean)
//       )
//     ];

//     if (hardwareIds.length === 0) {
//       return reply.send({ status_code: 200, message: "No connected hardwareIds found", data: [] });
//     }

//     // Fetch the latest IoT data and enrich it with sensor details
//     const latestDataPromises = hardwareIds.map(async hardwareId => {
//       // Fetch the latest IoT data for this hardwareId
//       const latestRecord = await IotData.findOne({ hardwareId })
//         .sort({ date: -1 }) // Sorting to get the latest record based on the date
//         .lean();

//       // If no IoT data is found for this hardwareId, return a placeholder
//       if (!latestRecord) {
//         return {
//           hardwareId,
//           message: "No IoT data found",
//           tanks: []
//         };
//       }

//       // Find sensors related to this hardwareId
//       const relatedSensors = sensors.filter(sensor => sensor.connected_to?.trim() === hardwareId);

//       // Check if this hardwareId is "disconnected" in Insensors (based on your logic, e.g., isConnected=false)
//       const isDisconnected = relatedSensors.some(sensor => sensor.isConnected === false); // You can adjust this check based on your schema.

//       // Default message for GSM connection status
//       let message = isDisconnected ? "GSM is disconnected" : "GSM is not connected";

//       // If any tank data has height > 0, assume GSM is connected, overriding the disconnected state
//       if (latestRecord?.tanks?.some(tank => parseFloat(tank.tankHeight || 0) > 0)) {
//         message = "GSM is connected";
//       }

//       // Enrich each tank with the IoT data
//       const tanksStatus = relatedSensors.map(sensor => {
//         const tankhardwareId = sensor.hardwareId?.trim();
//         const matchedTank = latestRecord?.tanks?.find(
//           tank => tank.tankhardwareId === tankhardwareId
//         );

//         // Check if LoRa is connected based on the tankHeight
//         const loraMessage =
//           matchedTank && parseFloat(matchedTank.tankHeight || 0) > 0
//             ? "LORA is connected"
//             : "LORA is not connected";

//         return {
//           tankhardwareId,
//           tankName: sensor.tankName ?? null,
//           tankLocation: sensor.tankLocation ?? null,
//           masterName: sensor.masterName ?? null,
//           location: sensor.location ?? null,
//           loraMessage,
//           latestTankData: matchedTank || null
//         };
//       });

//       return {
//         hardwareId,
//         message,
//         masterName: relatedSensors[0]?.masterName ?? null,
//         location: relatedSensors[0]?.location ?? null,
//         tanks: tanksStatus
//       };
//     });

//     // Wait for all promises to resolve to gather all the enriched data
//     const iotDataGrouped = await Promise.all(latestDataPromises);

//     // Return the final response
//     return reply.send({
//       status_code: 200,
//       message: "Success",
//       data: iotDataGrouped
//     });

//   } catch (err) {
//     console.error("Error fetching IoT data by customerId:", err);
//     return reply.code(500).send({ error: "Internal Server Error" });
//   }
// };

//important
// exports.getIotDataByCustomer = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.status(400).send({ error: "customerId is required" });
//     }

//     console.log("Fetching data for customerId:", customerId);

//     // Step 1: Fetch all sensors for the customer
//     const sensors = await Insensors.find({ customerId });

//     if (!sensors || sensors.length === 0) {
//       return reply.send({ status_code: 404, message: "No sensors found for this customer", data: [] });
//     }

//     // Step 2: Fetch latest IoT data for each sensor's hardwareId
//     const enrichedSensors = await Promise.all(sensors.map(async (sensor) => {
//       const { connected_to: hardwareId, masterName, location } = sensor;

//       // Fetch the latest IoT data for this hardwareId
//       const iotData = await IotData.findOne({ hardwareId })
//         .sort({ date: -1 })  // Sort to get the latest data
//         .lean();

//       if (!iotData) {
//         return {
//           hardwareId,
//           message: "No IoT data found",
//           masterName,
//           location,
//           tanks: []
//         };
//       }

//       // Step 3: Get GSM status based on the latest IoT data
//       const latestRecord = iotData;
//       const indiaTime = moment.tz(latestRecord.date, "Asia/Kolkata");
//       const connected_gsm_date = indiaTime.format("YYYY-MM-DD");
//       const connected_gsm_time = indiaTime.format("HH:mm:ss");

//       const now = moment.tz("Asia/Kolkata");
//       const diffInMinutes = now.diff(indiaTime, "minutes");
//       const isGSMConnected = diffInMinutes <= 1;
//       const gsmStatus = isGSMConnected ? "GSM Connected" : "GSM Not Connected";

//       // Step 4: Annotate each tank with LoRa connection status
//       const tanksWithConnectionStatus = latestRecord.tanks.map(tank => {
//         const tankMoment = moment.tz(tank.date, "Asia/Kolkata");
//         const tankDiff = now.diff(tankMoment, "minutes");

//         const loraStatus = tankDiff <= 1 ? "LORA is connected" : "LORA is not connected";
//         return {
//           tankhardwareId: tank.tankhardwareId,
//           tankName: sensor.tankName ?? null,
//           tankLocation: sensor.tankLocation ?? null,
//           masterName: sensor.masterName ?? null,
//           location: sensor.location ?? null,
//           loraMessage: loraStatus,
//           latestTankData: tank
//         };
//       });

//       // Step 5: Return enriched sensor data in the desired format
//       return {
//         hardwareId,
//         message: gsmStatus,
//         masterName,
//         location,
//         tanks: tanksWithConnectionStatus
//       };
//     }));

//     // Step 6: Return the enriched data for the customer
//     return reply.send({
//       status_code: 200,
//       message: "Success",
//       data: enrichedSensors
//     });

//   } catch (err) {
//     console.error("Error in getAllDataForCustomer:", err);
//     return reply.status(500).send({ error: "Internal Server Error" });
//   }
// };


// exports.getIotDataByCustomer = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.status(400).send({ error: "customerId is required" });
//     }

//     console.log("Fetching data for customerId:", customerId);

//     // Step 1: Fetch all sensors for the customer
//     const sensors = await Insensors.find({ customerId });

//     if (!sensors || sensors.length === 0) {
//       return reply.send({ status_code: 404, message: "No sensors found for this customer", data: [] });
//     }

//     // Step 2: Fetch latest IoT data for each sensor's hardwareId
//     const enrichedSensors = await Promise.all(sensors.map(async (sensor) => {
//       const { connected_to: hardwareId, masterName, location } = sensor;

//       // Fetch the latest IoT data for this hardwareId
//       const iotData = await IotData.findOne({ hardwareId })
//         .sort({ date: -1 })  // Sort to get the latest data
//         .lean();

//       if (!iotData) {
//         return {
//           hardwareId,
//           message: "No IoT data found",
//           masterName,
//           location,
//           tanks: []
//         };
//       }

//       // Step 3: Get GSM status based on the latest IoT data
//       const latestRecord = iotData;
//       const indiaTime = moment.tz(latestRecord.date, "Asia/Kolkata");
//       const connected_gsm_date = indiaTime.format("YYYY-MM-DD");
//       const connected_gsm_time = indiaTime.format("HH:mm:ss");

//       const now = moment.tz("Asia/Kolkata");
//       const diffInMinutes = now.diff(indiaTime, "minutes");
//       const isGSMConnected = diffInMinutes <= 1;
//       const gsmStatus = isGSMConnected ? "GSM Connected" : "GSM Not Connected";

//       // Step 4: Annotate each tank with LoRa connection status
//       const tanksWithConnectionStatus = latestRecord.tanks.slice(0, 2).map(tank => { // Limit to 2 tanks
//         const tankMoment = moment.tz(tank.date, "Asia/Kolkata");
//         const tankDiff = now.diff(tankMoment, "minutes");

//         const loraStatus = tankDiff <= 1 ? "LORA is connected" : "LORA is not connected";
//         return {
//           tankhardwareId: tank.tankhardwareId,
//           tankName: sensor.tankName ?? null,
//           tankLocation: sensor.tankLocation ?? null,
//           masterName: sensor.masterName ?? null,
//           location: sensor.location ?? null,
//           loraMessage: loraStatus,
//           latestTankData: tank
//         };
//       });

//       // Step 5: Return enriched sensor data in the desired format
//       return {
//         hardwareId,
//         message: gsmStatus,
//         masterName,
//         location,
//         tanks: tanksWithConnectionStatus
//       };
//     }));

//     // Step 6: Return the enriched data for the customer
//     return reply.send({
//       status_code: 200,
//       message: "Success",
//       data: enrichedSensors
//     });

//   } catch (err) {
//     console.error("Error in getAllDataForCustomer:", err);
//     return reply.status(500).send({ error: "Internal Server Error" });
//   }
// };


// exports.getIotDataByCustomer = async (req, reply) => {
//   try {
//     const { customerId } = req.params;

//     if (!customerId) {
//       return reply.code(400).send({ error: "customerId is required" });
//     }

//     // Step 1: Get all devices for this customer
//     const sensors = await Insensors.find({ customerId });

//     if (!sensors.length) {
//       return reply.code(404).send({ message: "No sensors found for this customer." });
//     }

//     // Step 2: Get all unique master hardwareIds from connected_to
//     const masterHardwareIds = [
//       ...new Set(
//         sensors.map(s => s.connected_to?.trim()).filter(Boolean)
//       )
//     ];

//     // Step 3: Loop over each master (connected_to) and build enriched data
//     const enrichedMasters = await Promise.all(masterHardwareIds.map(async (hardwareId) => {
//       const latestRecord = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();

//       if (!latestRecord) {
//         return {
//           hardwareId,
//           message: "No IoT data found",
//           tanks: []
//         };
//       }

//       // Get all slaves connected to this master
//       const connectedSlaves = sensors.filter(sensor => sensor.connected_to?.trim() === hardwareId);

//       const message = latestRecord.tanks.some(t => parseFloat(t.tankHeight || 0) > 0)
//         ? "GSM is connected"
//         : "GSM is not connected";

//       // Map connected slaves to tank details
//       let tanks = connectedSlaves.map(slave => {
//         const slaveId = slave.hardwareId?.trim();
//         const matchedTank = latestRecord.tanks.find(tank => tank.tankhardwareId === slaveId);

//         const loraMessage = matchedTank && parseFloat(matchedTank.tankHeight || 0) > 0
//           ? "LORA is connected"
//           : "LORA is not connected";

//         return {
//           tankhardwareId: slaveId,
//           tankName: slave.tankName ?? null,
//           tankLocation: slave.tankLocation ?? null,
//           masterName: slave.masterName ?? null,
//           location: slave.location ?? null,
//           loraMessage,
//           latestTankData: matchedTank ?? null
//         };
//       });

//       // ❗ Remove the first tank entry
//       tanks = tanks.slice(1);

//       return {
//         hardwareId,
//         message,
//         masterName: connectedSlaves[0]?.masterName ?? null,
//         location: connectedSlaves[0]?.location ?? null,
//         tanks
//       };
//     }));

//     return reply.send({
//       status_code: 200,
//       message: "Success",
//       data: enrichedMasters
//     });

//   } catch (err) {
//     console.error("Error fetching IoT data by customerId:", err);
//     return reply.code(500).send({ error: "Internal Server Error" });
//   }
// };



exports.getIotDataByCustomer = async (req, reply) => {
  try {
    const { customerId } = req.params;

    if (!customerId) {
      return reply.code(400).send({ error: "customerId is required" });
    }

    // ✅ Get all sensors for the customer
    const sensors = await Insensors.find({ customerId });

    if (!sensors.length) {
      return reply.code(404).send({ message: "No sensors found for this customer." });
    }

    // ✅ Get only master hardware IDs from Insensors directly
    const masterSensors = sensors.filter(s => s.type === 'master');
    const masterHardwareIds = masterSensors.map(m => m.hardwareId?.trim());

    // ✅ Map for masterName/location from Order
    const orders = await Order.find({ customerId }).lean();
    const orderMap = {};
    orders.forEach(order => {
      order.master_connections.forEach(connection => {
        orderMap[connection.hardwareId] = {
          masterName: connection.master_name || null,
          location: connection.location || null
        };
      });
    });

    // ✅ Prepare final enriched master data
    const enrichedMasters = await Promise.all(masterHardwareIds.map(async (hardwareId) => {
      const latestRecord = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();

      const orderInfo = orderMap[hardwareId] || {};

      if (!latestRecord) {
        return {
          hardwareId,
          message: "No IoT data found",
          masterName: orderInfo.masterName ?? null,
          location: orderInfo.location ?? null,
          tanks: []
        };
      }

      // ✅ Check GSM status
      const indiaTime = moment.tz(latestRecord.date, "Asia/Kolkata");
      const now = moment.tz("Asia/Kolkata");
      const diffInMinutes = now.diff(indiaTime, "minutes");
      const gsmConnected = diffInMinutes <= 1;
      const message = gsmConnected ? "GSM is connected" : "GSM is not connected";

      // ✅ Get slaves connected to this master
      const connectedSlaves = sensors.filter(sensor => sensor.connected_to?.trim() === hardwareId);

      // ✅ Prepare tank info
      const tanks = connectedSlaves.map(slave => {
        const slaveId = slave.tankhardwareId?.trim();
        const matchedTank = latestRecord.tanks?.find(t => t.tankhardwareId === slaveId);

        let loraMessage = "LORA is not connected";

        if (matchedTank?.date && matchedTank.tankHeight !== "0") {
          const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata");
          const loraDiff = now.diff(tankTime, "minutes");
          loraMessage = loraDiff <= 1 ? "LORA is connected" : "LORA is not connected";
        }

        return {
          tankhardwareId: slaveId,
          tankName: slave.tankName ?? null,
          tankLocation: slave.tankLocation ?? null,
          masterName: orderInfo.masterName ?? null,
          location: orderInfo.location ?? null,
          loraMessage,
          latestTankData: matchedTank ?? null
        };
      });

      return {
        hardwareId,
        message,
        masterName: orderInfo.masterName ?? null,
        location: orderInfo.location ?? null,
        tanks
      };
    }));

    return reply.send({
      status_code: 200,
      message: "Success",
      data: enrichedMasters
    });

  } catch (err) {
    console.error("Error fetching IoT data by customerId:", err);
    return reply.code(500).send({ error: "Internal Server Error" });
  }
};



exports.getIotDataByCustomerAndHardwareId = async (req, reply) => {
  try {
    const { customerId, hardwareId } = req.params;

    if (!customerId || !hardwareId) {
      return reply.code(400).send({ error: "Both customerId and hardwareId are required" });
    }

    // Step 1: Get all sensors
    const sensors = await Insensors.find({ customerId });
    if (!sensors.length) {
      return reply.code(404).send({ message: "No sensors found for this customer." });
    }

    // Step 2: Get latest IoT data
    const latestRecord = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();
    if (!latestRecord) {
      return reply.code(404).send({
        hardwareId,
        message: "No IoT data found",
        tanks: []
      });
    }

    // Step 3: Calculate GSM connection status
    const indiaTime = moment.tz(latestRecord.date, "Asia/Kolkata");
    const now = moment.tz("Asia/Kolkata");
    const diffInMinutes = now.diff(indiaTime, "minutes");
    const gsmConnected = diffInMinutes <= 1;
    const gsmMessage = gsmConnected ? "GSM is connected" : "GSM is not connected";

    // Step 4: Get all connected slaves
    const connectedSlaves = sensors.filter(sensor => sensor.connected_to?.trim() === hardwareId);

    // Step 5: Get orderMap for fallback master info
    const orders = await Order.find({ customerId }).lean();
    const orderMap = {};
    orders.forEach(order => {
      order.master_connections?.forEach(connection => {
        orderMap[connection.hardwareId] = {
          masterName: connection.master_name || null,
          location: connection.location || null
        };
      });
    });

    // Step 6: Fallback master info from orderMap
    const fallbackMasterInfo = orderMap[hardwareId] || { masterName: null, location: null };

    // Step 7: Map tanks data
    const tanks = connectedSlaves.map(slave => {
      const slaveId = slave.tankhardwareId?.trim();
      const matchedTank = latestRecord.tanks?.find(tank => tank.tankhardwareId === slaveId);

      let loraConnected = false;
      let loraMessage = "LORA is not connected";

      if (matchedTank?.date && matchedTank.tankHeight !== "0") {
        const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata");
        const loraDiff = now.diff(tankTime, "minutes");
        loraConnected = loraDiff <= 1;
        loraMessage = loraConnected ? "LORA is connected" : "LORA is not connected";
      }

      return {
        tankhardwareId: slaveId,
        tankName: slave.tankName ?? null,
        tankLocation: slave.tankLocation ?? null,
        masterName: slave.masterName ?? fallbackMasterInfo.masterName,
        location: slave.location ?? fallbackMasterInfo.location,
        message: loraMessage,
        latestTankData: matchedTank ?? null
      };
    });

    // Step 8: Send response
    return reply.send({
      status_code: 200,
      message: "Success",
      data: {
        hardwareId,
        message: gsmMessage,
        masterName: connectedSlaves[0]?.masterName ?? fallbackMasterInfo.masterName,
        location: connectedSlaves[0]?.location ?? fallbackMasterInfo.location,
        tanks
      }
    });

  } catch (err) {
    console.error("Error fetching IoT data by customerId and hardwareId:", err);
    return reply.code(500).send({ error: "Internal Server Error" });
  }
};



//const moment = require("moment-timezone");


// exports.raiseATicket = async (req, reply) => {
//   try {
//     const { customerId, connected_to } = req.params;

//     if (!customerId || !connected_to) {
//       return reply.code(400).send({ error: "customerId and connected_to are required" });
//     }

//     const sensors = await Insensors.find({ customerId }).lean();
//     const orders = await Order.find({ customerId }).lean();

//     if (!sensors.length) {
//       return reply.code(404).send({ message: "No sensors found for this customer." });
//     }

//     const masterSensor = sensors.find(s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master");
//     if (!masterSensor) {
//       return reply.code(404).send({ message: "Master hardwareId not found." });
//     }

//     const orderMap = {};
//     orders.forEach(order => {
//       order.master_connections.forEach(conn => {
//         orderMap[conn.hardwareId] = {
//           masterName: conn.master_name || null,
//           location: conn.location || null
//         };
//       });
//     });

//     const now = moment.tz("Asia/Kolkata");

//     function getDisconnectDuration(timeStr) {
//       if (!timeStr) return null;
//       const time = moment.tz(timeStr, "DD-MM-YYYY HH:mm:ss", "Asia/Kolkata");
//       return time.isValid() ? now.diff(time, "minutes") : null;
//     }

//     const latestMasterRecord = await IotData.findOne({ hardwareId: connected_to }).sort({ date: -1 }).lean();
//     let masterConnectedStatus = "disconnected";
//     let lastDataTime = "No data";
//     let diffInMinutes = null;

//     if (latestMasterRecord?.date) {
//       const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
//       diffInMinutes = now.diff(indiaTime, "minutes");
//       lastDataTime = indiaTime.format("DD-MM-YYYY HH:mm:ss");
//       if (diffInMinutes <= 1) masterConnectedStatus = "connected";
//     }

//     const connectedSlaves = sensors.filter(
//       s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave"
//     );

//     const formattedSlaves = [];
//     const disconnectedSlaves = [];

//     for (const slave of connectedSlaves) {
//       const slaveData = latestMasterRecord?.tanks.find(t => t.tankhardwareId === slave.tankhardwareId);
//       let slaveStatus = "disconnected";
//       let lastSlaveDataTime = "No data";
//       let slaveDiff = null;

//       if (slaveData?.date) {
//         const slaveTime = moment.tz(slaveData.date, "Asia/Kolkata");
//         slaveDiff = now.diff(slaveTime, "minutes");
//         lastSlaveDataTime = slaveTime.format("DD-MM-YYYY HH:mm:ss");
//         if (slaveDiff <= 1) slaveStatus = "connected";
//       }

//       if (slaveStatus === "disconnected") {
//         disconnectedSlaves.push({
//           slaveHardwareId: slave.tankhardwareId,
//           slaveName: slave.tankName || "Unknown Slave"
//         });
//       }

//       formattedSlaves.push({
//         hardwareId: slave.hardwareId,
//         slaveName: slave.tankName || null,
//         location: slave.tankLocation || null,
//         type: "slave",
//         connected_status: slaveStatus,
//         last_data_time: lastSlaveDataTime,
//         diff_in_minutes: slaveDiff
//       });
//     }

//     const issuesToAdd = [];

//     // ✅ Only raise a ticket if master is disconnected
//     // if (masterConnectedStatus === "disconnected") {
//     //   const existingMasterTicket = await Support.findOne({
//     //     "issues.hardwareId": connected_to,
//     //     "issues.type": "GSM or LoRa Disconnected"
//     //   });

//     //   if (!existingMasterTicket) {
//     //     const slaveHardwareIds = disconnectedSlaves.map(s => s.slaveHardwareId);
//     //     const slaveNames = disconnectedSlaves.map(s => s.slaveName);

//     //     issuesToAdd.push({
//     //       type: "GSM or LoRa Disconnected",
//     //       masterHardwareId: connected_to,
//     //       hardwareId: connected_to, // Master hardwareId
//     //       hardwareIds: slaveHardwareIds, // Slave tankHardwareIds
//     //       slaveNames,
//     //       message: `Master ${connected_to} is disconnected along with ${slaveHardwareIds.length} slave(s)`
//     //     });
//     //   }
//     // }

//     if (masterConnectedStatus === "disconnected") {
//       const existingMasterTicket = await Support.findOne({
//         "issues.hardwareId": connected_to,
//         "issues.type": "GSM or LoRa Disconnected"
//       });
    
//       if (!existingMasterTicket) {
//         const slaveHardwareIds = disconnectedSlaves.map(s => s.slaveHardwareId);
//         const slaveNames = disconnectedSlaves.map(s => s.slaveName);
    
//         // Check if disconnection is at least 15 minutes old
//         if (diffInMinutes >= 1) {
//           issuesToAdd.push({
//             type: "GSM or LoRa Disconnected",
//             masterHardwareId: connected_to,
//             hardwareId: connected_to,
//             hardwareIds: slaveHardwareIds,
//             slaveNames,
//             message: `Master ${connected_to} is disconnected along with ${slaveHardwareIds.length} slave(s)`,
//             disconnectedAt: lastDataTime // optional: for future tracking
//           });
//         }
//       }
//     }
    

//     if (issuesToAdd.length > 0) {
//       const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
    
//       if (supportRecord) {
//         await Support.findOneAndUpdate(
//           { supportId: "AWHYSU64" },
//           {
//             $push: { issues: { $each: issuesToAdd } },
//             $set: { updatedAt: new Date(), lastTicketRaisedAt: moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss") }
//           }
//         );
//       }
//     }
    

//     const masterDetails = {
//       hardwareId: connected_to,
//       masterName: masterSensor.masterName || orderMap[connected_to]?.masterName || null,
//       location: masterSensor.location || orderMap[connected_to]?.location || null,
//       type: "master",
//       connected_status: masterConnectedStatus,
//       last_data_time: lastDataTime,
//       diff_in_minutes: diffInMinutes
//     };

//     return reply.send({
//       status_code: 200,
//       message: "Checked connection and raised ticket if needed.",
//       master: masterDetails,
//       connected_slaves: formattedSlaves
//     });

//   } catch (error) {
//     console.error("Error raising ticket:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };



// exports.raiseATicket = async (req, reply) => {
//   try {
//     const { customerId, connected_to } = req.params;

//     if (!customerId || !connected_to) {
//       return reply.code(400).send({ error: "customerId and connected_to are required" });
//     }

//     // Fetch all sensors and orders for the customer
//     const sensors = await Insensors.find({ customerId }).lean();
//     const orders = await Order.find({ customerId }).lean();

//     if (!sensors.length) {
//       return reply.code(404).send({ message: "No sensors found for this customer." });
//     }

//     // Find master sensor matching connected_to
//     const masterSensor = sensors.find(s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master");
//     if (!masterSensor) {
//       return reply.code(404).send({ message: "Master hardwareId not found." });
//     }

//     // Map orders for quick lookup of masterName and location
//     const orderMap = {};
//     orders.forEach(order => {
//       order.master_connections.forEach(conn => {
//         orderMap[conn.hardwareId] = {
//           masterName: conn.master_name || null,
//           location: conn.location || null
//         };
//       });
//     });

//     const now = moment.tz("Asia/Kolkata");

//     // Helper to get the latest record from multiple IoT data docs
//     function getLatestDataRecord(records) {
//       if (!records || records.length === 0) return null;
//       return records.reduce((latest, record) => {
//         if (!latest) return record;
//         return new Date(record.date) > new Date(latest.date) ? record : latest;
//       }, null);
//     }

//     // Fetch all IoT data for the master (no date limit here, adjust if needed)
//     const allMasterIotData = await IotData.find({ hardwareId: connected_to }).lean();
//     const latestMasterRecord = getLatestDataRecord(allMasterIotData);

//     let masterConnectedStatus = "disconnected";
//     let lastDataTime = "No data";
//     let diffInMinutes = null;

//     if (latestMasterRecord?.date) {
//       const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
//       diffInMinutes = now.diff(indiaTime, "minutes");
//       lastDataTime = indiaTime.format("DD-MM-YYYY HH:mm:ss");
//       if (diffInMinutes <= 1) masterConnectedStatus = "connected";  // within 1 minute considered connected
//     }

//     // Find slaves connected to this master
//     const connectedSlaves = sensors.filter(
//       s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave"
//     );

//     const slaveHardwareIds = connectedSlaves.map(s => s.tankhardwareId);

//     // Fetch all IoT data for slaves
//     const allSlaveIotData = await IotData.find({ hardwareId: { $in: slaveHardwareIds } }).lean();

//     const formattedSlaves = [];
//     const disconnectedSlaves = [];

//     for (const slave of connectedSlaves) {
//       const slaveRecords = allSlaveIotData.filter(d => d.hardwareId === slave.tankhardwareId);
//       const latestSlaveRecord = getLatestDataRecord(slaveRecords);

//       let slaveStatus = "disconnected";
//       let lastSlaveDataTime = "No data";
//       let slaveDiff = null;

//       if (latestSlaveRecord?.date) {
//         const slaveTime = moment.tz(latestSlaveRecord.date, "Asia/Kolkata");
//         slaveDiff = now.diff(slaveTime, "minutes");
//         lastSlaveDataTime = slaveTime.format("DD-MM-YYYY HH:mm:ss");
//         if (slaveDiff <= 1) slaveStatus = "connected";
//       }

//       if (slaveStatus === "disconnected") {
//         disconnectedSlaves.push({
//           slaveHardwareId: slave.tankhardwareId,
//           slaveName: slave.tankName || "Unknown Slave"
//         });
//       }

//       formattedSlaves.push({
//         hardwareId: slave.hardwareId,
//         slaveName: slave.tankName || null,
//         location: slave.tankLocation || null,
//         type: "slave",
//         connected_status: slaveStatus,
//         last_data_time: lastSlaveDataTime,
//         diff_in_minutes: slaveDiff
//       });
//     }

//     const issuesToAdd = [];

//     // Raise ticket only if master is disconnected and disconnection is at least 1 minute old
//     if (masterConnectedStatus === "disconnected") {
//       const existingMasterTicket = await Support.findOne({
//         "issues.hardwareId": connected_to,
//         "issues.type": "GSM or LoRa Disconnected"
//       });

//       if (!existingMasterTicket && diffInMinutes >= 1) {
//         const slaveHardwareIds = disconnectedSlaves.map(s => s.slaveHardwareId);
//         const slaveNames = disconnectedSlaves.map(s => s.slaveName);

//         issuesToAdd.push({
//           type: "GSM or LoRa Disconnected",
//           masterHardwareId: connected_to,
//           hardwareId: connected_to,
//           hardwareIds: slaveHardwareIds,
//           slaveNames,
//           message: `Master ${connected_to} is disconnected along with ${slaveHardwareIds.length} slave(s)`,
//           disconnectedAt: lastDataTime // optional
//         });
//       }
//     }

//     if (issuesToAdd.length > 0) {
//       const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });

//       if (supportRecord) {
//         await Support.findOneAndUpdate(
//           { supportId: "AWHYSU64" },
//           {
//             $push: { issues: { $each: issuesToAdd } },
//             $set: {
//               updatedAt: new Date(),
//               lastTicketRaisedAt: moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss")
//             }
//           }
//         );
//       }
//     }

//     const masterDetails = {
//       hardwareId: connected_to,
//       masterName: masterSensor.masterName || orderMap[connected_to]?.masterName || null,
//       location: masterSensor.location || orderMap[connected_to]?.location || null,
//       type: "master",
//       connected_status: masterConnectedStatus,
//       last_data_time: lastDataTime,
//       diff_in_minutes: diffInMinutes
//     };

//     return reply.send({
//       status_code: 200,
//       message: "Checked connection and raised ticket if needed.",
//       master: masterDetails,
//       connected_slaves: formattedSlaves
//     });

//   } catch (error) {
//     console.error("Error raising ticket:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };



// exports.raiseATicket = async (req, reply) => {
//   try {
//     const { customerId, connected_to } = req.params;

//     if (!customerId || !connected_to) {
//       return reply.code(400).send({ error: "customerId and connected_to are required" });
//     }

//     const sensors = await Insensors.find({ customerId });

//     if (!sensors.length) {
//       return reply.code(404).send({ message: "No sensors found for this customer." });
//     }

//     const masterSensor = sensors.find(s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master");

//     if (!masterSensor) {
//       return reply.code(404).send({ message: "Master hardwareId not found." });
//     }

//     const latestMasterRecord = await IotData.findOne({ hardwareId: connected_to }).sort({ date: -1 }).lean();

//     if (!latestMasterRecord) {
//       return reply.code(404).send({ message: "No IoT data found for this hardwareId." });
//     }

//     const now = moment.tz("Asia/Kolkata");
//     const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
//     const diffInMinutesMaster = now.diff(indiaTime, "minutes");

//     const masterDisconnected = diffInMinutesMaster > 1 ? [{
//       hardwareId: connected_to,
//       masterName: masterSensor.tankName || "Unknown Master",
//       connected_status: "disconnected",
//       last_seen_minutes_ago: diffInMinutesMaster
//     }] : [];

//     const connectedSlaves = sensors.filter(sensor =>
//       sensor.connected_to?.trim() === connected_to.trim() &&
//       sensor.type === "slave"
//     );

//     const disconnectedSlaves = [];
//     const slaveStatusList = [];

//     for (const slave of connectedSlaves) {
//       const slaveId = slave.tankhardwareId?.trim();
//       const matchedTank = latestMasterRecord.tanks.find(tank => tank.tankhardwareId === slaveId);

//       let isDisconnected = true;
//       let loraDiffInMinutes = null;

//       if (matchedTank && matchedTank.date) {
//         const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata");
//         loraDiffInMinutes = now.diff(tankTime, "minutes");

//         if (loraDiffInMinutes <= 1) {
//           isDisconnected = false;
//         }
//       }

//       const slaveInfo = {
//         hardwareId: connected_to,
//         slaveHardwareId: slaveId,
//         slaveName: slave.tankName || "Unknown Slave",
//         connected_status: isDisconnected ? "disconnected" : "connected",
//         last_seen_minutes_ago: loraDiffInMinutes
//       };

//       slaveStatusList.push(slaveInfo);

//       if (isDisconnected) {
//         disconnectedSlaves.push(slaveInfo);
//       }
//     }

//     const issuesToAdd = [];

//     if (masterDisconnected.length > 0) {
//       const existingGsmIssue = await Support.findOne({
//         "issues.hardwareId": connected_to,
//         "issues.type": "GSM Disconnected"
//       });

//       if (!existingGsmIssue) {
//         issuesToAdd.push({
//           type: "GSM Disconnected",
//           hardwareId: connected_to,
//           message: `Master GSM disconnected - ${connected_to}`
//         });
//       }
//     }

//     const newHardwareIds = [];
//     const newSlaveNames = [];

//     for (const slave of disconnectedSlaves) {
//       const existingSlaveIssue = await Support.findOne({
//         "issues.hardwareIds": slave.slaveHardwareId,
//         "issues.masterHardwareId": connected_to,
//         "issues.type": "LoRa Disconnected"
//       });

//       if (!existingSlaveIssue) {
//         newHardwareIds.push(slave.slaveHardwareId);
//         newSlaveNames.push(slave.slaveName);
//       }
//     }

//     if (newHardwareIds.length > 0) {
//       issuesToAdd.push({
//         type: "LoRa Disconnected",
//         masterHardwareId: connected_to,
//         hardwareIds: newHardwareIds,
//         slaveNames: newSlaveNames,
//         message: `Slaves LoRa disconnected under master ${connected_to}`
//       });
//     }

//     if (issuesToAdd.length > 0) {
//       const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });

//       if (supportRecord) {
//         await Support.findOneAndUpdate(
//           { _id: supportRecord._id },
//           {
//             $push: {
//               issues: { $each: issuesToAdd }
//             },
//             updatedAt: new Date()
//           },
//           { new: true }
//         );
//       } else {
//         console.error("Support record not found for supportId AWHYSU64");
//       }
//     }

//     return reply.send({
//       status_code: 200,
//       message: "Checked connection and updated support if needed.",
//       masterDisconnected,
//       disconnectedSlaves,
//       connectedSlaves: slaveStatusList
//     });

//   } catch (error) {
//     console.error("Error raising ticket:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };


// const raiseATicketLikeLogic = async (customerId, connected_to) => {
//   try {
//     if (!customerId || !connected_to) return;

//     const sensors = await Insensors.find({ customerId }).lean();
//     const orders = await Order.find({ customerId }).lean();

//     if (!sensors.length) return;

//     const masterSensor = sensors.find(
//       s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master"
//     );
//     if (!masterSensor) return;

//     const orderMap = {};
//     orders.forEach(order => {
//       order.master_connections.forEach(conn => {
//         orderMap[conn.hardwareId] = {
//           masterName: conn.master_name || null,
//           location: conn.location || null
//         };
//       });
//     });

//     const now = moment.tz("Asia/Kolkata");

//     function getLatestDataRecord(records) {
//       if (!records || records.length === 0) return null;
//       return records.reduce((latest, record) => {
//         if (!latest) return record;
//         return new Date(record.date) > new Date(latest.date) ? record : latest;
//       }, null);
//     }

//     const allMasterIotData = await IotData.find({ hardwareId: connected_to }).lean();
//     const latestMasterRecord = getLatestDataRecord(allMasterIotData);

//     let masterConnectedStatus = "disconnected";
//     let lastDataTime = "No data";
//     let diffInMinutes = null;

//     if (latestMasterRecord?.date) {
//       const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
//       diffInMinutes = now.diff(indiaTime, "minutes");
//       lastDataTime = indiaTime.format("DD-MM-YYYY HH:mm:ss");
//       if (diffInMinutes <= 1) masterConnectedStatus = "connected";
//     }

//     const connectedSlaves = sensors.filter(
//       s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave"
//     );

//     const slaveHardwareIds = connectedSlaves.map(s => s.tankhardwareId);
//     const allSlaveIotData = await IotData.find({ hardwareId: { $in: slaveHardwareIds } }).lean();

//     const disconnectedSlaves = [];

//     for (const slave of connectedSlaves) {
//       const slaveRecords = allSlaveIotData.filter(d => d.hardwareId === slave.tankhardwareId);
//       const latestSlaveRecord = getLatestDataRecord(slaveRecords);

//       let slaveStatus = "disconnected";
//       let slaveDiff = null;

//       if (latestSlaveRecord?.date) {
//         const slaveTime = moment.tz(latestSlaveRecord.date, "Asia/Kolkata");
//         slaveDiff = now.diff(slaveTime, "minutes");
//         if (slaveDiff <= 1) slaveStatus = "connected";
//       }

//       if (slaveStatus === "disconnected") {
//         disconnectedSlaves.push({
//           slaveHardwareId: slave.tankhardwareId,
//           slaveName: slave.tankName || "Unknown Slave"
//         });
//       }
//     }

//     const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
//     if (!supportRecord) return;

//     const existingIssues = supportRecord.issues || [];

//     const existingMasterIssue = existingIssues.find(
//       issue =>
//         issue.hardwareId === connected_to &&
//         issue.type === "GSM or LoRa Disconnected"
//     );

//     const alreadyReportedSlaves = new Set(
//       existingMasterIssue?.hardwareIds || []
//     );

//     const newSlaveHardwareIds = [];
//     const newSlaveNames = [];

//     for (const slave of disconnectedSlaves) {
//       if (!alreadyReportedSlaves.has(slave.slaveHardwareId)) {
//         newSlaveHardwareIds.push(slave.slaveHardwareId);
//         newSlaveNames.push(slave.slaveName);
//       }
//     }

//     if (masterConnectedStatus === "disconnected" && diffInMinutes >= 1 && (newSlaveHardwareIds.length > 0 || !existingMasterIssue)) {
//       const newIssue = {
//         type: "GSM or LoRa Disconnected",
//         masterHardwareId: connected_to,
//         hardwareId: connected_to,
//         hardwareIds: newSlaveHardwareIds,
//         slaveNames: newSlaveNames,
//         message: `Master ${connected_to} is disconnected along with ${newSlaveHardwareIds.length} new slave(s)`,
//         disconnectedAt: lastDataTime
//       };

//       await Support.findOneAndUpdate(
//         { supportId: "AWHYSU64" },
//         {
//           $push: existingMasterIssue ? {
//             "issues.$[elem].hardwareIds": { $each: newSlaveHardwareIds },
//             "issues.$[elem].slaveNames": { $each: newSlaveNames }
//           } : {
//             issues: newIssue
//           },
//           $set: {
//             updatedAt: new Date(),
//             lastTicketRaisedAt: now.format("YYYY-MM-DD HH:mm:ss")
//           }
//         },
//         existingMasterIssue
//           ? { arrayFilters: [{ "elem.hardwareId": connected_to, "elem.type": "GSM or LoRa Disconnected" }] }
//           : {}
//       );
//     }

//   } catch (error) {
//     console.error("Error in raiseATicketLikeLogic:", error);
//   }
// };

// const raiseATicketLikeLogic = async (customerId, connected_to) => {
//   try {
//     if (!customerId || !connected_to) return;

//     const sensors = await Insensors.find({ customerId }).lean();
//     const orders = await Order.find({ customerId }).lean();

//     if (!sensors.length) return;

//     const masterSensor = sensors.find(
//       s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master"
//     );
//     if (!masterSensor) return;

//     const orderMap = {};
//     orders.forEach(order => {
//       order.master_connections.forEach(conn => {
//         orderMap[conn.hardwareId] = {
//           masterName: conn.master_name || null,
//           location: conn.location || null
//         };
//       });
//     });

//     const now = moment.tz("Asia/Kolkata");

//     function getLatestDataRecord(records) {
//       if (!records || records.length === 0) return null;
//       return records.reduce((latest, record) => {
//         if (!latest) return record;
//         return new Date(record.date) > new Date(latest.date) ? record : latest;
//       }, null);
//     }

//     const allMasterIotData = await IotData.find({ hardwareId: connected_to }).lean();
//     const latestMasterRecord = getLatestDataRecord(allMasterIotData);

//     let masterConnectedStatus = "disconnected";
//     let lastDataTime = "No data";
//     let diffInMinutes = null;

//     if (latestMasterRecord?.date) {
//       const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
//       diffInMinutes = now.diff(indiaTime, "minutes");
//       lastDataTime = indiaTime.format("DD-MM-YYYY HH:mm:ss");
//       if (diffInMinutes <= 2) masterConnectedStatus = "connected";
//     }

//     const connectedSlaves = sensors.filter(
//       s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave"
//     );

//     const slaveHardwareIds = connectedSlaves.map(s => s.tankhardwareId);
//     const allSlaveIotData = await IotData.find({ hardwareId: { $in: slaveHardwareIds } }).lean();

//     const disconnectedSlaves = [];

//     for (const slave of connectedSlaves) {
//       const slaveRecords = allSlaveIotData.filter(d => d.hardwareId === slave.tankhardwareId);
//       const latestSlaveRecord = getLatestDataRecord(slaveRecords);

//       let slaveStatus = "disconnected";
//       let slaveDiff = null;

//       if (latestSlaveRecord?.date) {
//         const slaveTime = moment.tz(latestSlaveRecord.date, "Asia/Kolkata");
//         slaveDiff = now.diff(slaveTime, "minutes");
//         if (slaveDiff <= 2) slaveStatus = "connected";
//       }

//       if (slaveStatus === "disconnected") {
//         disconnectedSlaves.push({
//           slaveHardwareId: slave.tankhardwareId,
//           slaveName: slave.tankName || "Unknown Slave"
//         });
//       }
//     }

//     const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
//     if (!supportRecord) return;

//     const existingIssues = supportRecord.issues || [];

//     // Find existing unresolved issue
//     const existingMasterIssue = existingIssues.find(
//       issue =>
//         issue.hardwareId === connected_to &&
//         issue.type === "GSM or LoRa Disconnected" &&
//         issue.resolved !== true // <-- only unresolved
//     );

//     const alreadyReportedSlaves = new Set(
//       existingMasterIssue?.hardwareIds || []
//     );

//     const newSlaveHardwareIds = [];
//     const newSlaveNames = [];

//     for (const slave of disconnectedSlaves) {
//       if (!alreadyReportedSlaves.has(slave.slaveHardwareId)) {
//         newSlaveHardwareIds.push(slave.slaveHardwareId);
//         newSlaveNames.push(slave.slaveName);
//       }
//     }

//     const formattedNow = now.format("YYYY-MM-DD HH:mm:ss");

//     if (
//       masterConnectedStatus === "disconnected" &&
//       diffInMinutes >= 2 &&
//       (newSlaveHardwareIds.length > 0 || !existingMasterIssue)
//     ) {
//       if (!existingMasterIssue) {
//         // Create new issue with resolved: false
//         const newIssue = {
//           type: "GSM or LoRa Disconnected",
//           masterHardwareId: connected_to,
//           hardwareId: connected_to,
//           hardwareIds: newSlaveHardwareIds,
//           slaveNames: newSlaveNames,
//           message: `Master ${connected_to} is disconnected along with ${newSlaveHardwareIds.length} new slave(s)`,
//           disconnectedAt: lastDataTime,
//           lastTicketRaisedAt: formattedNow,
//           resolved: false // <--- add resolved flag here
//         };

//         await Support.findOneAndUpdate(
//           { supportId: "AWHYSU64" },
//           {
//             $push: { issues: newIssue },
//             $set: { updatedAt: new Date() }
//           }
//         );
//       } else {
//         // Update existing unresolved issue only
//         await Support.findOneAndUpdate(
//           { supportId: "AWHYSU64" },
//           {
//             $push: {
//               "issues.$[elem].hardwareIds": { $each: newSlaveHardwareIds },
//               "issues.$[elem].slaveNames": { $each: newSlaveNames }
//             },
//             $set: {
//               "issues.$[elem].lastTicketRaisedAt": formattedNow,
//               updatedAt: new Date()
//             }
//           },
//           {
//             arrayFilters: [
//               { "elem.hardwareId": connected_to, "elem.type": "GSM or LoRa Disconnected", "elem.resolved": false }
//             ]
//           }
//         );
//       }
//     }
//   } catch (error) {
//     console.error("Error in raiseATicketLikeLogic:", error);
//   }
// };


// const cron = require("node-cron");

// cron.schedule("* * * * *", async () => {
//   console.log("Running auto ticket check...");

//   const allMasters = await Insensors.find({ type: "master" }).lean();
//   for (const master of allMasters) {
//     await raiseATicketLikeLogic(master.customerId, master.hardwareId);
//   }
// });

const cron = require("node-cron");

// const raiseATicketLikeLogic = async (customerId, connected_to) => {
//   try {
//     if (!customerId || !connected_to) return;

//     const sensors = await Insensors.find({ customerId }).lean();
//     const orders = await Order.find({ customerId }).lean();
//     if (!sensors.length) return;

//     const masterSensor = sensors.find(
//       s => s.hardwareId?.trim() === connected_to.trim() && s.type === "master"
//     );
//     if (!masterSensor) return;

//     const orderMap = {};
//     orders.forEach(order => {
//       order.master_connections.forEach(conn => {
//         orderMap[conn.hardwareId] = {
//           masterName: conn.master_name || null,
//           location: conn.location || null
//         };
//       });
//     });

//     const now = moment.tz("Asia/Kolkata");

//     function getLatestDataRecord(records) {
//       if (!records || records.length === 0) return null;
//       return records.reduce((latest, record) => {
//         if (!latest) return record;
//         return new Date(record.date) > new Date(latest.date) ? record : latest;
//       }, null);
//     }

//     // 🔸 Master status check
//     const allMasterIotData = await IotData.find({ hardwareId: connected_to }).lean();
//     const latestMasterRecord = getLatestDataRecord(allMasterIotData);

//     let masterConnectedStatus = "disconnected";
//     let lastDataTime = "No data";
//     let diffInMinutes = null;

//     if (latestMasterRecord?.date) {
//       const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
//       diffInMinutes = now.diff(indiaTime, "minutes");
//       lastDataTime = indiaTime.format("DD-MM-YYYY HH:mm:ss");
//       if (diffInMinutes <= 2) masterConnectedStatus = "connected";
//     }

//     // 🔸 Slave status check
//     const connectedSlaves = sensors.filter(
//       s => s.connected_to?.trim() === connected_to.trim() && s.type === "slave"
//     );
// console.log("connectedSlaves",connectedSlaves)
//     const slaveHardwareIds = connectedSlaves.map(s => s.tankhardwareId);
//     // const allSlaveIotData = await IotData.find({ "tanks.tankhardwareId": { $in: slaveHardwareIds } }).lean();
//     const allSlaveIotData = await IotData.aggregate([
//       { $match: { "tanks.tankhardwareId": { $in: slaveHardwareIds } } },
//       { $project: {
//           hardwareId: 1,
//           date: 1,
//           "tanks": {
//             $filter: {
//               input: "$tanks",
//               as: "tank",
//               cond: { $in: ["$$tank.tankhardwareId", slaveHardwareIds] }
//             }
//           }
//         }
//       }
//     ]);
//     console.log("allSlaveIotData",allSlaveIotData)
//     // 🔹 Create map of latest tank data
//     const latestTankDataMap = {};
//     for (const record of allSlaveIotData) {
//       const baseDate = record.date;
//       for (const tank of record.tanks || []) {
//         const tankId = tank.tankhardwareId;
//         const tankDate = tank.date || baseDate;

//         if (!tankId || !tankDate) continue;

//         if (
//           !latestTankDataMap[tankId] ||
//           new Date(tankDate) > new Date(latestTankDataMap[tankId].date)
//         ) {
//           latestTankDataMap[tankId] = {
//             date: tankDate,
//             time: tank.time,
//             hardwareId: tankId
//           };
//         }
//       }
//     }

//     const disconnectedSlaves = [];
//     for (const slave of connectedSlaves) {
//       const latestSlaveRecord = latestTankDataMap[slave.tankhardwareId];

//       let slaveStatus = "disconnected";
//       if (latestSlaveRecord?.date) {
//         const slaveTime = moment.tz(latestSlaveRecord.date, "Asia/Kolkata");
//         const slaveDiff = now.diff(slaveTime, "minutes");
//         if (slaveDiff <= 2) slaveStatus = "connected";
//       }

//       if (slaveStatus === "disconnected") {
//         disconnectedSlaves.push({
//           slaveHardwareId: slave.tankhardwareId,
//           slaveName: slave.tankName || "Unknown Slave"
//         });
//       }
//     }
//     console.log(",disconnectedSlaves",disconnectedSlaves)

//     if (disconnectedSlaves.length === 0 && masterConnectedStatus === "connected") {
//       return; // ✅ No ticket needed
//     }

//     const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
//     if (!supportRecord) return;

//     const existingIssues = supportRecord.issues || [];
//     const existingMasterIssue = existingIssues.find(
//       issue =>
//         issue.hardwareId === connected_to &&
//         issue.type === "GSM or LoRa Disconnected" &&
//         issue.resolved !== true
//     );

//     const alreadyReportedSlaves = new Set(existingMasterIssue?.hardwareIds || []);
//     const newSlaveHardwareIds = [];
//     const newSlaveNames = [];

//     for (const slave of disconnectedSlaves) {
//       if (!alreadyReportedSlaves.has(slave.slaveHardwareId)) {
//         newSlaveHardwareIds.push(slave.slaveHardwareId);
//         newSlaveNames.push(slave.slaveName);
//       }
//     }

//     const formattedNow = now.format("YYYY-MM-DD HH:mm:ss");

//     // 🔸 Raise new issue
//     if (!existingMasterIssue && (masterConnectedStatus === "disconnected" || disconnectedSlaves.length > 0)) {
//       const newIssue = {
//         type: "GSM or LoRa Disconnected",
//         masterHardwareId: connected_to,
//         hardwareId: connected_to,
//         hardwareIds: newSlaveHardwareIds,
//         slaveNames: newSlaveNames,
//         message: `Master ${connected_to} is ${masterConnectedStatus} with ${disconnectedSlaves.length} disconnected slave(s)`,
//         disconnectedAt: lastDataTime,
//         lastTicketRaisedAt: formattedNow,
//         resolved: false
//       };
//       await Support.findOneAndUpdate(
//         { supportId: "AWHYSU64" },
//         { $push: { issues: newIssue }, $set: { updatedAt: new Date() } }
//       );
//     }

//     // 🔸 Update existing issue with new disconnected slaves
//     if (existingMasterIssue && newSlaveHardwareIds.length > 0) {
//       await Support.findOneAndUpdate(
//         { supportId: "AWHYSU64" },
//         {
//           $push: {
//             "issues.$[elem].hardwareIds": { $each: newSlaveHardwareIds },
//             "issues.$[elem].slaveNames": { $each: newSlaveNames }
//           },
//           $set: {
//             "issues.$[elem].lastTicketRaisedAt": formattedNow,
//             updatedAt: new Date()
//           }
//         },
//         {
//           arrayFilters: [
//             {
//               "elem.hardwareId": connected_to,
//               "elem.type": "GSM or LoRa Disconnected",
//               "elem.resolved": false
//             }
//           ]
//         }
//       );
//     }
//   } catch (error) {
//     console.error("Error in raiseATicketLikeLogic:", error);
//   }
// };

// const raiseATicketLikeLogic = async (customerId, connected_to) => {
//   try {
//     if (!customerId || !connected_to) return;

//     const normalizedConnectedTo = connected_to.trim().toLowerCase();

//     const sensors = await Insensors.find({ customerId }).lean();
//     if (!sensors.length) return;

//     const masterSensor = sensors.find(
//       (s) => s.hardwareId?.trim().toLowerCase() === normalizedConnectedTo && s.type === "master"
//     );
//     if (!masterSensor) return;

//     const orders = await Order.find({ customerId }).lean();

//     const connectedSlaves = sensors.filter(
//       (s) => s.connected_to?.trim().toLowerCase() === normalizedConnectedTo && s.type === "slave"
//     );

//     const disconnectedSlaves = connectedSlaves
//       .filter((s) => s.connected_status === "disconnected")
//       .map((s) => ({
//         slaveHardwareId: s.tankhardwareId?.trim().toLowerCase(),
//         slaveName: s.tankName || "Unknown Slave",
//       }));

//     const supportRecord = await Support.findOne({ supportId: "AWHYSU64" });
//     if (!supportRecord) return;

//     const now = moment.tz("Asia/Kolkata");
//     const formattedNow = now.format("YYYY-MM-DD HH:mm:ss");

//     const existingMasterIssue = supportRecord.issues.find(
//       (issue) =>
//         issue.hardwareId?.trim().toLowerCase() === normalizedConnectedTo &&
//         issue.type === "GSM or LoRa Disconnected" &&
//         !issue.resolved &&
//         !issue.movedToCategory
//     );

//     if (existingMasterIssue) {
//       if (masterSensor.connected_status === "connected") {
//         return;
//       }
//       return;
//     }

//     const existingSlaveHardwareIds = new Set();
//     supportRecord.issues
//       .filter(
//         (issue) =>
//           issue.hardwareId?.trim().toLowerCase() === normalizedConnectedTo &&
//           !issue.movedToCategory
//       )
//       .forEach((issue) => {
//         (issue.hardwareIds || []).forEach((id) => {
//           if (typeof id === "string") {
//             existingSlaveHardwareIds.add(id.trim().toLowerCase());
//           }
//         });
//       });

//     const newSlaveHardwareIds = [];
//     const newSlaveNames = [];

//     for (const slave of disconnectedSlaves) {
//       const sensorCurrent = sensors.find(
//         (s) => s.tankhardwareId?.trim().toLowerCase() === slave.slaveHardwareId
//       );
//       console.log("sensorCurrent",sensorCurrent)
//       if (
//         sensorCurrent &&
//         sensorCurrent.connected_status === "disconnected" &&
//         !existingSlaveHardwareIds.has(slave.slaveHardwareId)
//       ) {
//         newSlaveHardwareIds.push(slave.slaveHardwareId);
//         newSlaveNames.push(slave.slaveName);
//       }
//     }

//     // 👇 Even if no new slaves found, if master is disconnected, still raise a ticket
//     const masterDisconnected = masterSensor.connected_status !== "connected";

//     if (!masterDisconnected && newSlaveHardwareIds.length === 0) {
//       return;
//     }

//     const lastDataTime =
//       masterSensor.connected_gsm_date && masterSensor.connected_gsm_time
//         ? `${masterSensor.connected_gsm_date} ${masterSensor.connected_gsm_time}`
//         : "No data";

//     const message = `Master ${connected_to} is ${masterSensor.connected_status || "disconnected"}${newSlaveHardwareIds.length > 0
//       ? ` with ${newSlaveHardwareIds.length} disconnected slave(s)`
//       : ""}`;

//     const newIssue = {
//       type: "GSM or LoRa Disconnected",
//       masterHardwareId: normalizedConnectedTo,
//       hardwareId: normalizedConnectedTo,
//       hardwareIds: newSlaveHardwareIds,
//       slaveNames: newSlaveNames,
//       message,
//       disconnectedAt: lastDataTime,
//       lastTicketRaisedAt: formattedNow,
//       resolved: false,
//       movedToCategory: false,
//       createdAt: formattedNow,
//     };

//     await Support.findOneAndUpdate(
//       { supportId: "AWHYSU64" },
//       {
//         $push: { issues: newIssue },
//         $set: { updatedAt: new Date() },
//       }
//     );
//   } catch (error) {
//     console.error("Error in raiseATicketLikeLogic:", error);
//   }
// };



// Your existing raiseATicketLikeLogic function must be accessible

// ⬇️ Include the function here or import it if it's in another file
const updateConnectedStatusOnly = async (customerId, hardwareId) => {
  try {
    const sensors = await Insensors.find({ customerId });
    if (!sensors.length) return;

    const now = moment.tz("Asia/Kolkata");
    const latestRecord = await IotData.findOne({ hardwareId }).sort({ date: -1 }).lean();
    if (!latestRecord) return;

    const gsmTime = moment.tz(latestRecord.date, "Asia/Kolkata");
    const gsmDiff = now.diff(gsmTime, "minutes");
    const gsmConnected = gsmDiff <= 1;

    const connectedSlaves = sensors.filter(s => s.connected_to?.trim() === hardwareId);
    const tankMap = {};
    (latestRecord.tanks || []).forEach(t => {
      if (t.tankhardwareId) {
        tankMap[t.tankhardwareId.trim()] = t;
      }
    });

    const allSlavesConnected = connectedSlaves.every(slave => {
      const slaveId = slave.tankhardwareId?.trim();
      const tank = tankMap[slaveId];
      if (!tank || !tank.date || tank.tankHeight === "0") return false;
      const loraTime = moment.tz(tank.date, "Asia/Kolkata");
      return now.diff(loraTime, "minutes") <= 1;
    });

    const masterStatus = gsmConnected && allSlavesConnected ? "connected" : "disconnected";
    await Insensors.updateOne({ hardwareId, customerId }, { $set: { connected_status: masterStatus } });

    for (const slave of connectedSlaves) {
      const slaveId = slave.tankhardwareId?.trim();
      const tank = tankMap[slaveId];

      let status = "disconnected";
      if (tank && tank.date && tank.tankHeight !== "0") {
        const loraTime = moment.tz(tank.date, "Asia/Kolkata");
        if (now.diff(loraTime, "minutes") <= 1) status = "connected";
      }

      await Insensors.updateOne({ hardwareId: slave.hardwareId }, { $set: { connected_status: status } });
    }
  } catch (error) {
    console.error("❌ updateConnectedStatusOnly error:", error);
  }
};



// const raiseATicketLikeLogic = async (supportRecord, masterHardwareId, slaveData = []) => {
//   const now = new Date();
//   const formattedNow = new Date(now.getTime() + 19800000) // +05:30 offset in ms
//     .toISOString()
//     .replace("T", " ")
//     .substring(0, 19);

//   // Check if already categorized
//   const alreadyCategorized = supportRecord.categorizedIssues.some(
//     (catIssue) => catIssue.hardwareId === masterHardwareId
//   );

//   // Check if already raised and unresolved & not categorized
//   const alreadyRaisedUnresolved = supportRecord.issues.some(
//     (issue) =>
//       issue.hardwareId === masterHardwareId &&
//       issue.resolved === false &&
//       issue.movedToCategory === false
//   );

//   if (alreadyCategorized) {
//     console.log(`⛔ Ticket for ${masterHardwareId} already categorized. Skipping.`);
//     return;
//   }

//   if (alreadyRaisedUnresolved) {
//     console.log(`⛔ Unresolved ticket already exists for ${masterHardwareId}. Skipping.`);
//     return;
//   }

//   const slaveHardwareIds = slaveData.map((slave) => slave.tankhardwareId);
//   const slaveNames = slaveData.map((slave) => slave.sensorName || slave.tankName || "");

//   const newIssue = {
//     type: "GSM or LoRa Disconnected",
//     masterHardwareId,
//     hardwareId: masterHardwareId,
//     hardwareIds: slaveHardwareIds,
//     slaveNames: slaveNames,
//     resolved: false,
//     movedToCategory: false,
//     lastTicketRaisedAt: formattedNow,
//     createdAt: formattedNow,
//   };

//   supportRecord.issues.push(newIssue);
//   supportRecord.lastTicketRaisedAt = formattedNow;

//   await supportRecord.save();
//   console.log(`✅ New ticket raised for ${masterHardwareId}`);
// };



// exports.raiseATicket = async (req, reply) => {
//   try {
//     const { customerId, connected_to } = req.params;

//     if (!customerId || !connected_to) {
//       return reply.code(400).send({ error: "customerId and connected_to are required" });
//     }

//     const masterDevice = await Insensors.findOne({
//       customerId,
//       hardwareId: connected_to,
//       type: "master"
//     }).lean();

//     if (!masterDevice) {
//       return reply.code(404).send({ message: "Master device not found" });
//     }

//     const allSlaves = await Insensors.find({
//       connected_to,
//       customerId,
//       type: "slave"
//     }).lean();

//     const disconnectedSlaves = allSlaves.filter(
//       slave => slave.connected_status === "disconnected"
//     );

//     const hasDisconnectedSlaves = disconnectedSlaves.length > 0;
//     const isMasterDisconnected = masterDevice.connected_status === "disconnected";

//     // If nothing is disconnected, no ticket should be raised
//     if (!isMasterDisconnected && !hasDisconnectedSlaves) {
//       return reply.code(200).send({ message: "All devices are connected. No ticket needed." });
//     }

//     const supportId = `${customerId}_${connected_to}`;
//     const existingSupport = await Support.findOne({ supportId });

//     // Helper to check if hardwareId is already in unresolved & not moved
//     const isIssueAlreadyTracked = (supportDoc, hardwareId) => {
//       return supportDoc.issues?.some(issue => {
//         const allHwIds = [
//           issue.hardwareId?.toLowerCase(),
//           ...(issue.hardwareIds?.map(id => id?.toLowerCase()) || [])
//         ];
//         return (
//           allHwIds.includes(hardwareId.toLowerCase()) &&
//           !issue.resolved &&
//           issue.movedToCategory !== true
//         );
//       });
//     };

//     const nowTime = moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");

//     if (existingSupport) {
//       let updated = false;

//       // Add master if disconnected and not already tracked
//       if (isMasterDisconnected && !isIssueAlreadyTracked(existingSupport, masterDevice.hardwareId)) {
//         existingSupport.issues.push({
//           type: "master",
//           hardwareId: masterDevice.hardwareId,
//           masterName: masterDevice.deviceName || "",
//           resolved: false,
//           movedToCategory: false,
//           createdAt: nowTime,
//           lastTicketRaisedAt: nowTime
//         });
//         updated = true;
//       }

//       // Add each disconnected slave if not already tracked
//       for (const slave of disconnectedSlaves) {
//         if (isIssueAlreadyTracked(existingSupport, slave.hardwareId)) continue;

//         // If issue for this master already exists, append slave
//         let masterIssue = existingSupport.issues.find(issue =>
//           issue.type === "master" &&
//           issue.hardwareId === masterDevice.hardwareId &&
//           !issue.resolved
//         );

//         if (!masterIssue) {
//           // create new slave-type issue
//           existingSupport.issues.push({
//             type: "slave",
//             hardwareId: slave.hardwareId,
//             masterHardwareId: masterDevice.hardwareId,
//             slaveName: slave.deviceName || "",
//             resolved: false,
//             movedToCategory: false,
//             createdAt: nowTime,
//             lastTicketRaisedAt: nowTime
//           });
//         } else {
//           if (!masterIssue.hardwareIds) masterIssue.hardwareIds = [];
//           if (!masterIssue.slaveNames) masterIssue.slaveNames = [];
//           masterIssue.hardwareIds.push(slave.hardwareId);
//           masterIssue.slaveNames.push(slave.deviceName || "");
//           masterIssue.lastTicketRaisedAt = nowTime;
//         }

//         updated = true;
//       }

//       if (updated) {
//         await existingSupport.save();
//         return reply.code(201).send({ message: "Support ticket updated with new disconnected issues." });
//       } else {
//         return reply.code(200).send({ message: "No new disconnected issues to add." });
//       }

//     } else {
//       // Create new ticket
//       const issues = [];

//       if (isMasterDisconnected) {
//         issues.push({
//           type: "master",
//           hardwareId: masterDevice.hardwareId,
//           masterName: masterDevice.deviceName || "",
//           resolved: false,
//           movedToCategory: false,
//           createdAt: nowTime,
//           lastTicketRaisedAt: nowTime
//         });
//       }

//       for (const slave of disconnectedSlaves) {
//         issues.push({
//           type: "slave",
//           hardwareId: slave.hardwareId,
//           masterHardwareId: masterDevice.hardwareId,
//           slaveName: slave.deviceName || "",
//           resolved: false,
//           movedToCategory: false,
//           createdAt: nowTime,
//           lastTicketRaisedAt: nowTime
//         });
//       }

//       const newSupport = new Support({
//         supportId,
//         customerId,
//         connected_to,
//         createdAt: nowTime,
//         updatedAt: nowTime,
//         status: "open",
//         issues
//       });

//       await newSupport.save();
//       return reply.code(201).send({ message: "Support ticket created successfully." });
//     }

//   } catch (error) {
//     console.error("Error in raiseATicket:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };




// cron.schedule("* * * * *", async () => {
//   console.log("Running auto ticket check...");
//   const allMasters = await Insensors.find({  }).lean();
//   for (const master of allMasters) {
//     await raiseATicketLikeLogic(master.customerId, master.hardwareId);
//   }
// });

// cron.schedule("*/1 * * * *", async () => {
//   try {
//     console.log("🔁 Running auto-disconnect ticket check...");

//     // Find all master sensors
//     const allMasters = await Insensors.find({ type: "master" }).lean();

//     for (const master of allMasters) {
//       const customerId = master.customerId;
//       const hardwareId = master.hardwareId;

//       if (!customerId || !hardwareId) continue;

//       // Find slaves connected to this master
//       const connectedSlaves = await Insensors.find({
//         connected_to: hardwareId,
//         type: "slave"
//       }).lean();

//       // Filter disconnected slaves
//       const disconnectedSlaves = connectedSlaves.filter(
//         (s) => s.connected_status === "disconnected"
//       );

//       const masterIsDisconnected = master.connected_status === "disconnected";

//       // Only raise ticket if master is disconnected or has disconnected slaves
//       if (masterIsDisconnected || disconnectedSlaves.length > 0) {
//         await raiseATicketLikeLogic(customerId, hardwareId);
//       }
//     }

//     console.log("✅ Auto ticket check completed.");
//   } catch (err) {
//     console.error("Cron error:", err);
//   }
// });

const generateTicketId = () => {
  return "AWTKT" + Date.now(); // Or use UUID or nanoid
};


// const raiseATicketLikeLogic = async (supportRecord, masterHardwareId, slaveData = []) => {
//   const now = new Date();
//   const formattedNow = new Date(now.getTime() + 19800000) // +05:30 offset in ms
//     .toISOString()
//     .replace("T", " ")
//     .substring(0, 19);

//   // Check if already categorized
//   const alreadyCategorized = supportRecord.categorizedIssues.some(
//     (catIssue) => catIssue.hardwareId === masterHardwareId
//   );
//   if (alreadyCategorized) {
//     console.log(`⛔ Ticket for ${masterHardwareId} already categorized. Skipping.`);
//     return;
//   }

//   // Prepare slave hardwareIds and names
//   const slaveHardwareIds = slaveData.map((slave) => slave.tankhardwareId).sort();
//   const slaveNames = slaveData.map((slave) => slave.sensorName || slave.tankName || "").sort();

//   // Check for existing unresolved and not moved-to-category issue
//   const duplicateExists = supportRecord.issues.some((issue) => {
//     const existingSlaveIds = (issue.hardwareIds || []).sort();
//     const existingSlaveNames = (issue.slaveNames || []).sort();

//     return (
//       issue.hardwareId === masterHardwareId &&
//       issue.masterHardwareId === masterHardwareId &&
//       issue.resolved === false &&
//       issue.movedToCategory === false &&
//       JSON.stringify(existingSlaveIds) === JSON.stringify(slaveHardwareIds) &&
//       JSON.stringify(existingSlaveNames) === JSON.stringify(slaveNames)
//     );
//   });

//   if (duplicateExists) {
//     console.log(`⛔ Duplicate unresolved issue already exists for ${masterHardwareId}. Skipping.`);
//     return;
//   }

//   // Create new issue
//   const newIssue = {
//     ticketId: generateTicketId(),
//     type: "GSM or LoRa Disconnected",
//     masterHardwareId,
//     hardwareId: masterHardwareId,
//     hardwareIds: slaveHardwareIds,
//     slaveNames: slaveNames,
//     resolved: false,
//     movedToCategory: false,
//     lastTicketRaisedAt: formattedNow,
//     createdAt: formattedNow,
//   };
//   console.log("newIssue",newIssue)
//   supportRecord.issues.push(newIssue);
//   supportRecord.lastTicketRaisedAt = formattedNow;
//   await Support.findByIdAndUpdate(
//     supportRecord._id,
//     {
//       $push: { issues: newIssue },
//       $set: { lastTicketRaisedAt: formattedNow }
//     },
//     { new: true }
//   );
  
// console.log("")
//   await supportRecord.save();
//   console.log(`✅ New ticket raised for ${masterHardwareId}`);
// };

// const raiseATicketLikeLogic = async (supportRecord, masterHardwareId, slaveData = []) => {
//   const now = new Date();
//   const formattedNow = new Date(now.getTime() + 19800000)
//     .toISOString()
//     .replace("T", " ")
//     .substring(0, 19);

//   // Check if already categorized
//   const alreadyCategorized = supportRecord.categorizedIssues.some(
//     (catIssue) => catIssue.hardwareId === masterHardwareId
//   );
//   if (alreadyCategorized) {
//     console.log(`⛔ Ticket for ${masterHardwareId} already categorized. Skipping.`);
//     return;
//   }

//   // Prepare slave hardwareIds and names
//   const slaveHardwareIds = slaveData.map((slave) => slave.tankhardwareId).sort();
//   const slaveNames = slaveData.map((slave) => slave.sensorName || slave.tankName || "").sort();

//   // Check for existing unresolved and not moved-to-category issue
//   const duplicateExists = supportRecord.issues.some((issue) => {
//     const existingSlaveIds = (issue.hardwareIds || []).sort();
//     const existingSlaveNames = (issue.slaveNames || []).sort();

//     return (
//       issue.hardwareId === masterHardwareId &&
//       issue.masterHardwareId === masterHardwareId &&
//       issue.resolved === false &&
//       issue.movedToCategory === false &&
//       JSON.stringify(existingSlaveIds) === JSON.stringify(slaveHardwareIds) &&
//       JSON.stringify(existingSlaveNames) === JSON.stringify(slaveNames)
//     );
//   });

//   if (duplicateExists) {
//     console.log(`⛔ Duplicate unresolved issue already exists for ${masterHardwareId}. Skipping.`);
//     return;
//   }

//   // Create new issue
//   const newIssue = {
//     ticketId: generateTicketId(),
//     type: "GSM or LoRa Disconnected",
//     masterHardwareId,
//     hardwareId: masterHardwareId,
//     hardwareIds: slaveHardwareIds,
//     slaveNames: slaveNames,
//     resolved: false,
//     movedToCategory: false,
//     lastTicketRaisedAt: formattedNow,
//     createdAt: formattedNow,
//   };

//   console.log("newIssue", newIssue);

//   // ✅ Atomic update
//   await Support.findByIdAndUpdate(
//     supportRecord._id,
//     {
//       $push: { issues: newIssue },
//       $set: { lastTicketRaisedAt: formattedNow }
//     },
//     { new: true }
//   );

//   console.log(`✅ New ticket raised for ${masterHardwareId}`);
// };

// cron.schedule("*/1 * * * *", async () => {
//   try {
//     console.log("🔁 Running auto-disconnect ticket check...");

//     // Step 1: Get all support profiles
//     const allSupportProfiles = await Support.find({});

//     for (const supportRecord of allSupportProfiles) {
//       const supportId = supportRecord.supportId;
//       if (!supportId) continue;

//       // Step 2: Find all master sensors
//       const allMasters = await Insensors.find({ type: "master" }).lean();

//       for (const master of allMasters) {
//         const customerId = master.customerId;
//         const hardwareId = master.hardwareId;

//         if (!customerId || !hardwareId) continue;

//         // ✅ Update GSM and LoRa connection statuses
//         await updateConnectedStatusOnly(customerId, hardwareId);

//         // 🔄 Re-fetch updated master and slaves
//         const updatedMaster = await Insensors.findOne({ hardwareId, customerId }).lean();
//         const connectedSlaves = await Insensors.find({
//           connected_to: hardwareId,
//           type: "slave"
//         }).lean();

//         // Step 3: Check disconnections
//         const disconnectedSlaves = connectedSlaves.filter(
//           (s) => s.connected_status === "disconnected"
//         );
//         const masterIsDisconnected = updatedMaster.connected_status === "disconnected";

//         // Step 4: Raise ticket if needed
//         if (masterIsDisconnected || disconnectedSlaves.length > 0) {
//           await raiseATicketLikeLogic(supportRecord, hardwareId, disconnectedSlaves);
//         }
//       }
//     }

//     console.log("✅ Auto ticket check completed.");
//   } catch (err) {
//     console.error("❌ Cron error:", err);
//   }
// });

// const raiseATicketLikeLogic = async (supportRecord, masterHardwareId, slaveData = []) => {
//   const now = new Date();
//   const formattedNow = new Date(now.getTime() + 19800000) // +05:30 offset in ms
//     .toISOString()
//     .replace("T", " ")
//     .substring(0, 19);

//   // Check if already categorized
//   const alreadyCategorized = supportRecord.categorizedIssues.some(
//     (catIssue) => catIssue.hardwareId === masterHardwareId
//   );
//   if (alreadyCategorized) {
//     console.log(`⛔ Ticket for ${masterHardwareId} already categorized. Skipping.`);
//     return;
//   }

//   // Prepare slave hardwareIds and names
//   const slaveHardwareIds = slaveData.map((slave) => slave.tankhardwareId).sort();
//   const slaveNames = slaveData.map((slave) => slave.sensorName || slave.tankName || "").sort();

//   // Check for existing unresolved and not moved-to-category issue
//   const duplicateExists = supportRecord.issues.some((issue) => {
//     const existingSlaveIds = (issue.hardwareIds || []).sort();
//     const existingSlaveNames = (issue.slaveNames || []).sort();

//     return (
//       issue.hardwareId === masterHardwareId &&
//       issue.masterHardwareId === masterHardwareId &&
//       issue.resolved === false &&
//       issue.movedToCategory === false &&
//       JSON.stringify(existingSlaveIds) === JSON.stringify(slaveHardwareIds) &&
//       JSON.stringify(existingSlaveNames) === JSON.stringify(slaveNames)
//     );
//   });

//   if (duplicateExists) {
//     console.log(`⛔ Duplicate unresolved issue already exists for ${masterHardwareId}. Skipping.`);
//     return;
//   }

//   // Create new issue
//   const newIssue = {
//     type: "GSM or LoRa Disconnected",
//     masterHardwareId,
//     hardwareId: masterHardwareId,
//     hardwareIds: slaveHardwareIds,
//     slaveNames: slaveNames,
//     resolved: false,
//     movedToCategory: false,
//     lastTicketRaisedAt: formattedNow,
//     createdAt: formattedNow,
//   };

//   supportRecord.issues.push(newIssue);
//   supportRecord.lastTicketRaisedAt = formattedNow;

//   await supportRecord.save();
//   console.log(`✅ New ticket raised for ${masterHardwareId}`);
// };

// const raiseATicketLikeLogic = async (supportRecord, masterHardwareId, slaveData = []) => {
//   const now = new Date();
//   const formattedNow = new Date(now.getTime() + 19800000) // +05:30 offset in ms
//     .toISOString()
//     .replace("T", " ")
//     .substring(0, 19);

//   // Check if already categorized
//   const alreadyCategorized = supportRecord.categorizedIssues.some(
//     (catIssue) => catIssue.hardwareId === masterHardwareId
//   );
//   if (alreadyCategorized) {
//     console.log(`⛔ Ticket for ${masterHardwareId} already categorized. Skipping.`);
//     return;
//   }

//   // Check for existing unresolved, uncategorized ticket for same master
//   const duplicateExists = supportRecord.issues.some((issue) => {
//     return (
//       issue.hardwareId === masterHardwareId &&
//       issue.masterHardwareId === masterHardwareId &&
//       issue.resolved === false &&
//       issue.movedToCategory === false
//     );
//   });

//   if (duplicateExists) {
//     console.log(`⛔ Duplicate unresolved issue already exists for ${masterHardwareId}. Skipping.`);
//     return;
//   }

//   // Prepare slave hardwareIds and names
//   const slaveHardwareIds = slaveData.map((slave) => slave.tankhardwareId).sort();
//   const slaveNames = slaveData.map((slave) => slave.sensorName || slave.tankName || "").sort();

//   // Create new issue
//   const newIssue = {
//     type: "GSM or LoRa Disconnected",
//     masterHardwareId,
//     hardwareId: masterHardwareId,
//     hardwareIds: slaveHardwareIds,
//     slaveNames: slaveNames,
//     resolved: false,
//     movedToCategory: false,
//     lastTicketRaisedAt: formattedNow,
//     createdAt: formattedNow,
//   };

//   supportRecord.issues.push(newIssue);
//   supportRecord.lastTicketRaisedAt = formattedNow;

//   await supportRecord.save();
//   console.log(`✅ New ticket raised for ${masterHardwareId}`);
// };

const raiseATicketLikeLogic = async (supportRecord, masterHardwareId, slaveData = []) => {
  const now = new Date();
  const formattedNow = new Date(now.getTime() + 19800000) // +05:30 IST offset
    .toISOString()
    .replace("T", " ")
    .substring(0, 19);

  // ✅ If issue already exists anywhere for this hardwareId, SKIP
  const issueAlreadyExists = [
    ...supportRecord.issues,
    ...supportRecord.categorizedIssues,
    ...supportRecord.resolvedIssues
  ].some((issue) => issue.hardwareId === masterHardwareId);

  if (issueAlreadyExists) {
    console.log(`⛔ Issue already exists for ${masterHardwareId}. Not raising again.`);
    return;
  }

  // ✅ Prepare slave hardwareIds and names
  const slaveHardwareIds = slaveData.map((s) => s.tankhardwareId).sort();
  const slaveNames = slaveData.map((s) => s.sensorName || s.tankName || "").sort();

  // ✅ Create new issue
  const newIssue = {
    type: "GSM or LoRa Disconnected",
    masterHardwareId,
    hardwareId: masterHardwareId,
    hardwareIds: slaveHardwareIds,
    slaveNames: slaveNames,
    resolved: false,
    movedToCategory: false,
    lastTicketRaisedAt: formattedNow,
    createdAt: formattedNow,
  };

  supportRecord.issues.push(newIssue);
  supportRecord.lastTicketRaisedAt = formattedNow;

  await supportRecord.save();
  console.log(`✅ New ticket raised for ${masterHardwareId}`);
};


cron.schedule("*/1 * * * *", async () => {
  try {
    console.log("🔁 Running auto-disconnect ticket check...");

    // Step 1: Get all support profiles
    const allSupportProfiles = await Support.find({});

    for (const supportRecord of allSupportProfiles) {
      const supportId = supportRecord.supportId;
      if (!supportId) continue;

      // Step 2: Find all master sensors
      const allMasters = await Insensors.find({ type: "master" }).lean();

      for (const master of allMasters) {
        const customerId = master.customerId;
        const hardwareId = master.hardwareId;

        if (!customerId || !hardwareId) continue;

        // ✅ Update GSM and LoRa connection statuses
        await updateConnectedStatusOnly(customerId, hardwareId);

        // 🔄 Re-fetch updated master and slaves
        const updatedMaster = await Insensors.findOne({ hardwareId, customerId }).lean();
        const connectedSlaves = await Insensors.find({
          connected_to: hardwareId,
          type: "slave"
        }).lean();

        // Step 3: Check disconnections
        const disconnectedSlaves = connectedSlaves.filter(
          (s) => s.connected_status === "disconnected"
        );
        const masterIsDisconnected = updatedMaster.connected_status === "disconnected";

        // Step 4: Raise ticket if needed
        if (masterIsDisconnected || disconnectedSlaves.length > 0) {
          await raiseATicketLikeLogic(supportRecord, hardwareId, disconnectedSlaves);
        }
      }
    }

    console.log("✅ Auto ticket check completed.");
  } catch (err) {
    console.error("❌ Cron error:", err);
  }
});



exports.raiseATicketBuildingDetails = async (req, reply) => {
  try {
    const { customerId, connected_to, installationId } = req.params;

    if (!customerId || !connected_to || !installationId) {
      return reply.code(400).send({ error: "customerId, connected_to, and installationId are required" });
    }

    const customer = await User.findOne({ customerId, installationId }).lean();
    if (!customer) {
      return reply.code(404).send({ message: "Customer not found." });
    }

    const sensors = await Insensors.find({ customerId });
    if (!sensors.length) {
      return reply.code(404).send({ message: "No sensors found for this customer." });
    }

    const masterSensor = sensors.find(s => (s.hardwareId?.trim() === connected_to.trim()));
    if (!masterSensor) {
      return reply.code(404).send({ message: "Master hardwareId not found." });
    }

    const latestMasterRecord = await IotData.findOne({ hardwareId: connected_to }).sort({ date: -1 }).lean();
    if (!latestMasterRecord) {
      return reply.code(404).send({ message: "No IoT data found for this hardwareId." });
    }

    const indiaTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
    const now = moment.tz("Asia/Kolkata");
    const formattedNow = now.format("YYYY-MM-DD HH:mm:ss");

    const diffInMinutesMaster = now.diff(indiaTime, "minutes");

    if (diffInMinutesMaster > 1) {
      await Insensors.updateOne(
        { hardwareId: connected_to },
        { $set: { lastTicketRaisedAt: formattedNow } }
      );
    }

    const connectedSlaves = sensors.filter(sensor => sensor.connected_to?.trim() === connected_to.trim());

    // ✅ Check if any slave is disconnected
    const disconnectedSlave = connectedSlaves.find(slave => slave.connected_status === "disconnected");
    if (disconnectedSlave) {
      return reply.code(400).send({
        error: `Slave device ${disconnectedSlave.hardwareId} is disconnected. Cannot raise ticket.`
      });
    }

    for (const slave of connectedSlaves) {
      const slaveId = slave.hardwareId?.trim();
      const matchedTank = latestMasterRecord.tanks.find(tank => tank.tankhardwareId === slaveId);

      if (matchedTank && matchedTank.date) {
        const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata");
        const loraDiffInMinutes = now.diff(tankTime, "minutes");

        if (loraDiffInMinutes > 1) {
          await Insensors.updateOne(
            { hardwareId: slaveId },
            { $set: { lastTicketRaisedAt: formattedNow } }
          );
        }
      }
    }

    await Support.updateOne(
      { supportId: "AWHYSU64" },
      { $set: { lastTicketRaisedAt: formattedNow } }
    );

    // Fetch updated values
    const updatedMasterSensor = await Insensors.findOne({ hardwareId: connected_to }).lean();
    const updatedSupport = await Support.findOne({ supportId: "AWHYSU64" }).lean();

    return reply.send({
      status_code: 200,
      customer,
      lastTicketRaisedAt: {
        masterSensor: updatedMasterSensor?.lastTicketRaisedAt || null,
        support: updatedSupport?.lastTicketRaisedAt || null
      }
    });

  } catch (error) {
    console.error("Error raising ticket:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};


exports.raiseATicketSlave = async (req, reply) => {
  try {
    const { customerId, connected_to } = req.params;

    if (!customerId || !connected_to) {
      return reply.code(400).send({ error: "customerId and connected_to are required" });
    }

    const sensors = await Insensors.find({ customerId });
    const masterSensor = sensors.find(s => s.hardwareId?.trim() === connected_to.trim());

    if (!masterSensor) {
      return reply.code(404).send({ message: "Master hardwareId not found." });
    }

    const latestMasterRecord = await IotData.findOne({ hardwareId: connected_to }).sort({ date: -1 }).lean();

    if (!latestMasterRecord) {
      return reply.code(404).send({ message: "No IoT data found for this hardwareId." });
    }

    const now = moment().tz("Asia/Kolkata");
    const masterTime = moment.tz(latestMasterRecord.date, "Asia/Kolkata");
    const diff = now.diff(masterTime, "minutes");

    const gsm_connected_status = diff <= 1 ? "connected" : "disconnected";
    const gsmStatus = gsm_connected_status === "connected" ? "GSM Connected" : "GSM Disconnected";

    const formattedTime = masterTime.format("HH:mm:ss");
    const formattedDate = masterTime.format("DD-MM-YYYY");

    const tanks = (latestMasterRecord.tanks || []).map(tank => {
      const tankTime = moment.tz(tank.date, "Asia/Kolkata");
      const timeDiff = now.diff(tankTime, "minutes");

      return {
        ...tank,
        time: tankTime.format("HH:mm:ss"),
        connected_status: timeDiff <= 1 ? "connected" : "disconnected"
      };
    });

    const responseData = {
      hardwareId: connected_to,
      gsm_connected_status,
      gsmStatus,
      connected_gsm_date: formattedDate,
      connected_gsm_time: formattedTime,
      gsm_last_check_time: now.format("DD-MM-YYYY HH:mm:ss"),
      tanks,
      date: latestMasterRecord.date,
      time: formattedTime
    };

    return reply.send({
      status_code: 200,
      message: "Success",
      data: responseData
    });

  } catch (error) {
    console.error("Error in raiseATicketSlave:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};






// exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
//   try {
//     const { supportId } = req.params;

//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     const allIssues = supportRecord.issues || [];
//     const hardwareSet = new Set();

//     // Collect all hardware IDs from issues
//     for (const issue of allIssues) {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId); // GSM
//       if (Array.isArray(issue.hardwareIds)) {
//         issue.hardwareIds.forEach(id => hardwareSet.add(id)); // LoRa slaves
//       }
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId); // LoRa master
//     }

//     const hardwareIds = [...hardwareSet];
//     const sensors = await Insensors.find({ hardwareId: { $in: hardwareIds } }).lean();
// console.log("sensors",sensors)
//     // Map sensors by hardwareId
//     const sensorMap = {};
//     for (const sensor of sensors) {
//       sensorMap[sensor.hardwareId] = sensor;
//     }

//     const masterMap = {};

//     for (const issue of allIssues) {
//       // GSM Disconnected
//       if (issue.type === "GSM or LoRa Disconnected" && issue.hardwareId) {
//         const sensor = sensorMap[issue.hardwareId];
//         if (sensor && sensor.type === "master") {
//           masterMap[sensor.hardwareId] = {
//             hardwareId: sensor.hardwareId,
//             masterName: sensor.masterName || null,
//             location: sensor.location || "",
//             type: "master",
//             connected_status: sensor.connected_status,
//             gsm_last_check_time: sensor.gsm_last_check_time,
//             gsm_last_disconnect_time: sensor.gsm_last_disconnect_time,
//             connected_gsm_date: sensor.connected_gsm_date,
//             connected_gsm_time: sensor.connected_gsm_time,
//             connected_lora_date: sensor.connected_lora_date,
//             connected_lora_time: sensor.connected_lora_time,
//             support_gsm_last_check_time: sensor.support_gsm_last_check_time,
//             connected_slave_count: 0,
//             connected_slaves: []
//           };
//         }
//       }

//       // LoRa Disconnected
//       if (issue.type === "GSM or LoRa Disconnected" && issue.masterHardwareId) {
//         const masterSensor = sensorMap[issue.masterHardwareId];
//         if (!masterSensor || masterSensor.type !== "master") continue;

//         if (!masterMap[masterSensor.hardwareId]) {
//           masterMap[masterSensor.hardwareId] = {
//             hardwareId: masterSensor.hardwareId,
//             masterName: masterSensor.masterName || null,
//             location: masterSensor.location || "",
//             type: "master",
//             connected_status: masterSensor.connected_status,
//             gsm_last_check_time: masterSensor.gsm_last_check_time,
//             gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
//             connected_gsm_date: masterSensor.connected_gsm_date,
//             connected_gsm_time: masterSensor.connected_gsm_time,
//             connected_lora_date: masterSensor.connected_lora_date,
//             connected_lora_time: masterSensor.connected_lora_time,
//             support_lora_last_check_time: masterSensor.support_lora_last_check_time,
//             connected_slave_count: 0,
//             connected_slaves: []
//           };
//         }

//         const master = masterMap[masterSensor.hardwareId];

//         // First try from issue.hardwareIds
//         let slaveIds = Array.isArray(issue.hardwareIds) ? issue.hardwareIds : [];

//         // If empty, fallback to slaves connected to this master
//       // If empty, fallback to slaves connected to this master's tankHardwareId
//       console.log("slaveIds",slaveIds)
//       if (slaveIds.length === 0) {
//         // fallback: find slaves connected to this master hardwareId
//         const fallbackSlaves = await Insensors.find({
//           connected_to: issue.masterHardwareId, // or masterSensor.hardwareId
//           type: "slave"
//         }).lean();
      
//         console.log("fallbackSlaves", fallbackSlaves);
//         for (const slaveSensor of fallbackSlaves) {
//           master.connected_slaves.push({
//             hardwareId: slaveSensor.hardwareId,
//             tankName: slaveSensor.tankName || "",
//             location: slaveSensor.location || "",
//             connected_status: slaveSensor.connected_status,
//             connected_lora_time: slaveSensor.connected_lora_time,
//             connected_lora_date: slaveSensor.connected_lora_date,
//             lora_last_check_time: slaveSensor.lora_last_check_time,
//             lora_last_disconnect_time: slaveSensor.lora_last_disconnect_time,
//             connected_to: slaveSensor.connected_to,
//             masterName: master.masterName,
//             type: "slave",
//             typeOfWater: slaveSensor.typeOfWater,
//             tankHeight: slaveSensor.tankHeight,
//             support_lora_last_check_time: slaveSensor.support_lora_last_check_time,
//           });
//           master.connected_slave_count++;
//         }
//       }
      
//  else {
//           // Populate slaves based on provided hardwareIds
//           for (const slaveId of slaveIds) {
//             const slaveSensor = sensorMap[slaveId];
//             if (slaveSensor && slaveSensor.type === "slave") {
//               master.connected_slaves.push({
//                 hardwareId: slaveSensor.hardwareId,
//                 tankName: slaveSensor.tankName || "",
//                 location: slaveSensor.location || "",
//                 connected_status: slaveSensor.connected_status,
//                 connected_lora_time: slaveSensor.connected_lora_time,
//                 connected_lora_date: slaveSensor.connected_lora_date,
//                 lora_last_check_time: slaveSensor.lora_last_check_time,
//                 lora_last_disconnect_time: slaveSensor.lora_last_disconnect_time,
//                 connected_to: slaveSensor.connected_to,
//                 masterName: master.masterName,
//                 type: "slave",
//                 typeOfWater: slaveSensor.typeOfWater,
//                 tankHeight: slaveSensor.tankHeight,
//                 support_lora_last_check_time: slaveSensor.support_lora_last_check_time,
//               });
//               master.connected_slave_count++;
//             }
//           }
//         }
//       }
//     }

//     const finalResponse = Object.values(masterMap);

//     return reply.send({
//       status_code: 200,
//       supportId,
//       totalMasters: finalResponse.length,
//       disconnectedIssues: finalResponse
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected issues:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

// exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
//   try {
//     const { supportId } = req.params;

//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     const allIssues = supportRecord.issues || [];
//     const hardwareSet = new Set();

//     // Collect all hardware IDs and tankHardwareIds from issues
//     for (const issue of allIssues) {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId); // GSM
//       if (Array.isArray(issue.hardwareIds)) {
//         issue.hardwareIds.forEach(id => hardwareSet.add(id)); // LoRa slaves
//       }
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId); // LoRa master
//     }

//     const hardwareIds = [...hardwareSet];
//     const sensors = await Insensors.find({
//       $or: [
//         { hardwareId: { $in: hardwareIds } },
//         { tankHardwareId: { $in: hardwareIds } }
//       ]
//     }).lean();

//     const customerId = supportRecord.customerId;
//     const orders = await Order.find({ customerId }).lean();

//     const orderMap = {};
//     for (const order of orders) {
//       if (Array.isArray(order.master_connections)) {
//         order.master_connections.forEach(conn => {
//           if (conn.hardwareId) {
//             orderMap[conn.hardwareId] = {
//               masterName: conn.master_name || null,
//               location: conn.location || null
//             };
//           }
//         });
//       }
//     }
//     // Map sensors by both hardwareId and tankHardwareId
//     const sensorMap = {};
//     for (const sensor of sensors) {
//       if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
//       if (sensor.tankHardwareId) sensorMap[sensor.tankHardwareId] = sensor;
//     }

//     const masterMap = {};

//     for (const issue of allIssues) {
//       // GSM Disconnected
//       if (issue.type === "GSM or LoRa Disconnected" && issue.hardwareId) {
//         const sensor = sensorMap[issue.hardwareId];
//         if (sensor && sensor.type === "master") {
//           const enriched = orderMap[sensor.hardwareId] || {};
//           masterMap[sensor.hardwareId] = {
//             hardwareId: sensor.hardwareId,
//             masterName: enriched.masterName || sensor.masterName || null,
//             location: enriched.location || sensor.location || "",
//             type: "master",
//             connected_status: sensor.connected_status,
//             gsm_last_check_time: sensor.gsm_last_check_time,
//             gsm_last_disconnect_time: sensor.gsm_last_disconnect_time,
//             connected_gsm_date: sensor.connected_gsm_date,
//             connected_gsm_time: sensor.connected_gsm_time,
//             connected_lora_date: sensor.connected_lora_date,
//             connected_lora_time: sensor.connected_lora_time,
//             support_gsm_last_check_time: sensor.support_gsm_last_check_time,
//             connected_slave_count: 0,
//             connected_slaves: []
//           };
//         }
//       }

//       // LoRa Disconnected
//       if (issue.type === "GSM or LoRa Disconnected" && issue.masterHardwareId) {
//         const masterSensor = sensorMap[issue.masterHardwareId];
//         if (!masterSensor || masterSensor.type !== "master") continue;

//         if (!masterMap[masterSensor.hardwareId]) {
//           masterMap[masterSensor.hardwareId] = {
//             hardwareId: masterSensor.hardwareId,
//             masterName: masterSensor.masterName || null,
//             location: masterSensor.location || "",
//             type: "master",
//             connected_status: masterSensor.connected_status,
//             gsm_last_check_time: masterSensor.gsm_last_check_time,
//             gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
//             connected_gsm_date: masterSensor.connected_gsm_date,
//             connected_gsm_time: masterSensor.connected_gsm_time,
//             connected_lora_date: masterSensor.connected_lora_date,
//             connected_lora_time: masterSensor.connected_lora_time,
//             support_lora_last_check_time: masterSensor.support_lora_last_check_time,
//             connected_slave_count: 0,
//             connected_slaves: []
//           };
//         }

//         const master = masterMap[masterSensor.hardwareId];
//         let slaveIds = Array.isArray(issue.hardwareIds) ? issue.hardwareIds : [];
//         console.log("slaveIds",slaveIds)
//         let fallbackSlaves = [];

//         if (slaveIds.length > 0) {
//           // Try to fetch slaves by hardwareId or tankHardwareId
//           fallbackSlaves = await Insensors.find({
//             $or: [
//               { hardwareId: { $in: slaveIds } },
//               { tankhardwareId: { $in: slaveIds } }
//             ],
//             type: "slave"
//           }).lean();
//         } else {
//           // Fallback: find by connected_to field
//           fallbackSlaves = await Insensors.find({
//             connected_to: issue.masterHardwareId,
//             type: "slave"
//           }).lean();
//         }

//         for (const slaveSensor of fallbackSlaves) {
//           master.connected_slaves.push({
//             hardwareId: slaveSensor.hardwareId,
//             tankName: slaveSensor.tankName || "",
//             location: slaveSensor.location || "",
//             connected_status: slaveSensor.connected_status,
//             connected_lora_time: slaveSensor.connected_lora_time,
//             connected_lora_date: slaveSensor.connected_lora_date,
//             lora_last_check_time: slaveSensor.lora_last_check_time,
//             lora_last_disconnect_time: slaveSensor.lora_last_disconnect_time,
//             connected_to: slaveSensor.connected_to,
//             masterName: master.masterName,
//             type: "slave",
//             typeOfWater: slaveSensor.typeOfWater,
//             tankHeight: slaveSensor.tankHeight,
//             support_lora_last_check_time: slaveSensor.support_lora_last_check_time,
//           });
//           master.connected_slave_count++;
//         }
//       }
//     }

//     const finalResponse = Object.values(masterMap);

//     return reply.send({
//       status_code: 200,
//       supportId,
//       totalMasters: finalResponse.length,
//       disconnectedIssues: finalResponse
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected issues:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };
// exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
//   try {
//     const { supportId } = req.params;

//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     const allIssues = [...(supportRecord.issues || []), ...(supportRecord.categorizedIssues || [])];
//     const hardwareSet = new Set();

//     for (const issue of allIssues) {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
//       if (Array.isArray(issue.hardwareIds)) {
//         issue.hardwareIds.forEach(id => hardwareSet.add(id));
//       }
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
//     }

//     const hardwareIds = [...hardwareSet];

//     const sensors = await Insensors.find({
//       $or: [
//         { hardwareId: { $in: hardwareIds } },
//         { tankhardwareId: { $in: hardwareIds } }
//       ]
//     }).lean();

//     const sensorMap = {};
//     for (const sensor of sensors) {
//       if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
//       if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
//     }

//     const customerId = sensors.length > 0 ? sensors[0].customerId : null;
//     const orders = customerId ? await Order.find({ customerId }).lean() : [];

//     const orderMap = {};
//     for (const order of orders) {
//       if (Array.isArray(order.master_connections)) {
//         for (const conn of order.master_connections) {
//           if (conn.hardwareId) {
//             orderMap[conn.hardwareId] = {
//               masterName: conn.master_name || null,
//               location: conn.location || null
//             };
//           }
//         }
//       }
//     }

//     const masterMap = {};
//     const assignedSlaves = new Set();

//  // ✅ Step 1: Get all unique master hardware IDs involved in the issues
// const masterHardwareIds = new Set();

// for (const issue of allIssues) {
//   const masterId = issue.masterHardwareId || issue.hardwareId;
//   const sensor = sensorMap[masterId];
//   if (sensor?.type === "master") {
//     masterHardwareIds.add(sensor.hardwareId);
//   }
// }

// // ✅ Step 2: Process each unique master once
// for (const masterId of masterHardwareIds) {
//   const masterSensor = sensorMap[masterId];
//   if (!masterSensor) continue;

//   const enriched = orderMap[masterSensor.hardwareId] || {};
//   if (!masterMap[masterSensor.hardwareId]) {
//     masterMap[masterSensor.hardwareId] = {
//       hardwareId: masterSensor.hardwareId,
//       masterName: masterSensor.masterName || enriched.masterName || "",
//       location: masterSensor.location || enriched.location || "",
//       type: "master",
//       connected_status: masterSensor.connected_status,
//       gsm_last_check_time: masterSensor.gsm_last_check_time,
//       gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
//       connected_gsm_date: masterSensor.connected_gsm_date,
//       connected_gsm_time: masterSensor.connected_gsm_time,
//       connected_lora_date: masterSensor.connected_lora_date,
//       connected_lora_time: masterSensor.connected_lora_time,
//       support_gsm_last_check_time: masterSensor.support_gsm_last_check_time,
//       connected_slave_count: 0,
//       connected_slaves: []
//     };
//   }

//   const master = masterMap[masterSensor.hardwareId];

//   const fallbackSlaves = await Insensors.find({
//     connected_to: masterSensor.hardwareId,
//     type: "slave"
//   }).lean();

//   for (const slaveSensor of fallbackSlaves) {
//     const slaveKey = slaveSensor.tankhardwareId || slaveSensor.hardwareId;
//     if (!slaveKey || assignedSlaves.has(slaveKey)) continue;
//     if (slaveSensor.connected_status !== "disconnected") continue;

//     assignedSlaves.add(slaveKey);

//     let typeOfWater = "";
//     if (customerId && slaveSensor.tankhardwareId) {
//       const tank = await Tank.findOne({
//         customerId,
//         tankhardwareId: slaveSensor.tankhardwareId
//       }).lean();
//       if (tank?.typeOfWater) typeOfWater = tank.typeOfWater;
//     }

//     master.connected_slaves.push({
//       hardwareId: slaveSensor.tankhardwareId || slaveSensor.hardwareId,
//       tankName: slaveSensor.tankName || "",
//       location: slaveSensor.location || "",
//       connected_status: slaveSensor.connected_status,
//       connected_lora_time: slaveSensor.connected_lora_time,
//       connected_lora_date: slaveSensor.connected_lora_date,
//       lora_last_check_time: slaveSensor.lora_last_check_time,
//       lora_last_disconnect_time: slaveSensor.lora_last_disconnect_time,
//       connected_to: slaveSensor.connected_to,
//       masterName: master.masterName,
//       type: "slave",
//       typeOfWater,
//       tankHeight: slaveSensor.tankHeight,
//       support_lora_last_check_time: slaveSensor.support_lora_last_check_time
//     });

//     master.connected_slave_count++;
//   }
// }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       totalMasters: Object.keys(masterMap).length,
//       disconnectedIssues: Object.values(masterMap)
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected issues:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

// exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
//   try {
//     const { supportId } = req.params;
//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     const allIssues = supportRecord.issues || [];
//     const hardwareSet = new Set();

//     // Collect hardwareId and masterHardwareId
//     for (const issue of allIssues) {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
//     }

//     const hardwareIds = [...hardwareSet];
//     const sensors = await Insensors.find({
//       $or: [
//         { hardwareId: { $in: hardwareIds } },
//         { tankhardwareId: { $in: hardwareIds } }
//       ]
//     }).lean();

//     const sensorMap = {};
//     for (const sensor of sensors) {
//       if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
//       if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
//     }

//     const customerId = supportRecord.customerId;
//     const orders = await Order.find({ customerId }).lean();

//     const orderMap = {};
//     for (const order of orders) {
//       (order.master_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           orderMap[conn.hardwareId] = {
//             masterName: conn.master_name || null,
//             location: conn.location || null
//           };
//         }
//       });
//     }
//     console.log("order",orderMap)
//     const masterMap = {};

//     for (const issue of allIssues) {
//       const masterId = issue.masterHardwareId || issue.hardwareId;
//       const masterSensor = sensorMap[masterId];
//       if (!masterSensor || masterSensor.type !== "master") continue;

//       // If master not already added
//       if (!masterMap[masterSensor.hardwareId]) {
//         const enriched = orderMap[masterSensor.hardwareId] || {};
//         masterMap[masterSensor.hardwareId] = {
//           hardwareId: masterSensor.hardwareId,
//           masterName: enriched.masterName || masterSensor.masterName || "",
//           location: enriched.location || masterSensor.location || "",
//           type: "master",
//           connected_status: masterSensor.connected_status,
//           gsm_last_check_time: masterSensor.gsm_last_check_time,
//           gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
//           connected_gsm_date: masterSensor.connected_gsm_date,
//           connected_gsm_time: masterSensor.connected_gsm_time,
//           connected_lora_date: masterSensor.connected_lora_date,
//           connected_lora_time: masterSensor.connected_lora_time,
//           support_gsm_last_check_time: masterSensor.support_gsm_last_check_time,
//           support_lora_last_check_time: masterSensor.support_lora_last_check_time,
//           team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time,
//           team_member_support_lora_last_check_time: masterSensor.team_member_support_lora_last_check_time,
//           connected_slave_count: 0,
//           connected_slaves: []
//         };
//       }

//       const master = masterMap[masterSensor.hardwareId];
//       console.log("master",master)

//       // ✅ Always fetch slaves using connected_to
//       const connectedSlaves = await Insensors.find({
//         connected_to: masterSensor.hardwareId,
//         type: "slave"
//       }).lean();

//       for (const slave of connectedSlaves) {
//         // Only include disconnected slaves
//         if (slave.connected_status !== "disconnected") continue;

//         master.connected_slaves.push({
//           hardwareId: slave.tankhardwareId || slave.hardwareId,
//           tankName: slave.tankName || "",
//           location: slave.location || "",
//           connected_status: slave.connected_status,
//           connected_lora_time: slave.connected_lora_time,
//           connected_lora_date: slave.connected_lora_date,
//           lora_last_check_time: slave.lora_last_check_time,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time,
//           connected_to: slave.connected_to,
//           masterName: master.masterName,
//           type: "slave",
//           typeOfWater: slave.typeOfWater || "",
//           tankHeight: slave.tankHeight,
//           support_lora_last_check_time: slave.support_lora_last_check_time,
//           //team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time,
//           team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time,
//         });

//         master.connected_slave_count++;
//       }
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       totalMasters: Object.keys(masterMap).length,
//       disconnectedIssues: Object.values(masterMap)
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected issues:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

//final
// exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
//   try {
//     const { supportId } = req.params;
//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     const allIssues = supportRecord.issues || [];
//     const hardwareSet = new Set();

//     for (const issue of allIssues) {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
//     }

//     const hardwareIds = [...hardwareSet];

//     const sensors = await Insensors.find({
//       $or: [
//         { hardwareId: { $in: hardwareIds } },
//         { tankhardwareId: { $in: hardwareIds } }
//       ]
//     }).lean();

//     const sensorMap = {};
//     for (const sensor of sensors) {
//       if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
//       if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
//     }

//     let customerId = supportRecord.customerId;
//     if (!customerId) {
//       const firstSensor = sensors.find(sensor => sensor.customerId);
//       if (firstSensor) {
//         customerId = firstSensor.customerId;
//       } else {
//         return reply.code(404).send({ message: "Unable to determine customerId from support or sensors." });
//       }
//     }

//     const orders = await Order.find({ customerId }).lean();

//     const orderMap = {};
//     for (const order of orders) {
//       (order.master_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           orderMap[conn.hardwareId] = {
//             masterName: conn.master_name || null,
//             location: conn.location || null
//           };
//         }
//       });
//     }

//     const slaveOrderMap = {};
//     for (const order of orders) {
//       (order.tank_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           slaveOrderMap[conn.hardwareId] = {
//             location: conn.location || null,
//             typeOfWater: conn.typeOfWater || null
//           };
//         }
//       });
//     }

//     const masterMap = {};

//     for (const issue of allIssues) {
//       const masterId = issue.masterHardwareId || issue.hardwareId;
//       const masterSensor = sensorMap[masterId];
//       if (!masterSensor || masterSensor.type !== "master") continue;

//       if (!masterMap[masterSensor.hardwareId]) {
//         const enriched = orderMap[masterSensor.hardwareId] || {};
//         masterMap[masterSensor.hardwareId] = {
//           hardwareId: masterSensor.hardwareId,
//           masterName: enriched.masterName || masterSensor.masterName || "",
//           location: enriched.location || masterSensor.location || "",
//           type: "master",
//           connected_status: masterSensor.connected_status,
//           gsm_last_check_time: masterSensor.gsm_last_check_time,
//           gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
//           connected_gsm_date: masterSensor.connected_gsm_date,
//           connected_gsm_time: masterSensor.connected_gsm_time,
//           connected_lora_date: masterSensor.connected_lora_date,
//           connected_lora_time: masterSensor.connected_lora_time,
//           support_gsm_last_check_time: masterSensor.support_gsm_last_check_time,
//           support_lora_last_check_time: masterSensor.support_lora_last_check_time,
//           team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time,
//           team_member_support_lora_last_check_time: masterSensor.team_member_support_lora_last_check_time,
//           connected_slave_count: 0,
//           connected_slaves: []
//         };
//       }

//       const master = masterMap[masterSensor.hardwareId];
//       const connectedSlaves = await Insensors.find({
//         connected_to: masterSensor.hardwareId,
//         type: "slave"
//       }).lean();

//       const slaveSet = new Set(master.connected_slaves.map(s => s.hardwareId));

//       for (const slave of connectedSlaves) {
//         const slaveHardwareId = slave.tankhardwareId || slave.hardwareId;
//         if (slaveSet.has(slaveHardwareId)) continue;
//         slaveSet.add(slaveHardwareId);

//         const tankInfo = await Tank.findOne({
//           $or: [
//             { hardwareId: slaveHardwareId },
//             { tankhardwareId: slaveHardwareId }
//           ]
//         }).lean();

//         const slaveOrderInfo = slaveOrderMap[slaveHardwareId] || {};
//         const slaveEnriched = {
//           hardwareId: slaveHardwareId,
//           tankName: slave.tankName || (tankInfo?.tankName ?? ""),
//           location: slave.location || tankInfo?.tankLocation || slaveOrderInfo.location || "",
//           connected_status: slave.connected_status,
//           connected_lora_time: slave.connected_lora_time,
//           connected_lora_date: slave.connected_lora_date,
//           lora_last_check_time: slave.lora_last_check_time,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time,
//           connected_to: slave.connected_to,
//           masterName: master.masterName,
//           type: "slave",
//           typeOfWater: slave.typeOfWater || tankInfo?.typeOfWater || slaveOrderInfo.typeOfWater || "",
//           tankHeight: slave.tankHeight,
//           support_lora_last_check_time: slave.support_lora_last_check_time,
//           team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time
//         };

//         master.connected_slaves.push(slaveEnriched);
//         master.connected_slave_count++;
//       }
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       totalMasters: Object.keys(masterMap).length,
//       disconnectedIssues: Object.values(masterMap)
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected issues:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

// exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
//   try {
//     const { supportId, customerId } = req.params;

//     if (!supportId || !customerId) {
//       return reply.code(400).send({ error: "supportId and customerId are required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId and customerId" });
//     }

//     const allIssues = supportRecord.issues || [];
//     const hardwareSet = new Set();

//     for (const issue of allIssues) {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
//     }

//     const hardwareIds = [...hardwareSet];

//     const sensors = await Insensors.find({
//       customerId,
//       $or: [
//         { hardwareId: { $in: hardwareIds } },
//         { tankhardwareId: { $in: hardwareIds } }
//       ]
//     }).lean();

//     const sensorMap = {};
//     for (const sensor of sensors) {
//       if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
//       if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
//     }

//     const orders = await Order.find({ customerId }).lean();

//     const orderMap = {};
//     for (const order of orders) {
//       (order.master_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           orderMap[conn.hardwareId] = {
//             masterName: conn.master_name || null,
//             location: conn.location || null
//           };
//         }
//       });
//     }

//     const slaveOrderMap = {};
//     for (const order of orders) {
//       (order.tank_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           slaveOrderMap[conn.hardwareId] = {
//             location: conn.location || null,
//             typeOfWater: conn.typeOfWater || null
//           };
//         }
//       });
//     }

//     const masterMap = {};

//     for (const issue of allIssues) {
//       const masterId = issue.masterHardwareId || issue.hardwareId;
//       const masterSensor = sensorMap[masterId];
//       if (!masterSensor || masterSensor.type !== "master") continue;

//       if (!masterMap[masterSensor.hardwareId]) {
//         const enriched = orderMap[masterSensor.hardwareId] || {};
//         masterMap[masterSensor.hardwareId] = {
//           hardwareId: masterSensor.hardwareId,
//           masterName: enriched.masterName || masterSensor.masterName || "",
//           location: enriched.location || masterSensor.location || "",
//           type: "master",
//           connected_status: masterSensor.connected_status,
//           gsm_last_check_time: masterSensor.gsm_last_check_time,
//           gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
//           connected_gsm_date: masterSensor.connected_gsm_date,
//           connected_gsm_time: masterSensor.connected_gsm_time,
//           connected_lora_date: masterSensor.connected_lora_date,
//           connected_lora_time: masterSensor.connected_lora_time,
//           support_gsm_last_check_time: masterSensor.support_gsm_last_check_time,
//           support_lora_last_check_time: masterSensor.support_lora_last_check_time,
//           team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time,
//           team_member_support_lora_last_check_time: masterSensor.team_member_support_lora_last_check_time,
//           connected_slave_count: 0,
//           connected_slaves: []
//         };
//       }

//       const master = masterMap[masterSensor.hardwareId];
//       const connectedSlaves = await Insensors.find({
//         connected_to: masterSensor.hardwareId,
//         type: "slave",
//         customerId
//       }).lean();

//       const slaveSet = new Set(master.connected_slaves.map(s => s.hardwareId));

//       for (const slave of connectedSlaves) {
//         const slaveHardwareId = slave.tankhardwareId || slave.hardwareId;
//         if (slaveSet.has(slaveHardwareId)) continue;
//         slaveSet.add(slaveHardwareId);

//         const tankInfo = await Tank.findOne({
//           $or: [
//             { hardwareId: slaveHardwareId },
//             { tankhardwareId: slaveHardwareId }
//           ]
//         }).lean();

//         const slaveOrderInfo = slaveOrderMap[slaveHardwareId] || {};
//         const slaveEnriched = {
//           hardwareId: slaveHardwareId,
//           tankName: slave.tankName || (tankInfo?.tankName ?? ""),
//           location: slave.location || tankInfo?.tankLocation || slaveOrderInfo.location || "",
//           connected_status: slave.connected_status,
//           connected_lora_time: slave.connected_lora_time,
//           connected_lora_date: slave.connected_lora_date,
//           lora_last_check_time: slave.lora_last_check_time,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time,
//           connected_to: slave.connected_to,
//           masterName: master.masterName,
//           type: "slave",
//           typeOfWater: slave.typeOfWater || tankInfo?.typeOfWater || slaveOrderInfo.typeOfWater || "",
//           tankHeight: slave.tankHeight,
//           support_lora_last_check_time: slave.support_lora_last_check_time,
//           team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time
//         };

//         master.connected_slaves.push(slaveEnriched);
//         master.connected_slave_count++;
//       }
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       customerId,
//       totalMasters: Object.keys(masterMap).length,
//       comments: supportRecord.comments || "",  
//       disconnectedIssues: Object.values(masterMap)
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected issues:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };


// exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
//   try {
//     const { supportId, customerId } = req.params;

//     if (!supportId || !customerId) {
//       return reply.code(400).send({ error: "supportId and customerId are required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId and customerId" });
//     }

//     const allIssues = supportRecord.issues || [];
//     const hardwareSet = new Set();

//     for (const issue of allIssues) {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
//     }

//     const hardwareIds = [...hardwareSet];

//     const sensors = await Insensors.find({
//       customerId,
//       $or: [
//         { hardwareId: { $in: hardwareIds } },
//         { tankhardwareId: { $in: hardwareIds } }
//       ]
//     }).lean();

//     const sensorMap = {};
//     for (const sensor of sensors) {
//       if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
//       if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
//     }

//     const orders = await Order.find({ customerId }).lean();

//     const orderMap = {};
//     for (const order of orders) {
//       (order.master_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           orderMap[conn.hardwareId] = {
//             masterName: conn.master_name || null,
//             location: conn.location || null
//           };
//         }
//       });
//     }

//     const slaveOrderMap = {};
//     for (const order of orders) {
//       (order.tank_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           slaveOrderMap[conn.hardwareId] = {
//             location: conn.location || null,
//             typeOfWater: conn.typeOfWater || null
//           };
//         }
//       });
//     }

//     const masterMap = {};

//     for (const issue of allIssues) {
//       const masterId = issue.masterHardwareId || issue.hardwareId;
//       const masterSensor = sensorMap[masterId];
//       if (!masterSensor || masterSensor.type !== "master") continue;

//       const latestMasterData = await IotData.findOne({ hardwareId: masterSensor.hardwareId }).sort({ date: -1 }).lean();
//       const now = moment.tz("Asia/Kolkata");
//       let gsmConnected = false;

//       if (latestMasterData?.date) {
//         const gsmTime = moment.tz(latestMasterData.date, "Asia/Kolkata");
//         gsmConnected = now.diff(gsmTime, "minutes") <= 1;
//       }

//       if (!masterMap[masterSensor.hardwareId]) {
//         const enriched = orderMap[masterSensor.hardwareId] || {};
//         masterMap[masterSensor.hardwareId] = {
//           hardwareId: masterSensor.hardwareId,
//           masterName: enriched.masterName || masterSensor.masterName || "",
//           location: enriched.location || masterSensor.location || "",
//           type: "master",
//           connected_status: gsmConnected ? "connected" : "disconnected",
//           gsm_last_check_time: masterSensor.gsm_last_check_time,
//           gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
//           connected_gsm_date: masterSensor.connected_gsm_date,
//           connected_gsm_time: masterSensor.connected_gsm_time,
//           connected_lora_date: masterSensor.connected_lora_date,
//           connected_lora_time: masterSensor.connected_lora_time,
//           support_gsm_last_check_time: masterSensor.support_gsm_last_check_time,
//           support_lora_last_check_time: masterSensor.support_lora_last_check_time,
//           team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time,
//           team_member_support_lora_last_check_time: masterSensor.team_member_support_lora_last_check_time,
//           connected_slave_count: 0,
//           connected_slaves: []
//         };
//       }

//       const master = masterMap[masterSensor.hardwareId];
//       const connectedSlaves = await Insensors.find({
//         connected_to: masterSensor.hardwareId,
//         type: "slave",
//         customerId
//       }).lean();

//       const slaveSet = new Set(master.connected_slaves.map(s => s.hardwareId));

//       for (const slave of connectedSlaves) {
//         const slaveHardwareId = slave.tankhardwareId || slave.hardwareId;
//         if (slaveSet.has(slaveHardwareId)) continue;
//         slaveSet.add(slaveHardwareId);

//         const tankInfo = await Tank.findOne({
//           $or: [
//             { hardwareId: slaveHardwareId },
//             { tankhardwareId: slaveHardwareId }
//           ]
//         }).lean();

//         const slaveOrderInfo = slaveOrderMap[slaveHardwareId] || {};

//         const matchedTank = latestMasterData?.tanks?.find(t => t.tankhardwareId === slaveHardwareId);
//         let loraConnected = false;
//         if (matchedTank?.date && matchedTank.tankHeight !== "0") {
//           const loraTime = moment.tz(matchedTank.date, "Asia/Kolkata");
//           loraConnected = now.diff(loraTime, "minutes") <= 1;
//         }

//         const slaveEnriched = {
//           hardwareId: slaveHardwareId,
//           tankName: slave.tankName || tankInfo?.tankName || "",
//           location: slave.location || tankInfo?.tankLocation || slaveOrderInfo.location || "",
//           connected_status: loraConnected ? "connected" : "disconnected",
//           connected_lora_time: slave.connected_lora_time,
//           connected_lora_date: slave.connected_lora_date,
//           lora_last_check_time: slave.lora_last_check_time,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time,
//           connected_to: slave.connected_to,
//           masterName: master.masterName,
//           type: "slave",
//           typeOfWater: slave.typeOfWater || tankInfo?.typeOfWater || slaveOrderInfo.typeOfWater || "",
//           tankHeight: slave.tankHeight,
//           support_lora_last_check_time: slave.support_lora_last_check_time,
//           team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time
//         };

//         master.connected_slaves.push(slaveEnriched);
//         master.connected_slave_count++;
//       }
//     }

//     // const commentTexts = (supportRecord.comments || []).map(c => c.text);
//     // for (const master of Object.values(masterMap)) {
//     //   master.comments = commentTexts;
//     // }

//     const comments = (supportRecord.comments || []).map(c => ({
//       text: c.text,
//       commentsTime: moment(c.createdAt).tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm")
//     }));
//     for (const master of Object.values(masterMap)) {
//       master.comments = comments;
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       customerId,
//       totalMasters: Object.keys(masterMap).length,
//       disconnectedIssues: Object.values(masterMap)
//     });
//   } catch (error) {
//     console.error("Error fetching disconnected issues:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

// exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
//   try {
//     const { supportId, customerId } = req.params;

//     if (!supportId || !customerId) {
//       return reply.code(400).send({ error: "supportId and customerId are required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId and customerId" });
//     }

//     const allIssues = supportRecord.issues || [];
//     const hardwareSet = new Set();

//     for (const issue of allIssues) {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
//     }

//     const hardwareIds = [...hardwareSet];

//     const sensors = await Insensors.find({
//       customerId,
//       $or: [
//         { hardwareId: { $in: hardwareIds } },
//         { tankhardwareId: { $in: hardwareIds } }
//       ]
//     }).lean();

//     const sensorMap = {};
//     for (const sensor of sensors) {
//       if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
//       if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
//     }

//     const orders = await Order.find({ customerId }).lean();

//     const orderMap = {};
//     for (const order of orders) {
//       (order.master_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           orderMap[conn.hardwareId] = {
//             masterName: conn.master_name || null,
//             location: conn.location || null
//           };
//         }
//       });
//     }

//     const slaveOrderMap = {};
//     for (const order of orders) {
//       (order.tank_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           slaveOrderMap[conn.hardwareId] = {
//             location: conn.location || null,
//             typeOfWater: conn.typeOfWater || null
//           };
//         }
//       });
//     }

//     const masterMap = {};
//     const now = moment.tz("Asia/Kolkata");

//     for (const issue of allIssues) {
//       const masterId = issue.masterHardwareId || issue.hardwareId;
//       const masterSensor = sensorMap[masterId];
//       if (!masterSensor || masterSensor.type !== "master") continue;

//       const latestMasterData = await IotData.findOne({ hardwareId: masterSensor.hardwareId }).sort({ date: -1 }).lean();

//       let gsmConnected = false;
//       if (latestMasterData?.date) {
//         const gsmTime = moment.tz(latestMasterData.date, "Asia/Kolkata");
//         gsmConnected = now.diff(gsmTime, "minutes") <= 1;
//       }

//       if (!masterMap[masterSensor.hardwareId]) {
//         const enriched = orderMap[masterSensor.hardwareId] || {};
//         masterMap[masterSensor.hardwareId] = {
//           hardwareId: masterSensor.hardwareId,
//           masterName: enriched.masterName || masterSensor.masterName || "",
//           location: enriched.location || masterSensor.location || "",
//           type: "master",
//           connected_status: gsmConnected ? "connected" : "disconnected",
//           gsm_last_check_time: masterSensor.gsm_last_check_time,
//           gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
//           connected_gsm_date: masterSensor.connected_gsm_date,
//           connected_gsm_time: masterSensor.connected_gsm_time,
//           connected_lora_date: masterSensor.connected_lora_date,
//           connected_lora_time: masterSensor.connected_lora_time,
//           support_gsm_last_check_time: masterSensor.support_gsm_last_check_time,
//           support_lora_last_check_time: masterSensor.support_lora_last_check_time,
//           team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time,
//           team_member_support_lora_last_check_time: masterSensor.team_member_support_lora_last_check_time,
//           connected_slave_count: 0,
//           connected_slaves: []
//         };
//       }

//       const master = masterMap[masterSensor.hardwareId];
//       const connectedSlaves = await Insensors.find({
//         connected_to: masterSensor.hardwareId,
//         type: "slave",
//         customerId
//       }).lean();

//       const slaveSet = new Set(master.connected_slaves.map(s => s.hardwareId));

//       for (const slave of connectedSlaves) {
//         const slaveHardwareId = slave.tankhardwareId || slave.hardwareId;
//         if (slaveSet.has(slaveHardwareId)) continue;
//         slaveSet.add(slaveHardwareId);

//         const tankInfo = await Tank.findOne({
//           $or: [
//             { hardwareId: slaveHardwareId },
//             { tankhardwareId: slaveHardwareId }
//           ]
//         }).lean();

//         const slaveOrderInfo = slaveOrderMap[slaveHardwareId] || {};

//         const matchedTank = latestMasterData?.tanks?.find(t => t.tankhardwareId === slaveHardwareId);
//         let loraConnected = false;
//         if (matchedTank?.date && matchedTank.tankHeight !== "0") {
//           const loraTime = moment.tz(matchedTank.date, "Asia/Kolkata");
//           loraConnected = now.diff(loraTime, "minutes") <= 1;
//         }

//         const slaveEnriched = {
//           hardwareId: slaveHardwareId,
//           tankName: slave.tankName || tankInfo?.tankName || "",
//           location: slave.location || tankInfo?.tankLocation || slaveOrderInfo.location || "",
//           connected_status: loraConnected ? "connected" : "disconnected",
//           connected_lora_time: slave.connected_lora_time,
//           connected_lora_date: slave.connected_lora_date,
//           lora_last_check_time: slave.lora_last_check_time,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time,
//           connected_to: slave.connected_to,
//           masterName: master.masterName,
//           type: "slave",
//           typeOfWater: slave.typeOfWater || tankInfo?.typeOfWater || slaveOrderInfo.typeOfWater || "",
//           tankHeight: slave.tankHeight,
//           support_lora_last_check_time: slave.support_lora_last_check_time,
//           team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time
//         };

//         master.connected_slaves.push(slaveEnriched);
//         master.connected_slave_count++;
//       }
//     }

//     // 🔍 Filter comments by customerId
//     const comments = (supportRecord.comments || [])
//       .filter(c => c.customerId === customerId)
//       .map(c => ({
//         text: c.text,
//         commentsTime: moment(c.createdAt).tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm")
//       }));

//     for (const master of Object.values(masterMap)) {
//       master.comments = comments;
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       customerId,
//       totalMasters: Object.keys(masterMap).length,
//       disconnectedIssues: Object.values(masterMap)
//     });
//   } catch (error) {
//     console.error("Error fetching disconnected issues:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

exports.getDisconnectedIssuesBySupportId = async (req, reply) => {
  try {
    const { supportId, customerId } = req.params;

    if (!supportId || !customerId) {
      return reply.code(400).send({ error: "supportId and customerId are required" });
    }

    const supportRecord = await Support.findOne({ supportId }).lean();
    if (!supportRecord) {
      return reply.code(404).send({ message: "No support record found for this supportId and customerId" });
    }

    const allIssues = supportRecord.issues || [];
    const hardwareSet = new Set();

    for (const issue of allIssues) {
      if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
      if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
    }

    const hardwareIds = [...hardwareSet];

    const sensors = await Insensors.find({
      customerId,
      $or: [
        { hardwareId: { $in: hardwareIds } },
        { tankhardwareId: { $in: hardwareIds } }
      ]
    }).lean();

    const sensorMap = {};
    for (const sensor of sensors) {
      if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
      if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
    }

    const orders = await Order.find({ customerId }).lean();

    const orderMap = {};
    for (const order of orders) {
      (order.master_connections || []).forEach(conn => {
        if (conn.hardwareId) {
          orderMap[conn.hardwareId] = {
            masterName: conn.master_name || null,
            location: conn.location || null
          };
        }
      });
    }

    const slaveOrderMap = {};
    for (const order of orders) {
      (order.tank_connections || []).forEach(conn => {
        if (conn.hardwareId) {
          slaveOrderMap[conn.hardwareId] = {
            location: conn.location || null,
            typeOfWater: conn.typeOfWater || null
          };
        }
      });
    }

    const masterMap = {};
    const now = moment.tz("Asia/Kolkata");

    for (const issue of allIssues) {
      const masterId = issue.masterHardwareId || issue.hardwareId;
      const masterSensor = sensorMap[masterId];
      if (!masterSensor || masterSensor.type !== "master") continue;

      const stillUnresolved = allIssues.some(i =>
        (i.hardwareId === masterSensor.hardwareId || i.masterHardwareId === masterSensor.hardwareId) &&
        !i.resolved && !i.movedToCategory
      );
      
      if (!stillUnresolved) continue;

      const latestMasterData = await IotData.findOne({ hardwareId: masterSensor.hardwareId }).sort({ date: -1 }).lean();

      let gsmConnected = false;
      if (latestMasterData?.date) {
        const gsmTime = moment.tz(latestMasterData.date, "Asia/Kolkata");
        gsmConnected = now.diff(gsmTime, "minutes") <= 1;
      }

      // Get latest lastTicketRaisedAt for this master
      const relatedIssues = allIssues.filter(
        i =>
          i.hardwareId === masterSensor.hardwareId ||
          i.masterHardwareId === masterSensor.hardwareId
      );

      const lastTicketRaisedAt = relatedIssues.reduce((latest, issue) => {
        if (!issue.lastTicketRaisedAt) return latest;
        const current = new Date(issue.lastTicketRaisedAt);
        return !latest || current > new Date(latest) ? issue.lastTicketRaisedAt : latest;
      }, null);

      if (!masterMap[masterSensor.hardwareId]) {
        const enriched = orderMap[masterSensor.hardwareId] || {};
        masterMap[masterSensor.hardwareId] = {
          hardwareId: masterSensor.hardwareId,
          masterName: enriched.masterName || masterSensor.masterName || "",
          location: enriched.location || masterSensor.location || "",
          type: "master",
          connected_status: gsmConnected ? "connected" : "disconnected",
          gsm_last_check_time: masterSensor.gsm_last_check_time,
          gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
          connected_gsm_date: masterSensor.connected_gsm_date,
          connected_gsm_time: masterSensor.connected_gsm_time,
          connected_lora_date: masterSensor.connected_lora_date,
          connected_lora_time: masterSensor.connected_lora_time,
          support_gsm_last_check_time: masterSensor.support_gsm_last_check_time,
          support_lora_last_check_time: masterSensor.support_lora_last_check_time,
          team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time,
          team_member_support_lora_last_check_time: masterSensor.team_member_support_lora_last_check_time,
          outDoor_status: masterSensor.outDoor_status || "inprogress",
          connected_slave_count: 0,
          connected_slaves: [],
          lastTicketRaisedAt: lastTicketRaisedAt
        };
      }

      const master = masterMap[masterSensor.hardwareId];
      const connectedSlaves = await Insensors.find({
        connected_to: masterSensor.hardwareId,
        type: "slave",
        customerId
      }).lean();

      const slaveSet = new Set(master.connected_slaves.map(s => s.hardwareId));

      for (const slave of connectedSlaves) {
        const slaveHardwareId = slave.tankhardwareId || slave.hardwareId;
        if (slaveSet.has(slaveHardwareId)) continue;
        slaveSet.add(slaveHardwareId);

        const tankInfo = await Tank.findOne({
          $or: [
            { hardwareId: slaveHardwareId },
            { tankhardwareId: slaveHardwareId }
          ]
        }).lean();

        const slaveOrderInfo = slaveOrderMap[slaveHardwareId] || {};

        const matchedTank = latestMasterData?.tanks?.find(t => t.tankhardwareId === slaveHardwareId);
        let loraConnected = false;
        if (matchedTank?.date && matchedTank.tankHeight !== "0") {
          const loraTime = moment.tz(matchedTank.date, "Asia/Kolkata");
          loraConnected = now.diff(loraTime, "minutes") <= 1;
        }

        // Get latest lastTicketRaisedAt for this slave
        const slaveRelatedIssues = allIssues.filter(
          i => i.hardwareId === slaveHardwareId
        );

        const slaveLastTicketRaisedAt = slaveRelatedIssues.reduce((latest, issue) => {
          if (!issue.lastTicketRaisedAt) return latest;
          const current = new Date(issue.lastTicketRaisedAt);
          return !latest || current > new Date(latest) ? issue.lastTicketRaisedAt : latest;
        }, null);

        const slaveEnriched = {
          hardwareId: slaveHardwareId,
          tankName: slave.tankName || tankInfo?.tankName || "",
          location: slave.location || tankInfo?.tankLocation || slaveOrderInfo.location || "",
          connected_status: loraConnected ? "connected" : "disconnected",
          connected_lora_time: slave.connected_lora_time,
          connected_lora_date: slave.connected_lora_date,
          lora_last_check_time: slave.lora_last_check_time,
          lora_last_disconnect_time: slave.lora_last_disconnect_time,
          connected_to: slave.connected_to,
          masterName: master.masterName,
          type: "slave",
          typeOfWater: slave.typeOfWater || tankInfo?.typeOfWater || slaveOrderInfo.typeOfWater || "",
          tankHeight: slave.tankHeight,
          support_lora_last_check_time: slave.support_lora_last_check_time,
          team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time,
          lastTicketRaisedAt: slaveLastTicketRaisedAt,
          outDoor_status: slave.outDoor_status || "inprogress",

        };

        master.connected_slaves.push(slaveEnriched);
        master.connected_slave_count++;
      }
    }

    // Filter comments by customerId
    const comments = (supportRecord.comments || [])
      .filter(c => c.customerId === customerId)
      .map(c => ({
        text: c.text,
        commentsTime: moment(c.createdAt).tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm")
      }));

    for (const master of Object.values(masterMap)) {
      master.comments = comments;
    }

    return reply.send({
      status_code: 200,
      supportId,
      customerId,
      totalMasters: Object.keys(masterMap).length,
      disconnectedIssues: Object.values(masterMap)
    });
  } catch (error) {
    console.error("Error fetching disconnected issues:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};


exports.getResolvedIssuesBySupportId = async (req, reply) => {
  try {
    const { supportId, customerId } = req.params;

    if (!supportId || !customerId) {
      return reply.code(400).send({ error: "supportId and customerId are required" });
    }

    const supportRecord = await Support.findOne({ supportId }).lean();
    if (!supportRecord) {
      return reply.code(404).send({ message: "No support record found" });
    }

    const resolvedIssues = (supportRecord.resolvedIssues || []).filter(issue => issue.currentlyResolved !== false);
    const hardwareSet = new Set();

    for (const issue of resolvedIssues) {
      if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
      if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
    }

    const hardwareIds = [...hardwareSet];

    const sensors = await Insensors.find({
      customerId,
      $or: [
        { hardwareId: { $in: hardwareIds } },
        { tankhardwareId: { $in: hardwareIds } }
      ]
    }).lean();

    const sensorMap = {};
    for (const sensor of sensors) {
      if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
      if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
    }

    const orders = await Order.find({ customerId }).lean();

    const orderMap = {};
    for (const order of orders) {
      (order.master_connections || []).forEach(conn => {
        if (conn.hardwareId) {
          orderMap[conn.hardwareId] = {
            masterName: conn.master_name || null,
            location: conn.location || null
          };
        }
      });
    }

    const slaveOrderMap = {};
    for (const order of orders) {
      (order.tank_connections || []).forEach(conn => {
        if (conn.hardwareId) {
          slaveOrderMap[conn.hardwareId] = {
            location: conn.location || null,
            typeOfWater: conn.typeOfWater || null
          };
        }
      });
    }

    const masterMap = {};

    for (const issue of resolvedIssues) {
      const masterId = issue.masterHardwareId || issue.hardwareId;
      const masterSensor = sensorMap[masterId];
      if (!masterSensor || masterSensor.type !== "master") continue;

      const enriched = orderMap[masterId] || {};

      const masterEntry = {
        hardwareId: masterSensor.hardwareId,
        masterName: enriched.masterName || masterSensor.masterName || "",
        location: enriched.location || masterSensor.location || "",
        type: "master",
        connected_status: "connected",
        connected_gsm_date: masterSensor.connected_gsm_date,
        connected_gsm_time: masterSensor.connected_gsm_time,
        connected_lora_date: masterSensor.connected_lora_date,
        connected_lora_time: masterSensor.connected_lora_time,
        gsm_last_check_time: masterSensor.gsm_last_check_time,
        gsm_last_disconnect_time: masterSensor.gsm_last_disconnect_time,
        support_gsm_last_check_time: masterSensor.support_gsm_last_check_time,
        support_lora_last_check_time: masterSensor.support_lora_last_check_time,
        team_member_support_gsm_last_check_time: masterSensor.team_member_support_gsm_last_check_time,
        team_member_support_lora_last_check_time: masterSensor.team_member_support_lora_last_check_time,
        connected_slave_count: 0,
        connected_slaves: [],
        resolvedAt: issue.resolvedAt,
        originalMovedAt: issue.originalMovedAt,
        reason: issue.reason
      };

      const connectedSlaves = await Insensors.find({
        connected_to: masterId,
        type: "slave",
        customerId
      }).lean();

      for (const slave of connectedSlaves) {
        const slaveHardwareId = slave.tankhardwareId || slave.hardwareId;

        const tankInfo = await Tank.findOne({
          $or: [{ hardwareId: slaveHardwareId }, { tankhardwareId: slaveHardwareId }]
        }).lean();

        const slaveOrderInfo = slaveOrderMap[slaveHardwareId] || {};

        const slaveEnriched = {
          hardwareId: slaveHardwareId,
          tankName: slave.tankName || tankInfo?.tankName || "",
          location: slave.location || tankInfo?.tankLocation || slaveOrderInfo.location || "",
          connected_status: "connected",
          connected_lora_time: slave.connected_lora_time,
          connected_lora_date: slave.connected_lora_date,
          lora_last_check_time: slave.lora_last_check_time,
          lora_last_disconnect_time: slave.lora_last_disconnect_time,
          connected_to: slave.connected_to,
          masterName: masterEntry.masterName,
          type: "slave",
          typeOfWater: slave.typeOfWater || tankInfo?.typeOfWater || slaveOrderInfo.typeOfWater || "",
          tankHeight: slave.tankHeight,
          support_lora_last_check_time: slave.support_lora_last_check_time,
          team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time
        };

        masterEntry.connected_slaves.push(slaveEnriched);
        masterEntry.connected_slave_count++;
      }

      masterMap[masterSensor.hardwareId] = masterEntry;
    }

    // Format and attach comments
    const comments = (supportRecord.comments || []).map(c => ({
      text: c.text,
      commentsTime: moment(c.createdAt).tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm")
    }));

    for (const master of Object.values(masterMap)) {
      master.comments = comments;
    }

    return reply.send({
      status_code: 200,
      supportId,
      customerId,
      totalResolved: Object.keys(masterMap).length,
      resolvedIssues: Object.values(masterMap)
    });
  } catch (err) {
    console.error("Error in getResolvedIssuesBySupportId:", err);
    return reply.code(500).send({ error: "Internal Server Error" });
  }
};


// exports.getRemoveConnectedMastersWithSlaves = async (req, reply) => {
//   try {
//     const { supportId } = req.params;
//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     const allIssues = supportRecord.issues || [];

//     // Gather all unique hardwareIds from issues
//     const hardwareSet = new Set();
//     allIssues.forEach(issue => {
//       if (issue.hardwareId) hardwareSet.add(issue.hardwareId);
//       if (issue.masterHardwareId) hardwareSet.add(issue.masterHardwareId);
//       if (issue.hardwareIds && Array.isArray(issue.hardwareIds)) {
//         issue.hardwareIds.forEach(id => hardwareSet.add(id));
//       }
//     });
//     const hardwareIds = [...hardwareSet];

//     // Fetch all sensors related to these hardwareIds
//     const sensors = await Insensors.find({
//       $or: [
//         { hardwareId: { $in: hardwareIds } },
//         { tankhardwareId: { $in: hardwareIds } }
//       ]
//     }).lean();

//     // Map sensors by hardwareId and tankhardwareId
//     const sensorMap = {};
//     sensors.forEach(sensor => {
//       if (sensor.hardwareId) sensorMap[sensor.hardwareId] = sensor;
//       if (sensor.tankhardwareId) sensorMap[sensor.tankhardwareId] = sensor;
//     });

//     // Determine customerId from support or sensors
//     let customerId = supportRecord.customerId;
//     if (!customerId) {
//       const firstSensor = sensors.find(sensor => sensor.customerId);
//       if (firstSensor) {
//         customerId = firstSensor.customerId;
//       } else {
//         return reply.code(404).send({ message: "Unable to determine customerId" });
//       }
//     }

//     // Fetch orders for enriching master/slave info
//     const orders = await Order.find({ customerId }).lean();

//     const orderMap = {};
//     orders.forEach(order => {
//       (order.master_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           orderMap[conn.hardwareId] = {
//             masterName: conn.master_name || null,
//             location: conn.location || null
//           };
//         }
//       });
//     });

//     const slaveOrderMap = {};
//     orders.forEach(order => {
//       (order.tank_connections || []).forEach(conn => {
//         if (conn.hardwareId) {
//           slaveOrderMap[conn.hardwareId] = {
//             location: conn.location || null,
//             typeOfWater: conn.typeOfWater || null
//           };
//         }
//       });
//     });

//     const connectedMasters = [];
//     const updatedIssues = [];

//     // Process each issue to check connection status
//     for (const issue of allIssues) {
//       const masterId = issue.masterHardwareId || issue.hardwareId;
//       const masterSensor = sensorMap[masterId];
//       if (!masterSensor || masterSensor.type !== "master") {
//         // If no master sensor found or not a master, keep the issue as is
//         updatedIssues.push(issue);
//         continue;
//       }

//       // Get connected slaves of this master
//       const connectedSlaves = await Insensors.find({
//         connected_to: masterSensor.hardwareId,
//         type: "slave"
//       }).lean();

//       // Check if master is connected
//       const isMasterConnected = masterSensor.connected_status === "connected";

//       // Check if all slaves are connected
//       const allSlavesConnected = connectedSlaves.every(slave => slave.connected_status === "connected");

//       if (isMasterConnected && allSlavesConnected) {
//         // All connected - prepare connected master object
//         const enrichedMaster = {
//           hardwareId: masterSensor.hardwareId,
//           masterName: orderMap[masterSensor.hardwareId]?.masterName || masterSensor.masterName || "",
//           location: orderMap[masterSensor.hardwareId]?.location || masterSensor.location || "",
//           type: "master",
//           connected_status: masterSensor.connected_status,
//           connected_slave_count: connectedSlaves.length,
//           connected_slaves: connectedSlaves.map(slave => ({
//             hardwareId: slave.tankhardwareId || slave.hardwareId,
//             tankName: slave.tankName || "",
//             location: slave.location || slaveOrderMap[slave.tankhardwareId || slave.hardwareId]?.location || "",
//             connected_status: slave.connected_status,
//             type: "slave",
//             typeOfWater: slave.typeOfWater || slaveOrderMap[slave.tankhardwareId || slave.hardwareId]?.typeOfWater || "",
//             connected_to: slave.connected_to
//           }))
//         };

//         connectedMasters.push(enrichedMaster);
//         // Do NOT add this issue to updatedIssues (removing it from issues)
//       } else {
//         // Not all connected, keep the issue in support issues
//         updatedIssues.push(issue);
//       }
//     }

//     // Update the Support document issues with filtered updatedIssues
//     await Support.updateOne({ supportId }, { $set: { issues: updatedIssues } });

//     return reply.send({
//       status_code: 200,
//       supportId,
//       totalConnectedMasters: connectedMasters.length,
//       connectedMasters
//     });

//   } catch (error) {
//     console.error("Error in getConnectedMastersWithSlaves:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

exports.getRemoveConnectedMastersWithSlaves = async (req, reply) => {
  try {
    const { supportId, hardwareId } = req.params;

    if (!supportId || !hardwareId) {
      return reply.code(400).send({ error: "supportId and hardwareId are required" });
    }

    // Find the support record
    const supportRecord = await Support.findOne({ supportId }).lean();
    if (!supportRecord) {
      return reply.code(404).send({ message: "No support record found for this supportId" });
    }

    const originalIssues = supportRecord.issues || [];

    // Filter out issues where hardwareId matches hardwareId or masterHardwareId
    const filteredIssues = originalIssues.filter(issue => {
      return !(
        issue.hardwareId === hardwareId ||
        issue.masterHardwareId === hardwareId
      );
    });

    // Update the support record
    await Support.updateOne(
      { supportId },
      { $set: { issues: filteredIssues } }
    );

    return reply.send({
      status_code: 200,
      message: `Issue(s) with hardwareId "${hardwareId}" removed successfully.`,
      remainingIssues: filteredIssues
    });

  } catch (error) {
    console.error("Error in removeIssueByHardwareId:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};

// exports.getDisconnectedCustomerDetails = async (req, reply) => {
//   try {
//     const { supportId } = req.params;

//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     const unresolvedIssues = (supportRecord.issues || []).filter(
//       issue => issue.resolved === false && issue.movedToCategory !== true
//     );

//     const allHardwareIds = new Set();
//     for (const issue of unresolvedIssues) {
//       if (issue.hardwareId) allHardwareIds.add(issue.hardwareId.trim().toLowerCase());
//       if (Array.isArray(issue.hardwareIds)) {
//         issue.hardwareIds.forEach(id => {
//           if (typeof id === "string") allHardwareIds.add(id.trim().toLowerCase());
//         });
//       }
//     }

//     if (allHardwareIds.size === 0) {
//       return reply.code(404).send({ message: "No unresolved hardware IDs found in issues" });
//     }

//     const hardwareIdsArray = Array.from(allHardwareIds);

//     const disconnectedSensors = await Insensors.find({
//       connected_status: "disconnected",
//       $or: [
//         { connected_to: { $in: hardwareIdsArray } },
//         { hardwareId: { $in: hardwareIdsArray } }
//       ]
//     }).lean();

//     if (!disconnectedSensors.length) {
//       return reply.code(404).send({ message: "No disconnected issues found" });
//     }

//     const customerIds = [...new Set(disconnectedSensors.map(s => s.customerId))];
//     const customers = await User.find({ customerId: { $in: customerIds } }).lean();

//     const customerHardwareMap = {};
//     for (const sensor of disconnectedSensors) {
//       const custId = sensor.customerId;
//       if (!customerHardwareMap[custId]) {
//         customerHardwareMap[custId] = new Set();
//       }

//       const sensorHw = sensor.tankhardwareId?.trim().toLowerCase();
//       const sensorConnected = sensor.connected_to?.trim().toLowerCase();

//       for (const issue of unresolvedIssues) {
//         const allIssueHardwareIds = [
//           ...(issue.hardwareIds?.map(id => id?.trim().toLowerCase()) || []),
//           issue.hardwareId?.trim().toLowerCase()
//         ];

//         if (
//           allIssueHardwareIds.includes(sensorHw) ||
//           allIssueHardwareIds.includes(sensorConnected)
//         ) {
//           customerHardwareMap[custId].add(issue.hardwareId);
//         }
//       }
//     }

//     const response = [];
//     for (const user of customers) {
//       const custId = user.customerId;
//       const hardwareIdSet = customerHardwareMap[custId] || new Set();

//       const relatedIssues = unresolvedIssues.filter(issue => {
//         const issueHw = issue.hardwareId?.trim().toLowerCase();
//         const hardwareIds = issue.hardwareIds?.map(id => id?.trim().toLowerCase()) || [];
//         const allIds = [issueHw, ...hardwareIds];
//         return Array.from(hardwareIdSet).some(hw => allIds.includes(hw?.trim().toLowerCase()));
//       });

//       let latestIssueTime = null;
//       for (const issue of relatedIssues) {
//         if (issue.lastTicketRaisedAt) {
//           const issueTime = new Date(issue.lastTicketRaisedAt);
//           if (!latestIssueTime || issueTime > latestIssueTime) {
//             latestIssueTime = issueTime;
//           }
//         }
//       }

//       response.push({
//         customer: {
//           customerId: custId,
//           username: user.username || "",
//           firstName: user.profile?.firstName || "",
//           lastName: user.profile?.lastName || "",
//           phone: user.phone || user.profile?.contactNumber || "",
//           email: user.emails?.[0]?.email || "",
//           phoneVerified: user.phoneVerified || false,
//           address1: user.profile?.address1 || "",
//           address2: user.profile?.address2 || "",
//           city: user.profile?.city || "",
//           state: user.profile?.state || "",
//           country: user.profile?.country || "",
//           zip: user.profile?.zip || "",
//           notes: user.profile?.notes || "",
//           latitude: user.latitude,
//           longitude: user.longitude,
//           fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")),
//           installationId: user.installationId || "",
//           notificationPreferences: {
//             allowNotifications: user.allowNotifications || false,
//             automaticStartAndStopNotify: user.automaticStartAndStopNotify || false,
//             manualStartAndStopNotify: user.manualStartAndStopNotify || false,
//             criticalLowWaterAlert: user.criticalLowWaterAlert || false,
//             lowWaterAlert: user.lowWaterAlert || false,
//             notificationPreference: user.notificationPreference || "never"
//           },
//           surveyStatus: user.survey_status || "pending",
//           buildingName: user.buildingName,
//           stripePaymentStatus: user.stripePaymentStatus || false,
//           stripeSubscriptionStatus: user.stripeSubscriptionStatus || false,
//           createdAt: user.createdAt,
//           updatedAt: user.updatedAt,
//           lastTicketRaisedAt: latestIssueTime ? moment(latestIssueTime).format("YYYY-MM-DD HH:mm:ss") : null,
//           totalHardwareIdsCount: hardwareIdSet.size
//         }
//       });
//     }

//     return reply.send({
//       status_code: 200,
//       data: response
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected customer details:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };




// exports.getDisconnectedCustomerDetails = async (req, reply) => {
//   try {
//     const { supportId } = req.params;

//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     // 1. Get the support record by supportId
//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     // 2. Extract all hardwareIds from issues
//     const hardwareIds = [];
//     for (const issue of supportRecord.issues) {
//       if (issue.hardwareId) hardwareIds.push(issue.hardwareId);
//       if (Array.isArray(issue.hardwareIds)) hardwareIds.push(...issue.hardwareIds);
//     }

//     if (hardwareIds.length === 0) {
//       return reply.code(404).send({ message: "No hardware IDs found in issues" });
//     }

//     // 3. Find disconnected Insensors
//     const disconnectedSensors = await Insensors.find({
//       $or: [
//        // { hardwareId: { $in: hardwareIds } },
//         { connected_to: { $in: hardwareIds } }
//       ],
//       connected_status: "disconnected"
//     }).lean();

//     if (disconnectedSensors.length === 0) {
//       return reply.code(404).send({ message: "No disconnected issues found" });
//     }

//     // 4. Get all unique customerIds
//     const customerIds = [...new Set(disconnectedSensors.map(s => s.customerId))];
//     const customers = await User.find({ customerId: { $in: customerIds } }).lean();

//     // 5. Map unique customers
//     const uniqueCustomerMap = {};
//     for (const user of customers) {
//       if (!uniqueCustomerMap[user.customerId]) {
//         uniqueCustomerMap[user.customerId] = {
//           customer: {
//             customerId: user.customerId,
//             username: user.username || "",
//             firstName: user.profile?.firstName || "",
//             lastName: user.profile?.lastName || "",
//             phone: user.phone || user.profile?.contactNumber || "",
//             email: user.emails?.[0]?.email || "",
//             phoneVerified: user.phoneVerified || false,
//             address1: user.profile?.address1 || "",
//             address2: user.profile?.address2 || "",
//             city: user.profile?.city || "",
//             state: user.profile?.state || "",
//             country: user.profile?.country || "",
//             zip: user.profile?.zip || "",
//             notes: user.profile?.notes || "",
//             latitude: user.latitude,
//             longitude: user.longitude,
//             fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")),
//             installationId: user.installationId || "",
//             notificationPreferences: {
//               allowNotifications: user.allowNotifications || false,
//               automaticStartAndStopNotify: user.automaticStartAndStopNotify || false,
//               manualStartAndStopNotify: user.manualStartAndStopNotify || false,
//               criticalLowWaterAlert: user.criticalLowWaterAlert || false,
//               lowWaterAlert: user.lowWaterAlert || false,
//               notificationPreference: user.notificationPreference || "never"
//             },
//             surveyStatus: user.survey_status || "pending",
//             buildingName: user.buildingName,
//             stripePaymentStatus: user.stripePaymentStatus || false,
//             stripeSubscriptionStatus: user.stripeSubscriptionStatus || false,
//             createdAt: user.createdAt,
//             updatedAt: user.updatedAt
//           }
//         };
//       }
//     }

//     const response = Object.values(uniqueCustomerMap);

//     return reply.send({
//       status_code: 200,
//       data: response
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected customer details:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };


exports.getDisconnectedCustomerDetails = async (req, reply) => {
  try {
    const { supportId } = req.params;

    if (!supportId) {
      return reply.code(400).send({ error: "supportId is required" });
    }

    const supportRecord = await Support.findOne({ supportId }).lean();
    if (!supportRecord) {
      return reply.code(404).send({ message: "No support record found for this supportId" });
    }

    const unresolvedIssues = supportRecord.issues?.filter(
      (issue) => issue.resolved === false && issue.movedToCategory === false
    ) || [];

    const existingCategorizedHardwareIds = new Set();
    (supportRecord.categorizedIssues || []).forEach(issue => {
      if (issue.hardwareId) existingCategorizedHardwareIds.add(issue.hardwareId.trim().toLowerCase());
      if (Array.isArray(issue.hardwareIds)) {
        issue.hardwareIds.forEach(id => {
          if (typeof id === "string") existingCategorizedHardwareIds.add(id.trim().toLowerCase());
        });
      }
    });

    const hardwareIdsArray = new Set();
    unresolvedIssues.forEach((issue) => {
      if (issue.hardwareId) hardwareIdsArray.add(issue.hardwareId.trim());
      if (Array.isArray(issue.hardwareIds)) {
        issue.hardwareIds.forEach((id) => {
          if (typeof id === "string") hardwareIdsArray.add(id.trim());
        });
      }
    });

    const allHardwareIds = [...hardwareIdsArray];

    // const disconnectedSensorsRaw = await Insensors.find({
    //   connected_status: "disconnected",
    //   $or: [
    //     { connected_to: { $in: allHardwareIds } },
    //     { hardwareId: { $in: allHardwareIds } },
    //     { tankhardwareId: { $in: allHardwareIds } }
    //   ]
    // }).lean();

    const disconnectedSensorsRaw = await Insensors.find({
      $or: [
        { connected_to: { $in: allHardwareIds } },
        { hardwareId: { $in: allHardwareIds } },
        { tankhardwareId: { $in: allHardwareIds } }
      ]
    }).lean();
    
    const disconnectedSensors = disconnectedSensorsRaw.filter(sensor => {
      const ids = [
        sensor.hardwareId?.trim().toLowerCase(),
        sensor.connected_to?.trim().toLowerCase(),
        sensor.tankhardwareId?.trim().toLowerCase()
      ];
      return !ids.some(id => existingCategorizedHardwareIds.has(id));
    });

    const customerHardwareMap = {};
    for (const sensor of disconnectedSensors) {
      const custId = sensor.customerId;
      if (!customerHardwareMap[custId]) {
        customerHardwareMap[custId] = new Set();
      }

      const sensorHw = sensor.tankhardwareId?.trim().toLowerCase();
      const sensorConnected = sensor.connected_to?.trim().toLowerCase();
      const sensorHardwareId = sensor.hardwareId?.trim().toLowerCase();

      for (const issue of unresolvedIssues) {
        const allIssueHardwareIds = [
          ...(issue.hardwareIds?.map(id => id?.trim().toLowerCase()) || []),
          issue.hardwareId?.trim().toLowerCase()
        ];

        const isCategorizedMatch = [sensorHw, sensorConnected, sensorHardwareId].some(id =>
          id && existingCategorizedHardwareIds.has(id)
        );
        if (isCategorizedMatch) continue;

        if (
          (sensorHw && allIssueHardwareIds.includes(sensorHw)) ||
          (sensorConnected && allIssueHardwareIds.includes(sensorConnected)) ||
          (sensorHardwareId && allIssueHardwareIds.includes(sensorHardwareId))
        ) {
          for (const hw of allIssueHardwareIds) {
            if (hw && !existingCategorizedHardwareIds.has(hw)) {
              customerHardwareMap[custId].add(hw);
            }
          }
        }
      }
    }

    const customerDetails = await User.find({
      customerId: { $in: Object.keys(customerHardwareMap) }
    }).lean();

    const customerResults = customerDetails.map((customer) => {
      const customerId = customer.customerId;
      const affectedHardwareSet = customerHardwareMap[customerId] || new Set();
      const affectedLowerSet = new Set([...affectedHardwareSet].map(id => id.toLowerCase().trim()));

      const disconnectedSensorsForCustomer = disconnectedSensors.filter(
        s => s.customerId === customerId && s.connected_status === "disconnected"
      );

      const disconnectedSlaves = disconnectedSensorsForCustomer.filter(s => s.type === 'slave');
      const disconnectedMasters = disconnectedSensorsForCustomer.filter(s => s.type === 'master');
      console.log("disconnectedMasters",disconnectedMasters)
      const uniqueDisconnectedHardwareIds = new Set([
        ...disconnectedMasters.map(s => s.hardwareId?.trim()),
        ...disconnectedSlaves.map(s => s.tankhardwareId?.trim() || s.hardwareId?.trim())
      ].filter(Boolean));

      const disconnectedCount = disconnectedMasters.length + disconnectedSlaves.length;

      const customerIssues = unresolvedIssues.filter(issue => {
        const allIssueHardwareIds = [
          ...(issue.hardwareIds?.map(id => id?.trim().toLowerCase()) || []),
          issue.hardwareId?.trim().toLowerCase()
        ].filter(Boolean);
        return allIssueHardwareIds.some(hw => affectedLowerSet.has(hw));
      });

      const lastTicketRaisedAt = customerIssues.reduce((latest, issue) => {
        const issueTime = new Date(issue.lastTicketRaisedAt);
        if (!isNaN(issueTime)) {
          return (!latest || issueTime > new Date(latest)) ? issue.lastTicketRaisedAt : latest;
        }
        return latest;
      }, null);

      return {
        customerId: customer.customerId,
        buildingName: customer.buildingName || "",
        location: customer.location || "",
        username: customer.username || "",
        firstName: customer.profile?.firstName || "",
        lastName: customer.profile?.lastName || "",
        phone: customer.phone || customer.profile?.contactNumber || "",
        email: customer.emails?.[0]?.email || "",
        phoneVerified: customer.phoneVerified || false,
        address1: customer.profile?.address1 || "",
        address2: customer.profile?.address2 || "",
        city: customer.profile?.city || "",
        latitude: customer.latitude,
        longitude: customer.longitude,
        totalHardwareIdsCount: uniqueDisconnectedHardwareIds.size,
        hardwareIds: [...uniqueDisconnectedHardwareIds],
        lastTicketRaisedAt: lastTicketRaisedAt || null,
        disconnectedCount
      };
    });

    return reply.code(200).send({
      success: true,
      totalCustomers: customerResults.length,
      customers: customerResults
    });

  } catch (error) {
    console.error("Error in getDisconnectedCustomerDetails:", error);
    return reply.code(500).send({
      success: false,
      message: "Internal Server Error"
    });
  }
};






exports.getDisconnectedCustomerDetailsByTeamMemberId = async (req, reply) => {
  try {
    const { support_teamMemberId } = req.params;

    if (!support_teamMemberId) {
      return reply.code(400).send({ error: "support_teamMemberId is required" });
    }

    // Step 1: Get support record with categorized issues assigned to the team member
    const supportRecord = await Support.findOne({
      "team_member.team_member.support_teamMemberId": support_teamMemberId
    }).lean();

    if (!supportRecord) {
      return reply.code(404).send({ message: "Support record not found" });
    }

    // Step 2: Filter categorized issues assigned to this team member
    const assignedIssues = (supportRecord.categorizedIssues || []).filter(
      issue => issue.assignedTo?.support_teamMemberId === support_teamMemberId
    );

    // Step 3: Extract unique hardwareIds from assigned issues
    const assignedHardwareIds = [
      ...new Set(
        assignedIssues.map(issue => issue.hardwareId || issue.masterHardwareId).filter(Boolean)
      )
    ];

    if (assignedHardwareIds.length === 0) {
      return reply.code(404).send({ message: "No categorized issues assigned to this team member" });
    }

    // Step 4: Find disconnected insensors (either masters or slaves)
    const disconnectedDevices = await Insensors.find({
      $or: [
        { hardwareId: { $in: assignedHardwareIds } },
        { connected_to: { $in: assignedHardwareIds } }
      ],
      connected_status: "disconnected"
    }).lean();

    if (disconnectedDevices.length === 0) {
      return reply.code(404).send({ message: "No disconnected devices assigned to this team member" });
    }

    // Step 5: Extract unique customerIds
    const customerIds = [...new Set(disconnectedDevices.map(d => d.customerId))];

    const users = await User.find({ customerId: { $in: customerIds } }).lean();
    console.log("users",users)

    // Step 6: Prepare final response
    const response = users.map(user => ({
      customerId: user.customerId,
      firstName: user.profile?.firstName || "",
      lastName: user.profile?.lastName || "",
      address1: user.profile?.address1 || "",
      address2: user.profile?.address2 || "",

      phone: user.phone || user.profile?.contactNumber || "",
      email: user.emails?.[0]?.email || "",
      
      latitude: user.latitude,
      longitude: user.longitude,
      fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string"),
      installationId: user.installationId || "",
      username: user.username || "",
      buildingName: user.buildingName || "",
      notificationPreferences: {
        allowNotifications: user.allowNotifications || false,
        automaticStartAndStopNotify: user.automaticStartAndStopNotify || false,
        manualStartAndStopNotify: user.manualStartAndStopNotify || false,
        criticalLowWaterAlert: user.criticalLowWaterAlert || false,
        lowWaterAlert: user.lowWaterAlert || false,
        notificationPreference: user.notificationPreference || "never"
      },
      createdAt: user.createdAt,
      updatedAt: user.updatedAt
    }));

    return reply.send({ status_code: 200, data: response });

  } catch (error) {
    console.error("Error in getDisconnectedCustomerDetailsByTeamMemberId:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};


// exports.getDisconnectedMoveCustomerDetails = async (req, reply) => {
//   try {
//     const { supportId } = req.params;

//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     // 1. Fetch support record
//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     // 2. Only proceed if categorizedIssues exist
//     if (!Array.isArray(supportRecord.categorizedIssues) || supportRecord.categorizedIssues.length === 0) {
//       return reply.code(404).send({ message: "No categorized issues to process" });
//     }

//     // 3. Collect hardware IDs from categorized issues
//     const categorizedHardwareIds = [];
//     for (const issue of supportRecord.categorizedIssues) {
//       if (issue.hardwareId) categorizedHardwareIds.push(issue.hardwareId);
//       if (Array.isArray(issue.hardwareIds)) categorizedHardwareIds.push(...issue.hardwareIds);
//     }

//     if (categorizedHardwareIds.length === 0) {
//       return reply.code(404).send({ message: "No hardware IDs in categorized issues" });
//     }

//     // 4. Get disconnected sensors from Insensors
//     const disconnectedSensors = await Insensors.find({
//       $or: [
//         { hardwareId: { $in: categorizedHardwareIds } },
//         { connected_to: { $in: categorizedHardwareIds } }
//       ],
//       connected_status: "disconnected"
//     }).lean();

//     if (disconnectedSensors.length === 0) {
//       return reply.code(404).send({ message: "No disconnected sensors found" });
//     }

//     // 5. Get unique customerIds
//     const customerIds = [...new Set(disconnectedSensors.map(s => s.customerId))];

//     // 6. Fetch corresponding customers
//     const customers = await User.find({ customerId: { $in: customerIds } }).lean();

//     const uniqueCustomerMap = {};

//     for (const user of customers) {
//       const cid = user.customerId;
//       if (!uniqueCustomerMap[cid]) {
//         uniqueCustomerMap[cid] = {
//           customer: {
//             customerId: cid,
//             username: user.username || "",
//             firstName: user.profile?.firstName || user.firstName || "",
//             lastName: user.profile?.lastName || user.lastName || "",
//             phone: user.phone || user.profile?.contactNumber || user.alternativeNumber || "",
//             email: user.emails?.[0]?.email || user.email || "",
//             phoneVerified: user.phoneVerified || false,
//             address1: user.profile?.address1 || user.address1 || "",
//             address2: user.profile?.address2 || user.address2 || "",
//             city: user.profile?.city || user.city || "",
//             state: user.profile?.state || user.state || "",
//             country: user.profile?.country || user.country || "",
//             zip: user.profile?.zip || "",
//             notes: user.profile?.notes || "",
//             latitude: user.latitude || 0,
//             longitude: user.longitude || 0,
//             fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")),
//             installationId: user.installationId || "",
//             notificationPreferences: {
//               allowNotifications: user.allowNotifications || false,
//               automaticStartAndStopNotify: user.automaticStartAndStopNotify || false,
//               manualStartAndStopNotify: user.manualStartAndStopNotify || false,
//               criticalLowWaterAlert: user.criticalLowWaterAlert || false,
//               lowWaterAlert: user.lowWaterAlert || false,
//               notificationPreference: user.notificationPreference || "never"
//             },
//             surveyStatus: user.survey_status || "pending",
//             buildingName: user.buildingName || "",
//             stripePaymentStatus: user.stripePaymentStatus || false,
//             stripeSubscriptionStatus: user.stripeSubscriptionStatus || false,
//             createdAt: user.createdAt,
//             updatedAt: user.updatedAt
//           }
//         };
//       }
//     }

//     const response = Object.values(uniqueCustomerMap);

//     return reply.send({
//       status_code: 200,
//       data: response
//     });

//   } catch (error) {
//     console.error("Error fetching disconnected customer details:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

// exports.getDisconnectedMoveCustomerDetails = async (req, reply) => {
//   try {
//     const { supportId } = req.params;

//     if (!supportId) {
//       return reply.code(400).send({ error: "supportId is required" });
//     }

//     const supportRecord = await Support.findOne({ supportId }).lean();
//     if (!supportRecord) {
//       return reply.code(404).send({ message: "No support record found for this supportId" });
//     }

//     const categorizedHardwareIds = [];
//     const resolvedHardwareIds = [];

//     for (const issue of supportRecord.categorizedIssues || []) {
//       if (issue.hardwareId) categorizedHardwareIds.push(issue.hardwareId);
//       if (Array.isArray(issue.hardwareIds)) categorizedHardwareIds.push(...issue.hardwareIds);
//     }

//     for (const issue of supportRecord.resolvedIssues || []) {
//       if (issue.hardwareId) resolvedHardwareIds.push(issue.hardwareId);
//       if (Array.isArray(issue.hardwareIds)) resolvedHardwareIds.push(...issue.hardwareIds);
//     }

//     const allHardwareIds = [...new Set([...categorizedHardwareIds, ...resolvedHardwareIds])];
//     if (allHardwareIds.length === 0) {
//       return reply.code(404).send({ message: "No hardware IDs in support issues" });
//     }

//     const allSensors = await Insensors.find({
//       $or: [
//         { hardwareId: { $in: allHardwareIds } },
//         { connected_to: { $in: allHardwareIds } }
//       ]
//     }).lean();

//     if (allSensors.length === 0) {
//       return reply.code(404).send({ message: "No sensors found for support issues" });
//     }

//     const customerStatusMap = {};

//     for (const sensor of allSensors) {
//       const cid = sensor.customerId;
//       if (!cid) continue;

//       if (!customerStatusMap[cid]) {
//         customerStatusMap[cid] = { status: "unknown" };
//       }

//       if (resolvedHardwareIds.includes(sensor.hardwareId) || resolvedHardwareIds.includes(sensor.connected_to)) {
//         customerStatusMap[cid].status = "resolved";
//       } else if (sensor.connected_status === "disconnected") {
//         customerStatusMap[cid].status = "disconnected";
//       } else if (sensor.connected_status === "connected" && customerStatusMap[cid].status !== "disconnected" && customerStatusMap[cid].status !== "resolved") {
//         customerStatusMap[cid].status = "connected";
//       }
//     }

//     const customerIds = Object.keys(customerStatusMap);
//     const users = await User.find({ customerId: { $in: customerIds } }).lean();

//     const combinedCustomerList = users.map(user => {
//       const cid = user.customerId;
//       return {
//         customer : {
//           customerId: cid,
//           connectionStatus: customerStatusMap[cid]?.status || "unknown",
//           username: user.username || "",
//           firstName: user.profile?.firstName || user.firstName || "",
//           lastName: user.profile?.lastName || user.lastName || "",
//           phone: user.phone || user.profile?.contactNumber || user.alternativeNumber || "",
//           email: user.emails?.[0]?.email || user.email || "",
//           phoneVerified: user.phoneVerified || false,
//           address1: user.profile?.address1 || user.address1 || "",
//           address2: user.profile?.address2 || user.address2 || "",
//           city: user.profile?.city || user.city || "",
//           state: user.profile?.state || user.state || "",
//           country: user.profile?.country || user.country || "",
//           zip: user.profile?.zip || "",
//           notes: user.profile?.notes || "",
//           latitude: user.latitude || 0,
//           longitude: user.longitude || 0,
//           fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")),
//           installationId: user.installationId || "",
//           notificationPreferences: {
//             allowNotifications: user.allowNotifications || false,
//             automaticStartAndStopNotify: user.automaticStartAndStopNotify || false,
//             manualStartAndStopNotify: user.manualStartAndStopNotify || false,
//             criticalLowWaterAlert: user.criticalLowWaterAlert || false,
//             lowWaterAlert: user.lowWaterAlert || false,
//             notificationPreference: user.notificationPreference || "never"
//           },
//           surveyStatus: user.survey_status || "pending",
//           buildingName: user.buildingName || "",
//           stripePaymentStatus: user.stripePaymentStatus || false,
//           stripeSubscriptionStatus: user.stripeSubscriptionStatus || false,
//           createdAt: user.createdAt,
//           updatedAt: user.updatedAt
  

//         }
//              };
//     });

//     return reply.send({
//       status_code: 200,
//       data: combinedCustomerList
//     });

//   } catch (error) {
//     console.error("Error in getDisconnectedMoveCustomerDetails:", error);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

exports.getDisconnectedMoveCustomerDetails = async (req, reply) => {
  try {
    const { supportId } = req.params;

    if (!supportId) {
      return reply.code(400).send({ error: "supportId is required" });
    }

    const supportRecord = await Support.findOne({ supportId }).lean();
    if (!supportRecord) {
      return reply.code(404).send({ message: "No support record found for this supportId" });
    }

    // Extract hardwareIds from categorizedIssues only (exclude resolvedIssues)
    const categorizedHardwareIds = [];
    for (const issue of supportRecord.categorizedIssues || []) {
      if (issue.hardwareId) categorizedHardwareIds.push(issue.hardwareId);
      if (Array.isArray(issue.hardwareIds)) categorizedHardwareIds.push(...issue.hardwareIds);
    }

    if (categorizedHardwareIds.length === 0) {
      return reply.code(404).send({ message: "No hardware IDs in categorized issues" });
    }

    const allSensors = await Insensors.find({
      $or: [
        { hardwareId: { $in: categorizedHardwareIds } },
        { connected_to: { $in: categorizedHardwareIds } }
      ]
    }).lean();

    if (allSensors.length === 0) {
      return reply.code(404).send({ message: "No sensors found for categorized hardware IDs" });
    }

    // Determine connection status per customer
    const customerStatusMap = {};

    for (const sensor of allSensors) {
      const cid = sensor.customerId;
      if (!cid) continue;

      if (!customerStatusMap[cid]) {
        customerStatusMap[cid] = { status: "unknown" };
      }

      if (sensor.connected_status === "disconnected") {
        customerStatusMap[cid].status = "disconnected";
      } else if (sensor.connected_status === "connected" && customerStatusMap[cid].status !== "disconnected") {
        customerStatusMap[cid].status = "connected";
      }
    }

    const customerIds = Object.keys(customerStatusMap);
    const users = await User.find({ customerId: { $in: customerIds } }).lean();

    const combinedCustomerList = users.map(user => {
      const cid = user.customerId;
      return {
        customer: {
          customerId: cid,
          connectionStatus: customerStatusMap[cid]?.status || "unknown",
          username: user.username || "",
          firstName: user.profile?.firstName || user.firstName || "",
          lastName: user.profile?.lastName || user.lastName || "",
          phone: user.phone || user.profile?.contactNumber || user.alternativeNumber || "",
          email: user.emails?.[0]?.email || user.email || "",
          phoneVerified: user.phoneVerified || false,
          address1: user.profile?.address1 || user.address1 || "",
          address2: user.profile?.address2 || user.address2 || "",
          city: user.profile?.city || user.city || "",
          state: user.profile?.state || user.state || "",
          country: user.profile?.country || user.country || "",
          zip: user.profile?.zip || "",
          notes: user.profile?.notes || "",
          latitude: user.latitude || 0,
          longitude: user.longitude || 0,
          fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")),
          installationId: user.installationId || "",
          notificationPreferences: {
            allowNotifications: user.allowNotifications || false,
            automaticStartAndStopNotify: user.automaticStartAndStopNotify || false,
            manualStartAndStopNotify: user.manualStartAndStopNotify || false,
            criticalLowWaterAlert: user.criticalLowWaterAlert || false,
            lowWaterAlert: user.lowWaterAlert || false,
            notificationPreference: user.notificationPreference || "never"
          },
          surveyStatus: user.survey_status || "pending",
          buildingName: user.buildingName || "",
          stripePaymentStatus: user.stripePaymentStatus || false,
          stripeSubscriptionStatus: user.stripeSubscriptionStatus || false,
          createdAt: user.createdAt,
          updatedAt: user.updatedAt
        }
      };
    });

    return reply.send({
      status_code: 200,
      data: combinedCustomerList
    });

  } catch (error) {
    console.error("Error in getDisconnectedMoveCustomerDetails:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};

exports.getResolvedCustomerDetails = async (req, reply) => {
  try {
    const { supportId } = req.params;

    if (!supportId) {
      return reply.code(400).send({ error: "supportId is required" });
    }

    const supportRecord = await Support.findOne({ supportId }).lean();

    if (!supportRecord) {
      return reply.code(404).send({ message: "No support record found for this supportId" });
    }

    console.log("✅ Support Record:", JSON.stringify(supportRecord, null, 2));

    const resolvedIssues = supportRecord.resolvedIssues || [];

    if (!Array.isArray(resolvedIssues) || resolvedIssues.length === 0) {
      return reply.code(404).send({ message: "No resolved issues to process" });
    }

    const resolvedHardwareIds = [];
    for (const issue of resolvedIssues) {
      if (issue.hardwareId) resolvedHardwareIds.push(issue.hardwareId);
      if (Array.isArray(issue.hardwareIds)) resolvedHardwareIds.push(...issue.hardwareIds);
    }

    if (resolvedHardwareIds.length === 0) {
      return reply.code(404).send({ message: "No hardware IDs in resolved issues" });
    }

    const sensors = await Insensors.find({
      $or: [
        { hardwareId: { $in: resolvedHardwareIds } },
        { connected_to: { $in: resolvedHardwareIds } }
      ]
    }).lean();

    if (sensors.length === 0) {
      return reply.code(404).send({ message: "No sensors found for resolved hardware" });
    }

    const customerIds = [...new Set(sensors.map(s => s.customerId))];
    const customers = await User.find({ customerId: { $in: customerIds } }).lean();

    const uniqueCustomerMap = {};
    // for (const user of customers) {
    //   const cid = user.customerId;
    //   if (!uniqueCustomerMap[cid]) {
    //     uniqueCustomerMap[cid] = {
    //       customer: {
    //         customerId: cid,
    //         username: user.username || "",
    //         firstName: user.profile?.firstName || user.firstName || "",
    //         lastName: user.profile?.lastName || user.lastName || "",
    //         phone: user.phone || user.profile?.contactNumber || user.alternativeNumber || "",
    //         email: user.emails?.[0]?.email || user.email || "",
    //         phoneVerified: user.phoneVerified || false,
    //         address1: user.profile?.address1 || user.address1 || "",
    //         address2: user.profile?.address2 || user.address2 || "",
    //         city: user.profile?.city || user.city || "",
    //         state: user.profile?.state || user.state || "",
    //         country: user.profile?.country || user.country || "",
    //         zip: user.profile?.zip || "",
    //         notes: user.profile?.notes || "",
    //         latitude: user.latitude || 0,
    //         longitude: user.longitude || 0,
    //         fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")),
    //         installationId: user.installationId || "",
    //         notificationPreferences: {
    //           allowNotifications: user.allowNotifications || false,
    //           automaticStartAndStopNotify: user.automaticStartAndStopNotify || false,
    //           manualStartAndStopNotify: user.manualStartAndStopNotify || false,
    //           criticalLowWaterAlert: user.criticalLowWaterAlert || false,
    //           lowWaterAlert: user.lowWaterAlert || false,
    //           notificationPreference: user.notificationPreference || "never"
    //         },
    //         surveyStatus: user.survey_status || "pending",
    //         buildingName: user.buildingName || "",
    //         stripePaymentStatus: user.stripePaymentStatus || false,
    //         stripeSubscriptionStatus: user.stripeSubscriptionStatus || false,
    //         createdAt: user.createdAt,
    //         updatedAt: user.updatedAt
    //       }
    //     };
    //   }
    // }
// Step 1: Build map of resolvedAt per hardwareId
const resolvedHardwareMap = {};
for (const issue of resolvedIssues) {
  const resolvedAt = issue.resolvedAt;
  if (issue.hardwareId) resolvedHardwareMap[issue.hardwareId] = resolvedAt;
  if (Array.isArray(issue.hardwareIds)) {
    issue.hardwareIds.forEach(hid => {
      resolvedHardwareMap[hid] = resolvedAt;
    });
  }
}

    for (const user of customers) {
      const cid = user.customerId;
      if (!uniqueCustomerMap[cid]) {
        // Find all matching resolvedAt timestamps for this user's hardwareIds
        const customerSensorHardwareIds = sensors
          .filter(s => s.customerId === cid)
          .map(s => s.hardwareId || s.tankhardwareId || s.connected_to)
          .filter(Boolean);
    
        const resolvedTimes = customerSensorHardwareIds
          .map(hid => resolvedHardwareMap[hid])
          .filter(Boolean)
          .sort((a, b) => new Date(b) - new Date(a)); // Get most recent
    
        uniqueCustomerMap[cid] = {
          customer: {
            customerId: cid,
            username: user.username || "",
            firstName: user.profile?.firstName || user.firstName || "",
            lastName: user.profile?.lastName || user.lastName || "",
            phone: user.phone || user.profile?.contactNumber || user.alternativeNumber || "",
            email: user.emails?.[0]?.email || user.email || "",
            phoneVerified: user.phoneVerified || false,
            address1: user.profile?.address1 || user.address1 || "",
            address2: user.profile?.address2 || user.address2 || "",
            city: user.profile?.city || user.city || "",
            state: user.profile?.state || user.state || "",
            country: user.profile?.country || user.country || "",
            zip: user.profile?.zip || "",
            notes: user.profile?.notes || "",
            latitude: user.latitude || 0,
            longitude: user.longitude || 0,
            fcmIds: (user.fcmIds || []).filter(fcm => typeof fcm === "string" && fcm.startsWith("d")),
            installationId: user.installationId || "",
            notificationPreferences: {
              allowNotifications: user.allowNotifications || false,
              automaticStartAndStopNotify: user.automaticStartAndStopNotify || false,
              manualStartAndStopNotify: user.manualStartAndStopNotify || false,
              criticalLowWaterAlert: user.criticalLowWaterAlert || false,
              lowWaterAlert: user.lowWaterAlert || false,
              notificationPreference: user.notificationPreference || "never"
            },
            surveyStatus: user.survey_status || "pending",
            buildingName: user.buildingName || "",
            stripePaymentStatus: user.stripePaymentStatus || false,
            stripeSubscriptionStatus: user.stripeSubscriptionStatus || false,
            createdAt: user.createdAt,
            updatedAt: user.updatedAt,
            resolvedAt: resolvedTimes[0] || null // 🆕 Include latest resolved time if available
          }
        };
      }
    }
    

    return reply.send({
      status_code: 200,
      data: Object.values(uniqueCustomerMap)
    });

  } catch (error) {
    console.error("❌ Error fetching resolved customer details:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};


// const bcrypt = require("bcrypt");

exports.createTeamMemberSupport = async (req, reply) => {
  try {
    const { supportId } = req.params;

    const c_id = await generateTeamMemberId();
    const support_teamMemberId = `AWTMSU${c_id}`;

    const {
      name,
      phone,
      installationTeamMemId,
      password,
      email,
      alternativePhone,
      status
    } = req.body;

    if (!supportId || !support_teamMemberId || !name || !phone || !password) {
      return reply.code(400).send({ error: "Missing required fields" });
    }

    const supportRecord = await Support.findOne({ supportId });

    if (!supportRecord) {
      return reply.code(404).send({ error: "Support record not found" });
    }

    const existingMember = supportRecord.team_member?.team_member.find(
      member => member.phone === phone || member.support_teamMemberId === support_teamMemberId
    );

    if (existingMember) {
      return reply.code(400).send({ error: "Team member with this phone or ID already exists" });
    }

    const hashedPassword = await bcrypt.hash(password, 10);

    const newTeamMember = {
      support_teamMemberId,
      name,
      phone,
      installationTeamMemId,
      password: hashedPassword,
      status: status || "active",
      email: email || null,
      alternativePhone: alternativePhone || null,
    };

    await Support.findOneAndUpdate(
      { supportId },
      {
        $push: {
          "team_member.team_member": newTeamMember
        },
        $set: {
          updatedAt: new Date()
        }
      },
      { new: true }
    );

    return reply.send({
      status_code: 200,
      message: "Team member added successfully",
      teamMember: newTeamMember
    });

  } catch (error) {
    console.error("Error adding team member:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};


exports.getAllTeamMembersListSupport =  async (req, reply) => {
  try {
    const { supportId } = req.params;

    const support = await Support.findOne({ supportId });

    if (!support) {
      return reply.code(404).send({ error: "Support record not found" });
    }

    const teamMembers = support.team_member?.team_member || [];

    return reply.send({
      status_code: 200,
      message: "Team members fetched successfully",
      count: teamMembers.length,
      teamMembers
    });
  } catch (error) {
    console.error("Error fetching team members:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
}
exports.updateTeamMemberSupport = async (req, reply) => {
  try {
    const { supportId, teamMemberId } = req.params;
    const updateData = req.body;

    const support = await Support.findOne({ supportId });

    if (!support) {
      return reply.code(404).send({ error: "Support record not found" });
    }

    const teamMembers = support.team_member?.team_member || [];
    const memberIndex = teamMembers.findIndex(m => m.support_teamMemberId === teamMemberId);

    if (memberIndex === -1) {
      return reply.code(404).send({ error: "Team member not found" });
    }

    Object.assign(teamMembers[memberIndex], updateData);

    await Support.updateOne(
      { supportId },
      {
        $set: {
          "team_member.team_member": teamMembers,
          updatedAt: new Date()
        }
      }
    );

    return reply.send({
      status_code: 200,
      message: "Team member updated successfully",
      teamMember: teamMembers[memberIndex]
    });
  } catch (error) {
    console.error("Error updating team member:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};


exports.deleteTeamMemberSupport =   async (req, reply)=> {
  try {
    const { supportId, teamMemberId } = req.params;

    const support = await Support.findOne({ supportId });

    if (!support) {
      return reply.code(404).send({ error: "Support record not found" });
    }

    const originalLength = support.team_member?.team_member.length || 0;

    const updatedTeam = support.team_member?.team_member.filter(
      m => m.support_teamMemberId !== teamMemberId
    );

    if (originalLength === updatedTeam.length) {
      return reply.code(404).send({ error: "Team member not found" });
    }

    await Support.updateOne(
      { supportId },
      {
        $set: {
          "team_member.team_member": updatedTeam,
          updatedAt: new Date()
        }
      }
    );

    return reply.send({
      status_code: 200,
      message: "Team member deleted successfully"
    });
  } catch (error) {
    console.error("Error deleting team member:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
}

// exports.moveIssueToCategory = async (req, reply) => {
//   try {
//     const { supportId } = req.params;
//     const { category, hardwareId } = req.body;

//     if (!supportId || !category || !hardwareId) {
//       return reply.code(400).send({
//         message: "supportId (path), category and hardwareId (body) are required",
//       });
//     }

//     const support = await Support.findOne({ supportId });
//     if (!support) {
//       return reply.code(404).send({ message: "Support record not found" });
//     }

//     let issueMoved = false;
//     const nowTime = moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");

//     if (!Array.isArray(support.categorizedIssues)) {
//       support.categorizedIssues = [];
//     }

//     // Find the issue where hardwareId matches either hardwareId or inside hardwareIds array
//     const index = support.issues.findIndex((issue) => {
//       // Master hardwareId match
//       if (issue.hardwareId === hardwareId) return true;
//       // Slave hardwareIds array match
//       if (Array.isArray(issue.hardwareIds) && issue.hardwareIds.includes(hardwareId)) return true;
//       return false;
//     });

//     if (index === -1) {
//       return reply.code(404).send({ message: "No matching issue found to move" });
//     }

//     const issue = support.issues[index];

//     // If the hardwareId matches master hardwareId, move entire issue as is
//     if (issue.hardwareId === hardwareId) {
//       support.categorizedIssues.push({
//         ...issue,
//         masterHardwareId: issue.masterHardwareId || issue.hardwareId,
//         category,
//         movedAt: nowTime,
//       });
//       support.issues.splice(index, 1);
//       issueMoved = true;
//     } else {
//       // hardwareId matches inside hardwareIds array — move that slave issue individually
//       const slaveIndex = issue.hardwareIds.indexOf(hardwareId);
//       if (slaveIndex !== -1) {
//         const slaveName = issue.slaveNames?.[slaveIndex] || "Unknown";

//         support.categorizedIssues.push({
//           type: issue.type,
//           hardwareId,
//           masterHardwareId: issue.masterHardwareId || issue.hardwareId,
//           slaveName,
//           category,
//           movedAt: nowTime,
//         });

//         // Remove slave from issue
//         issue.hardwareIds.splice(slaveIndex, 1);
//         issue.slaveNames.splice(slaveIndex, 1);

//         // If no more slaves left, remove the issue completely
//         if (issue.hardwareIds.length === 0) {
//           support.issues.splice(index, 1);
//         }

//         issueMoved = true;
//       }
//     }

//     if (issueMoved) {
//       await support.save();
//       return reply.send({ message: "Issue moved to category successfully" });
//     } else {
//       return reply.code(404).send({ message: "No matching issue found to move" });
//     }
//   } catch (err) {
//     console.error("Error moving issue:", err);
//     return reply.code(500).send({ error: "Internal Server Error" });
//   }
// };



// exports.particularCategory =  async (req, reply) => {
//   const { supportId, category } = req.params;

//   const support = await Support.findOne({ supportId });
//   if (!support) {
//     return reply.code(404).send({ message: 'Support record not found' });
//   }

//   const issues = (support.categorizedIssues || []).filter(
//     (issue) => issue.category === category
//   );

//   if (issues.length === 0) {
//     return reply.code(404).send({ message: `No issues found for category: ${category}` });
//   }

//   return reply.send({ category, issues });
// };


//final
// exports.particularCategory = async (req, reply) => {
//   try {
//     const { customerId, supportId, category } = req.params;

//     if (!customerId || !supportId || !category) {
//       return reply.code(400).send({ error: "customerId, supportId, and category are required" });
//     }

//     const support = await Support.findOne({ supportId }).lean();
//     if (!support) {
//       return reply.code(404).send({ message: "Support record not found" });
//     }

//     // Filter categorizedIssues by category and customerId
//     const issues = (support.categorizedIssues || []).filter(
//       issue => issue.category === category
//     );

//     if (issues.length === 0) {
//       return reply.code(404).send({ message: `No issues found for category: ${category}` });
//     }

//     const hardwareIds = issues.map(issue => issue.hardwareId).filter(Boolean);

//     // Only fetch sensors that belong to the customerId
//     const insensors = await Insensors.find({
//       customerId,
//       hardwareId: { $in: hardwareIds },
//       connected_status: "disconnected"
//     }).lean();

//     if (!insensors.length) {
//       return reply.code(404).send({ message: "No disconnected devices found for this category." });
//     }

//     const orderMap = {};
//     const orders = await Order.find({ customerId }).lean();
//     orders.forEach(order => {
//       order.master_connections.forEach(conn => {
//         orderMap[conn.hardwareId] = {
//           masterName: conn.master_name || null,
//           location: conn.location || null
//         };
//       });
//     });

//     const disconnectedIssues = [];

//     for (const master of insensors.filter(i => i.type === "master")) {
//       const slaves = await Insensors.find({
//         customerId,
//         connected_to: master.hardwareId,
//         connected_status: "disconnected"
//       }).lean();

//       const slaveDetails = slaves.map(slave => {
//         const slaveIssue = issues.find(i => i.hardwareId === slave.hardwareId);
//         return {
//           hardwareId: slave.hardwareId,
//           tankName: slave.tankName || "",
//           location: slave.tankLocation || "",
//           connected_status: slave.connected_status,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time || null,
//           team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time,
//           connected_to: slave.connected_to || "",
//           masterName: orderMap[master.hardwareId]?.masterName || "",
//           type: "slave",
//           typeOfWater: slave.typeOfWater || "",
//           support_lora_last_check_time: null,
//           category,
//           assignedTo: slaveIssue?.assignedTo || null
//         };
//       });

//       const masterIssue = issues.find(i => i.hardwareId === master.hardwareId);

//       disconnectedIssues.push({
//         hardwareId: master.hardwareId,
//         masterName: orderMap[master.hardwareId]?.masterName || "",
//         location: orderMap[master.hardwareId]?.location || "",
//         type: "master",
//         connected_status: master.connected_status,
//         gsm_last_disconnect_time: master.gsm_last_disconnect_time || null,
//         team_member_support_gsm_last_check_time: master.team_member_support_gsm_last_check_time,
//         support_gsm_last_check_time: null,
//         connected_slave_count: slaveDetails.length,
//         connected_slaves: slaveDetails,
//         category,
//         assignedTo: masterIssue?.assignedTo || null
//       });
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       customerId,
//       totalMasters: disconnectedIssues.length,
//       disconnectedIssues
//     });

//   } catch (err) {
//     console.error("Error in particularCategory:", err);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

// exports.particularCategory = async (req, reply) => {
//   try {
//     const { supportId, category } = req.params;

//     if (!supportId || !category) {
//       return reply.code(400).send({ error: "supportId and category are required" });
//     }

//     const support = await Support.findOne({ supportId }).lean();
//     if (!support) {
//       return reply.code(404).send({ message: "Support record not found" });
//     }

//     const issues = (support.categorizedIssues || []).filter(issue => issue.category === category);
//     if (issues.length === 0) {
//       return reply.code(404).send({ message: `No issues found for category: ${category}` });
//     }

//     const hardwareIds = issues.map(issue => issue.hardwareId).filter(Boolean);
//     const insensors = await Insensors.find({
//       hardwareId: { $in: hardwareIds },
//       connected_status: "disconnected"
//     }).lean();

//     if (!insensors.length) {
//       return reply.code(404).send({ message: "No disconnected devices found for this category." });
//     }

//     const orderMap = {};
//     const customerId = insensors[0]?.customerId;
//     if (customerId) {
//       const orders = await Order.find({ customerId }).lean();
//       orders.forEach(order => {
//         order.master_connections.forEach(conn => {
//           orderMap[conn.hardwareId] = {
//             masterName: conn.master_name || null,
//             location: conn.location || null
//           };
//         });
//       });
//     }

//     const disconnectedIssues = [];

//     for (const master of insensors.filter(i => i.type === "master")) {
//       const slaves = await Insensors.find({
//         connected_to: master.hardwareId,
//         connected_status: "disconnected"
//       }).lean();

//       const slaveDetails = slaves.map(slave => {
//         const slaveIssue = issues.find(i => i.hardwareId === slave.hardwareId);
//         return {
//           hardwareId: slave.hardwareId,
//           tankName: slave.tankName || "",
//           location: slave.tankLocation || "",
//           connected_status: slave.connected_status,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time || null,
//           connected_to: slave.connected_to || "",
//           masterName: orderMap[master.hardwareId]?.masterName || "",
//           type: "slave",
//           typeOfWater: slave.typeOfWater || "",
//           support_lora_last_check_time: null,
//           category,
//           assignedTo: slaveIssue?.assignedTo || null // <-- Include assigned details here
//         };
//       });

//       const masterIssue = issues.find(i => i.hardwareId === master.hardwareId);

//       disconnectedIssues.push({
//         hardwareId: master.hardwareId,
//         masterName: orderMap[master.hardwareId]?.masterName || "",
//         location: orderMap[master.hardwareId]?.location || "",
//         type: "master",
//         connected_status: master.connected_status,
//         gsm_last_disconnect_time: master.gsm_last_disconnect_time || null,
//         support_gsm_last_check_time: null,
//         connected_slave_count: slaveDetails.length,
//         connected_slaves: slaveDetails,
//         category,
//         assignedTo: masterIssue?.assignedTo || null // <-- Include assigned details here
//       });
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       totalMasters: disconnectedIssues.length,
//       disconnectedIssues
//     });

//   } catch (err) {
//     console.error("Error in particularCategory:", err);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

// exports.particularCategory = async (req, reply) => {
//   try {
//     const { supportId, category } = req.params;

//     if (!supportId || !category) {
//       return reply.code(400).send({ error: "supportId and category are required" });
//     }

//     const support = await Support.findOne({ supportId }).lean();
//     if (!support) {
//       return reply.code(404).send({ message: "Support record not found" });
//     }

//     const issues = (support.categorizedIssues || []).filter(issue => issue.category === category);
//     if (issues.length === 0) {
//       return reply.code(404).send({ message: `No issues found for category: ${category}` });
//     }

//     const hardwareIds = issues.map(issue => issue.hardwareId).filter(Boolean);

//     // Get all sensors related to the issues (including masters and potential slaves)
//     const allRelatedSensors = await Insensors.find({
//       hardwareId: { $in: hardwareIds }
//     }).lean();

//     if (!allRelatedSensors.length) {
//       return reply.code(404).send({ message: "No matching devices found for this category." });
//     }

//     const orderMap = {};
//     const customerId = allRelatedSensors[0]?.customerId;
//     if (customerId) {
//       const orders = await Order.find({ customerId }).lean();
//       orders.forEach(order => {
//         order.master_connections.forEach(conn => {
//           orderMap[conn.hardwareId] = {
//             masterName: conn.master_name || null,
//             location: conn.location || null
//           };
//         });
//       });
//     }

//     const disconnectedIssues = [];

//     for (const master of allRelatedSensors.filter(i => i.type === "master")) {
//       const slaves = await Insensors.find({
//         connected_to: master.hardwareId
//       }).lean();

//       const disconnectedSlaves = slaves.filter(slave => slave.connected_status === "disconnected");

//       // If master is disconnected OR any of its slaves are disconnected, include it
//       if (master.connected_status === "disconnected" || disconnectedSlaves.length > 0) {
//         const slaveDetails = disconnectedSlaves.map(slave => {
//           const slaveIssue = issues.find(i => i.hardwareId === slave.hardwareId);
//           return {
//             hardwareId: slave.hardwareId,
//             tankName: slave.tankName || "",
//             location: slave.tankLocation || "",
//             connected_status: slave.connected_status,
//             lora_last_disconnect_time: slave.lora_last_disconnect_time || null,
//             connected_to: slave.connected_to || "",
//             masterName: orderMap[master.hardwareId]?.masterName || "",
//             type: "slave",
//             typeOfWater: slave.typeOfWater || "",
//             support_lora_last_check_time: null,
//             category,
//             assignedTo: slaveIssue?.assignedTo || null
//           };
//         });

//         const masterIssue = issues.find(i => i.hardwareId === master.hardwareId);

//         disconnectedIssues.push({
//           hardwareId: master.hardwareId,
//           masterName: orderMap[master.hardwareId]?.masterName || "",
//           location: orderMap[master.hardwareId]?.location || "",
//           type: "master",
//           connected_status: master.connected_status,
//           gsm_last_disconnect_time: master.gsm_last_disconnect_time || null,
//           support_gsm_last_check_time: null,
//           connected_slave_count: slaveDetails.length,
//           connected_slaves: slaveDetails,
//           category,
//           assignedTo: masterIssue?.assignedTo || null
//         });
//       }
//     }

//     if (disconnectedIssues.length === 0) {
//       return reply.code(404).send({ message: "No disconnected devices found for this category." });
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       totalMasters: disconnectedIssues.length,
//       disconnectedIssues
//     });

//   } catch (err) {
//     console.error("Error in particularCategory:", err);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };

// exports.moveIssueToCategory = async (req, reply) => {
//   try {
//     const { supportId } = req.params;
//     const { category, hardwareId } = req.body;

//     if (!supportId || !category || !hardwareId) {
//       return reply.code(400).send({
//         message: "supportId (path), category and hardwareId (body) are required",
//       });
//     }

//     const support = await Support.findOne({ supportId });
//     if (!support) {
//       return reply.code(404).send({ message: "Support record not found" });
//     }

//     let issueMoved = false;
//     const nowTime = moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");

//     if (!Array.isArray(support.categorizedIssues)) {
//       support.categorizedIssues = [];
//     }

//     const index = support.issues.findIndex((issue) => {
//       if (issue.hardwareId === hardwareId) return true;
//       if (Array.isArray(issue.hardwareIds) && issue.hardwareIds.includes(hardwareId)) return true;
//       return false;
//     });

//     if (index === -1) {
//       return reply.code(404).send({ message: "No matching issue found to move" });
//     }

//     const issue = support.issues[index];

//     // Normalize type if it's invalid
//     const normalizedType =
//       issue.type === "GSM or LoRa Disconnected" ? "GSM Disconnected" : issue.type;

//     if (issue.hardwareId === hardwareId) {
//       issue.movedToCategory = true;

//       support.categorizedIssues.push({
//         type: normalizedType,
//         hardwareId: issue.hardwareId,
//         masterHardwareId: issue.masterHardwareId || issue.hardwareId,
//         category,
//         //ticketId : issue.ticketId,
//         movedAt: nowTime,
//         movedToCategory: true,
//       });

//       support.issues.splice(index, 1);
//       issueMoved = true;
//     } else {
//       const slaveIndex = issue.hardwareIds.indexOf(hardwareId);
//       if (slaveIndex !== -1) {
//         const slaveName = issue.slaveNames?.[slaveIndex] || "Unknown";

//         support.categorizedIssues.push({
//           type: normalizedType,
//           hardwareId,
//           masterHardwareId: issue.masterHardwareId || issue.hardwareId,
//           slaveName,
//           category,
//           //ticketId : issue.ticketId,
//           movedAt: nowTime,
//           movedToCategory: true,
//         });

//         issue.hardwareIds.splice(slaveIndex, 1);
//         issue.slaveNames.splice(slaveIndex, 1);

//         if (issue.hardwareIds.length === 0) {
//           support.issues.splice(index, 1);
//         }

//         issueMoved = true;
//       }
//     }

//     if (issueMoved) {
//       await support.save();
//       return reply.send({ message: "Issue moved to category successfully" });
//     } else {
//       return reply.code(404).send({ message: "No matching issue found to move" });
//     }
//   } catch (err) {
//     console.error("Error moving issue:", err);
//     return reply.code(500).send({ error: "Internal Server Error" });
//   }
// };

exports.moveIssueToCategory = async (req, reply) => {
  try {
    const { supportId } = req.params;
    const { category, hardwareId } = req.body;

    if (!supportId || !category || !hardwareId) {
      return reply.code(400).send({
        message: "supportId (path), category and hardwareId (body) are required",
      });
    }

    const support = await Support.findOne({ supportId });
    if (!support) {
      return reply.code(404).send({ message: "Support record not found" });
    }

    let issueMoved = false;
    const nowTime = moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");

    if (!Array.isArray(support.categorizedIssues)) {
      support.categorizedIssues = [];
    }

    const index = support.issues.findIndex((issue) => {
      if (issue.hardwareId === hardwareId) return true;
      if (Array.isArray(issue.hardwareIds) && issue.hardwareIds.includes(hardwareId)) return true;
      return false;
    });

    if (index === -1) {
      return reply.code(404).send({ message: "No matching issue found to move" });
    }

    const issue = support.issues[index];

    // Normalize type if needed
    const normalizedType =
      issue.type === "GSM or LoRa Disconnected" ? "GSM Disconnected" : issue.type;

    if (issue.hardwareId === hardwareId) {
      // Master issue
      issue.movedToCategory = true;

      support.categorizedIssues.push({
        type: normalizedType,
        hardwareId: issue.hardwareId,
        masterHardwareId: issue.masterHardwareId || issue.hardwareId,
        category,
        movedAt: nowTime,
        movedToCategory: true,
      });

      support.issues.splice(index, 1);
      issueMoved = true;
    } else {
      // Slave issue
      const slaveIndex = issue.hardwareIds.indexOf(hardwareId);
      if (slaveIndex !== -1) {
        const slaveName = issue.slaveNames?.[slaveIndex] || "Unknown";

        support.categorizedIssues.push({
          type: normalizedType,
          hardwareId,
          masterHardwareId: issue.masterHardwareId || issue.hardwareId,
          slaveName,
          category,
          movedAt: nowTime,
          movedToCategory: true,
        });

        issue.hardwareIds.splice(slaveIndex, 1);
        issue.slaveNames.splice(slaveIndex, 1);

        // Remove full issue if no more slaves are left
        if (issue.hardwareIds.length === 0) {
          support.issues.splice(index, 1);
        }

        issueMoved = true;
      }
    }

    if (issueMoved) {
      await support.save();

      // 🧹 Cleanup any duplicate issues with same hardwareId (master or slave)
      support.issues = support.issues.filter((i) => {
        const isMaster = i.hardwareId === hardwareId;
        const isSlave = Array.isArray(i.hardwareIds) && i.hardwareIds.includes(hardwareId);
        return !isMaster && !isSlave;
      });

      await support.save();
      return reply.send({ message: "Issue moved to category successfully" });
    } else {
      return reply.code(404).send({ message: "No matching issue found to move" });
    }
  } catch (err) {
    console.error("Error moving issue:", err);
    return reply.code(500).send({ error: "Internal Server Error" });
  }
};


// exports.particularCategory = async (req, reply) => {
//   try {
//     const { supportId, category } = req.params;
//     const { customerId: queryCustomerId } = req.query;

//     if (!supportId || !category) {
//       return reply.code(400).send({ error: "supportId and category are required" });
//     }

//     const support = await Support.findOne({ supportId }).lean();
//     if (!support) {
//       return reply.code(404).send({ message: "Support record not found" });
//     }
//     console.log("support",support)
//     // Choose the appropriate array based on category
//     let issues = [];
//     if (category === "Resolved") {
//       issues = (support.resolvedIssues || []).filter(issue => issue.category === "Resolved");
//     } else {
//       issues = (support.categorizedIssues || []).filter(issue => issue.category === category);
//     }
//     console.log("issues",issues)
//     if (issues.length === 0) {
//       return reply.code(404).send({ message: `No issues found for category: ${category}` });
//     }

//     const hardwareIds = [...new Set(issues.map(issue => issue.hardwareId).filter(Boolean))];

//     if (hardwareIds.length === 0) {
//       return reply.code(404).send({ message: "No hardware IDs found for these issues" });
//     }

//     let customerId = queryCustomerId;

//     if (!customerId) {
//       const sensors = await Insensors.find({ hardwareId: { $in: hardwareIds } }).lean();
//       if (!sensors.length) {
//         return reply.code(404).send({ message: "No sensors found matching these hardware IDs" });
//       }
//       customerId = sensors[0].customerId;
//       if (!customerId) {
//         return reply.code(404).send({ message: "Customer ID not found for these sensors" });
//       }
//     }

//     const allRelatedSensors = await Insensors.find({
//       customerId,
//       hardwareId: { $in: hardwareIds }
//     }).lean();

//     if (!allRelatedSensors.length) {
//       return reply.code(404).send({ message: "No sensors found for the provided customer and hardware IDs" });
//     }

//     const orders = await Order.find({ customerId }).lean();
//     const orderMap = {};
//     orders.forEach(order => {
//       order.master_connections.forEach(conn => {
//         orderMap[conn.hardwareId] = {
//           masterName: conn.master_name || null,
//           location: conn.location || null
//         };
//       });
//     });

//     const disconnectedIssues = [];

//     // for (const master of allRelatedSensors.filter(i => i.type === "master")) {
//       const allMasters = allRelatedSensors.filter(i => i.type === "master");

//       for (const master of allMasters) {
//       const slaves = await Insensors.find({
//         connected_to: master.hardwareId,
//         customerId
//       }).lean();

//       const slaveDetails = await Promise.all(slaves.map(async (slave) => {
//         const slaveHardwareId = slave.tankhardwareId;

//         const tankInfo = await Tank.findOne({
//           $or: [
//             { hardwareId: slaveHardwareId },
//             { tankhardwareId: slaveHardwareId }
//           ]
//         }).lean();

//         const slaveComments = (support.comments || [])
//           .filter(comment => comment.hardwareId === slave.hardwareId)
//           .map(c => c.text);

//         return {
//           hardwareId: slave.tankhardwareId,
//           tankName: slave.tankName || "",
//           location: slave.tankLocation || "",
//           connected_status: slave.connected_status,
//           connected_lora_time: slave.connected_lora_time || "",
//           connected_lora_date: slave.connected_lora_date || "",
//           lora_last_check_time: slave.lora_last_check_time || null,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time || null,
//           connected_to: slave.connected_to || "",
//           masterName: orderMap[master.hardwareId]?.masterName || "",
//           type: "slave",
//           typeOfWater: tankInfo?.typeOfWater || "",
//           support_lora_last_check_time: slave.support_lora_last_check_time || null,
//           team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time || null,
//           comments: slaveComments
//         };
//       }));

//       const masterComments = (support.comments || [])
//         .filter(comment => comment.hardwareId === master.hardwareId)
//         .map(c => c.text);

//       disconnectedIssues.push({
//         hardwareId: master.hardwareId,
//         masterName: orderMap[master.hardwareId]?.masterName || "",
//         location: orderMap[master.hardwareId]?.location || "",
//         type: "master",
//         connected_status: master.connected_status,
//         gsm_last_check_time: master.gsm_last_check_time || null,
//         gsm_last_disconnect_time: master.gsm_last_disconnect_time || null,
//         connected_gsm_date: master.connected_gsm_date || "",
//         connected_gsm_time: master.connected_gsm_time || "",
//         connected_lora_date: master.connected_lora_date || "",
//         connected_lora_time: master.connected_lora_time || "",
//         support_gsm_last_check_time: master.support_gsm_last_check_time || null,
//         team_member_support_gsm_last_check_time: master.team_member_support_gsm_last_check_time || null,
//         connected_slave_count: slaveDetails.length,
//         connected_slaves: slaveDetails,
//         comments: masterComments
//       });
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       customerId,
//       totalMasters: disconnectedIssues.length,
//       disconnectedIssues
//     });

//   } catch (err) {
//     console.error("Error in particularCategory:", err);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };





// exports.assignCategorizeIssue = async (request, reply) => {
//   const { supportId } = request.params;
//   const { support_teamMemberId, startDate, endDate, category, masterHardwareId } = request.body;

//   if (!support_teamMemberId || !startDate || !endDate || !category || !masterHardwareId) {
//     return reply.code(400).send({ error: 'support_teamMemberId, startDate, endDate, category, and masterHardwareId are required' });
//   }

//   const support = await Support.findOne({ supportId });
//   if (!support) {
//     return reply.code(404).send({ error: 'Support record not found' });
//   }

//   const teamMembers = support.team_member?.team_member || [];
//   const teamMember = teamMembers.find(m => m.support_teamMemberId === support_teamMemberId);

//   if (!teamMember) {
//     return reply.code(400).send({ error: `Team member ID ${support_teamMemberId} not found` });
//   }

//   const start = new Date(startDate);
//   const end = new Date(endDate);
//   if (isNaN(start) || isNaN(end)) {
//     return reply.code(400).send({ error: 'Invalid startDate or endDate' });
//   }

//   // ✅ Format to "DD-MM-YYYY HH:mm:ss"
//   const formattedStart = moment(start).format("DD-MM-YYYY HH:mm:ss");
//   const formattedEnd = moment(end).format("DD-MM-YYYY HH:mm:ss");

//   let assignedCount = 0;

//   support.categorizedIssues.forEach(issue => {
//     if (
//       issue.masterHardwareId === masterHardwareId &&
//       issue.category === category
//     ) {
//       issue.assignedTo = {
//         name: teamMember.name,
//         support_teamMemberId: teamMember.support_teamMemberId,
//         phone: teamMember.phone,
//         email: teamMember.email,
//         startDate: formattedStart,  // 👈 use formatted date
//         endDate: formattedEnd       // 👈 use formatted date
//       };
//       assignedCount++;
//     }
//   });

//   if (assignedCount === 0) {
//     return reply.code(404).send({ message: 'No matching issues found for assignment' });
//   }

//   await support.save();

//   return reply.send({
//     message: `Assigned ${assignedCount} categorized issue(s) to ${teamMember.name}`,
//     assignedTo: teamMember.support_teamMemberId
//   });
// };



// const moment = require('moment'); // Ensure moment is installed



// exports.particularCategory = async (req, reply) => {
//   try {
//     const { supportId, category } = req.params;
//     const { customerId: queryCustomerId } = req.query;

//     if (!supportId || !category) {
//       return reply.code(400).send({ error: "supportId and category are required" });
//     }

//     const support = await Support.findOne({ supportId }).lean();
//     if (!support) return reply.code(404).send({ message: "Support record not found" });

//     // Filter issues by category
//     const issues = (category === "Resolved" ? support.resolvedIssues : support.categorizedIssues || [])
//       .filter(issue => issue.category === category);
//     if (!issues.length) return reply.code(404).send({ message: `No issues found for category: ${category}` });

//     const hardwareIds = [...new Set(issues.map(issue => issue.hardwareId).filter(Boolean))];
//     if (!hardwareIds.length) return reply.code(404).send({ message: "No hardware IDs found for these issues" });

//     let customerId = queryCustomerId;
//     if (!customerId) {
//       const sensorDoc = await Insensors.findOne({ hardwareId: { $in: hardwareIds } }).lean();
//       if (!sensorDoc || !sensorDoc.customerId) return reply.code(404).send({ message: "Customer ID not found" });
//       customerId = sensorDoc.customerId;
//     }

//     const allRelatedSensors = await Insensors.find({
//       customerId,
//       hardwareId: { $in: hardwareIds }
//     }).lean();

//     if (!allRelatedSensors.length) return reply.code(404).send({ message: "No sensors found" });

//     // Order map
//     const orders = await Order.find({ customerId }).lean();
//     const orderMap = {};
//     orders.forEach(order => {
//       order.master_connections.forEach(conn => {
//         orderMap[conn.hardwareId] = {
//           masterName: conn.master_name || null,
//           location: conn.location || null
//         };
//       });
//     });

//     // Create map for issue -> movedAt/resolvedAt
//     const issueMap = {};
//     issues.forEach(issue => {
//       issueMap[issue.hardwareId] = issue;
//     });

//     const disconnectedIssues = [];

//     const allMasters = allRelatedSensors.filter(i => i.type === "master");

//     for (const master of allMasters) {
//       const slaves = await Insensors.find({ connected_to: master.hardwareId, customerId }).lean();

//       // Get latest IoT data for master
//       const latestIotData = await IotData.findOne({ hardwareId: master.hardwareId }).sort({ date: -1 }).lean();

//       // GSM Status
//       const now = moment.tz("Asia/Kolkata");
//       let gsm_last_check_time = null;
//       let gsmConnected = false;

//       if (latestIotData?.date) {
//         const gsmTime = moment.tz(latestIotData.date, "Asia/Kolkata");
//         const gsmDiff = now.diff(gsmTime, "minutes");
//         gsmConnected = gsmDiff <= 1;
//         gsm_last_check_time = latestIotData.date;
//       }

//       // Prepare slave details with LORA check
//       const slaveDetails = await Promise.all(slaves.map(async (slave) => {
//         const slaveHardwareId = slave.tankhardwareId?.trim();
//         const matchedTank = latestIotData?.tanks?.find(tank => tank.tankhardwareId === slaveHardwareId);

//         let loraConnected = false;
//         let lora_last_check_time = null;

//         if (matchedTank?.date && matchedTank?.tankHeight !== "0") {
//           const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata");
//           const loraDiff = now.diff(tankTime, "minutes");
//           loraConnected = loraDiff <= 1;
//           lora_last_check_time = matchedTank.date;
//         }

//         const tankInfo = await Tank.findOne({
//           $or: [
//             { hardwareId: slaveHardwareId },
//             { tankhardwareId: slaveHardwareId }
//           ]
//         }).lean();

//         const slaveComments = (support.comments || [])
//           .filter(comment => comment.hardwareId === slave.hardwareId)
//           .map(c => c.text);

//         return {
//           hardwareId: slave.tankhardwareId,
//           tankName: slave.tankName || "",
//           location: slave.tankLocation || "",
//           connected_status: slave.connected_status,
//           connected_lora_date: slave.connected_lora_date || "",
//           connected_lora_time: slave.connected_lora_time || "",
//           loraConnected,
//           lora_last_check_time,
//           lora_last_disconnect_time: slave.lora_last_disconnect_time || null,
//           connected_to: slave.connected_to || "",
//           masterName: orderMap[master.hardwareId]?.masterName || "",
//           type: "slave",
//           typeOfWater: tankInfo?.typeOfWater || "",
//           support_lora_last_check_time: slave.support_lora_last_check_time || null,
//           team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time || null,
//           comments: slaveComments
//         };
//       }));

//       const masterComments = (support.comments || [])
//         .filter(comment => comment.hardwareId === master.hardwareId)
//         .map(c => c.text);

//       const issue = issueMap[master.hardwareId];

//       disconnectedIssues.push({
//         hardwareId: master.hardwareId,
//         masterName: orderMap[master.hardwareId]?.masterName || "",
//         location: orderMap[master.hardwareId]?.location || "",
//         type: "master",
//         connected_status: master.connected_status,
//         gsmConnected,
//         gsm_last_check_time,
//         gsm_last_disconnect_time: master.gsm_last_disconnect_time || null,
//         connected_gsm_date: master.connected_gsm_date || "",
//         connected_gsm_time: master.connected_gsm_time || "",
//         connected_lora_date: master.connected_lora_date || "",
//         connected_lora_time: master.connected_lora_time || "",
//         support_gsm_last_check_time: master.support_gsm_last_check_time || null,
//         team_member_support_gsm_last_check_time: master.team_member_support_gsm_last_check_time || null,
//         connected_slave_count: slaveDetails.length,
//         connected_slaves: slaveDetails,
//         comments: masterComments,
//         movedAt: category !== "Resolved" ? (issue?.movedAt || null) : null,
//         resolvedAt: category === "Resolved" ? (issue?.resolvedAt || null) : null
//       });
//     }

//     return reply.send({
//       status_code: 200,
//       supportId,
//       customerId,
//       totalMasters: disconnectedIssues.length,
//       disconnectedIssues
//     });

//   } catch (err) {
//     console.error("Error in particularCategory:", err);
//     return reply.code(500).send({ error: "Internal server error" });
//   }
// };


exports.particularCategory = async (req, reply) => {
  try {
    const { supportId, category } = req.params;
    const { customerId: queryCustomerId } = req.query;

    if (!supportId || !category) {
      return reply.code(400).send({ error: "supportId and category are required" });
    }

    const support = await Support.findOne({ supportId }).lean();
    if (!support) return reply.code(404).send({ message: "Support record not found" });

    const issues = (category === "Resolved" ? support.resolvedIssues : support.categorizedIssues || [])
      .filter(issue => issue.category === category);
    if (!issues.length) return reply.code(404).send({ message: `No issues found for category: ${category}` });

    const hardwareIds = [...new Set(issues.map(issue => issue.hardwareId).filter(Boolean))];
    if (!hardwareIds.length) return reply.code(404).send({ message: "No hardware IDs found for these issues" });

    let customerId = queryCustomerId;
    if (!customerId) {
      const sensorDoc = await Insensors.findOne({ hardwareId: { $in: hardwareIds } }).lean();
      if (!sensorDoc || !sensorDoc.customerId) return reply.code(404).send({ message: "Customer ID not found" });
      customerId = sensorDoc.customerId;
    }

    const allRelatedSensors = await Insensors.find({
      customerId,
      hardwareId: { $in: hardwareIds }
    }).lean();

    if (!allRelatedSensors.length) return reply.code(404).send({ message: "No sensors found" });

    const orders = await Order.find({ customerId }).lean();
    const orderMap = {};
    orders.forEach(order => {
      order.master_connections.forEach(conn => {
        orderMap[conn.hardwareId] = {
          masterName: conn.master_name || null,
          location: conn.location || null
        };
      });
    });

    const issueMap = {};
    issues.forEach(issue => {
      issueMap[issue.hardwareId] = issue;
    });

    const disconnectedIssues = [];
    const allMasters = allRelatedSensors.filter(i => i.type === "master");

    for (const master of allMasters) {
      const slaves = await Insensors.find({ connected_to: master.hardwareId, customerId }).lean();
      const latestIotData = await IotData.findOne({ hardwareId: master.hardwareId }).sort({ date: -1 }).lean();

      const now = moment.tz("Asia/Kolkata");
      let gsmConnected = false;

      if (latestIotData?.date) {
        const gsmTime = moment.tz(latestIotData.date, "Asia/Kolkata");
        const gsmDiff = now.diff(gsmTime, "minutes");
        gsmConnected = gsmDiff <= 1;
      }

      // 🔄 Update master connected_status
      await Insensors.updateOne(
        { hardwareId: master.hardwareId },
        { $set: { connected_status: gsmConnected ? "connected" : "disconnected" } }
      );

      const slaveDetails = await Promise.all(slaves.map(async (slave) => {
        const slaveHardwareId = slave.tankhardwareId?.trim();
        const matchedTank = latestIotData?.tanks?.find(tank => tank.tankhardwareId === slaveHardwareId);

        let loraConnected = false;

        if (matchedTank?.date && matchedTank?.tankHeight !== "0") {
          const tankTime = moment.tz(matchedTank.date, "Asia/Kolkata");
          const loraDiff = now.diff(tankTime, "minutes");
          loraConnected = loraDiff <= 1;
        }

        // 🔄 Update slave connected_status
        await Insensors.updateOne(
          { tankhardwareId: slaveHardwareId },
          { $set: { connected_status: loraConnected ? "connected" : "disconnected" } }
        );

        const tankInfo = await Tank.findOne({
          $or: [
            { hardwareId: slaveHardwareId },
            { tankhardwareId: slaveHardwareId }
          ]
        }).lean();

        // const slaveComments = (support.comments || [])
        //   .filter(comment => comment.hardwareId === slave.hardwareId)
        //   .map(c => c.text);

        const slaveComments = (support.comments || [])
  .filter(comment =>
    comment.hardwareId === slave.hardwareId &&
    comment.customerId === customerId // ✅ filter by customer
  )
  .map(c => ({
    text: c.text,
    commentsTime: c.createdAt
      ? moment(c.createdAt).tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm")
      : null
  }));


        return {
          hardwareId: slave.tankhardwareId,
          tankName: slave.tankName || "",
          location: slave.tankLocation || "",
          connected_status: loraConnected ? "connected" : "disconnected",
          connected_to: slave.connected_to || "",
          gsm_last_check_time: slave.gsm_last_check_time || null,
                  gsm_last_disconnect_time: slave.gsm_last_disconnect_time || null,
                  lora_last_disconnect_time: slave.lora_last_disconnect_time || null,
                  connected_gsm_date: slave.connected_gsm_date || "",
                   connected_gsm_time: slave.connected_gsm_time || "",
                  connected_lora_date: slave.connected_lora_date || "",
                  connected_lora_time: slave.connected_lora_time || "",
                   support_lora_last_check_time: slave.support_lora_last_check_time || null,
          masterName: orderMap[master.hardwareId]?.masterName || "",
          type: "slave",
          typeOfWater: tankInfo?.typeOfWater || "",
          outDoor_status: slave.outDoor_status || "inprogress",
          //comments: slaveComments
        };
      }));

      // const masterComments = (support.comments || [])
      //   .filter(comment => comment.hardwareId === master.hardwareId)
      //   .map(c => c.text);

      const masterComments = (support.comments || [])
  .filter(comment =>
    comment.hardwareId === master.hardwareId &&
    comment.customerId === customerId // ✅ filter by customer
  )
  .map(c => ({
    text: c.text,
    commentsTime: c.createdAt
      ? moment(c.createdAt).tz("Asia/Kolkata").format("DD-MM-YYYY HH:mm")
      : null
  }));


      const issue = issueMap[master.hardwareId];

      disconnectedIssues.push({
        hardwareId: master.hardwareId,
        masterName: orderMap[master.hardwareId]?.masterName || "",
        location: orderMap[master.hardwareId]?.location || "",
        type: "master",
        connected_status: gsmConnected ? "connected" : "disconnected",
        connected_slave_count: slaveDetails.length,
        gsm_last_check_time: master.gsm_last_check_time || null,
        gsm_last_disconnect_time: master.gsm_last_disconnect_time || null,
        lora_last_disconnect_time: master.lora_last_disconnect_time || null,
        connected_gsm_date: master.connected_gsm_date || "",
         connected_gsm_time: master.connected_gsm_time || "",
        connected_lora_date: master.connected_lora_date || "",
        connected_lora_time: master.connected_lora_time || "",
         support_gm_last_check_time: master.support_gsm_last_check_time || null,
        connected_slaves: slaveDetails,
        comments: masterComments,
        outDoor_status: master.outDoor_status || "inprogress",
        movedAt: category !== "Resolved" ? (issue?.movedAt || null) : null,
        resolvedAt: category === "Resolved" ? (issue?.resolvedAt || null) : null,
        category: issue?.category || category,
        hardwareList: master.hardwareList || {},
        assignedTo: issue?.assignedTo || null,
      });
    }

    return reply.send({
      status_code: 200,
      supportId,
      customerId,
      totalMasters: disconnectedIssues.length,
      disconnectedIssues
    });

  } catch (err) {
    console.error("Error in particularCategory:", err);
    return reply.code(500).send({ error: "Internal server error" });
  }
};

exports.updateHardwareList = async (req, reply) => {
  try {
    const { supportId, customerId, hardwareId } = req.params;
    const { hardwareList } = req.body;

    if (!supportId || !customerId || !hardwareId) {
      return reply.code(400).send({ error: "supportId, customerId, and hardwareId are required" });
    }

    if (!Array.isArray(hardwareList)) {
      return reply.code(400).send({ error: "hardwareList must be an array of objects" });
    }

    const support = await Support.findOne({ supportId }).lean();
    if (!support) return reply.code(404).send({ error: "Support record not found" });

    const escalationIssue = (support.categorizedIssues || []).find(issue =>
      issue.category === "Escalation" && issue.hardwareId === hardwareId
    );

    if (!escalationIssue) {
      return reply.code(403).send({
        error: "Escalation issue not found. Cannot update hardware list."
      });
    }

    const sensor = await Insensors.findOne({ customerId, hardwareId });
    if (!sensor) {
      return reply.code(404).send({ error: "Insensor not found" });
    }

    sensor.hardwareList = hardwareList;
    sensor.markModified('hardwareList');
    await sensor.save();

    return reply.send({
  status_code: 200,
  message: "Hardware list updated successfully",
  data: {
    supportId,
    customerId,
    hardwareId,
    hardwareList: sensor.hardwareList // ← array format
  }
});

  } catch (err) {
    console.error("Error updating hardwareList:", err);
    return reply.code(500).send({ error: "Internal server error" });
  }
};








exports.assignCategorizeIssue = async (request, reply) => {
  const { supportId } = request.params;
  const { support_teamMemberId, category, masterHardwareId } = request.body;

  if (!support_teamMemberId || !category || !masterHardwareId) {
    return reply.code(400).send({
      error: 'support_teamMemberId, category, and masterHardwareId are required'
    });
  }

  const support = await Support.findOne({ supportId });
  if (!support) {
    return reply.code(404).send({ error: 'Support record not found' });
  }

  const teamMembers = support.team_member?.team_member || [];
  const teamMember = teamMembers.find(m => m.support_teamMemberId === support_teamMemberId);

  if (!teamMember) {
    return reply.code(400).send({ error: `Team member ID ${support_teamMemberId} not found` });
  }

  const assignedAt = moment().format("DD-MM-YYYY HH:mm:ss");
const assignmentCode = Math.floor(100000 + Math.random() * 900000).toString(); // random 6-digit code
  let assignedCount = 0;

  support.categorizedIssues.forEach(issue => {
    if (
      issue.masterHardwareId === masterHardwareId &&
      issue.category === category
    ) {
      issue.assignedTo = {
        name: teamMember.name,
        support_teamMemberId: teamMember.support_teamMemberId,
        phone: teamMember.phone,
        email: teamMember.email,
        assignedAt: assignedAt,
        assignmentCode: assignmentCode  // ← Add this field
      };
      assignedCount++;
    }
  });

  if (assignedCount === 0) {
    return reply.code(404).send({ message: 'No matching issues found for assignment' });
  }

  await support.save();

  return reply.send({
    message: `Assigned ${assignedCount} categorized issue(s) to ${teamMember.name}`,
    assignmentCode: assignmentCode, // ← Return the code in response
    assignedTo: {
      support_teamMemberId: teamMember.support_teamMemberId,
      name: teamMember.name,
      phone: teamMember.phone,
      email: teamMember.email,
      assignedAt: assignedAt,
    }
  });
};





exports.getCategorizedIssue = async (request, reply) => {
  try {
    const { support_teamMemberId, customerId } = request.params;

    if (!support_teamMemberId || !customerId) {
      return reply.code(400).send({ error: "support_teamMemberId and customerId are required" });
    }

    const supportRecords = await Support.find({
      'categorizedIssues.assignedTo.support_teamMemberId': support_teamMemberId
    }).lean();

    if (!supportRecords.length) {
      return reply.code(404).send({ message: 'No categorized issues assigned to this team member.' });
    }

    const allIssues = supportRecords.flatMap(s =>
      s.categorizedIssues
        .filter(i => i.assignedTo?.support_teamMemberId === support_teamMemberId)
        .map(i => ({ ...i, supportId: s.supportId }))
    );

    if (!allIssues.length) {
      return reply.code(404).send({ message: 'No categorized issues found for this team member.' });
    }

    const supportId = allIssues[0].supportId;
    const hardwareIds = allIssues.map(i => i.hardwareId).filter(Boolean);
    const masterHardwareIds = allIssues.map(i => i.masterHardwareId).filter(Boolean);

    const insensors = await Insensors.find({
      customerId,
      $or: [
        { hardwareId: { $in: hardwareIds } },
        { hardwareId: { $in: masterHardwareIds } }
      ],
      connected_status: "disconnected"
    }).lean();

    if (!insensors.length) {
      return reply.code(404).send({ message: "No disconnected devices found for this customer and team member." });
    }

    const orders = await Order.find({ customerId }).lean();
    const orderMap = {};
    orders.forEach(order => {
      order.master_connections?.forEach(conn => {
        orderMap[conn.hardwareId] = {
          masterName: conn.master_name || null,
          location: conn.location || null
        };
      });
    });

    const formatDateIfValid = (value) => {
      const date = moment(value, "DD-MM-YYYY HH:mm:ss", true);
      return date.isValid() ? date.format("DD-MM-YYYY HH:mm:ss") : null;
    };

    const formatDateIfValidShort = (date, time) => {
      if (!date || !time) return null;
      const dateTime = `${date} ${time}`;
      const parsed = moment(dateTime, "DD-MM-YYYY HH:mm:ss", true);
      return parsed.isValid() ? parsed.format("DD-MM-YYYY HH:mm:ss") : null;
    };

    const disconnectedIssues = [];
    const masters = insensors.filter(d => d.type === "master");

    for (const master of masters) {
      const masterIssue = allIssues.find(i => i.masterHardwareId === master.hardwareId);
      if (!masterIssue) continue;

      const slaves = await Insensors.find({
        customerId,
        connected_to: master.hardwareId,
        connected_status: "disconnected",
        type: "slave"
      }).lean();

      const slaveDetails = [];

      for (const slave of slaves) {
        const issue = allIssues.find(i =>
          i.hardwareId === slave.hardwareId ||
          (Array.isArray(i.hardwareIds) && i.hardwareIds.includes(slave.hardwareId))
        );

        slaveDetails.push({
          hardwareId: slave.tankhardwareId,
          tankName: slave.tankName || "",
          location: slave.location || "",
          connected_status: slave.connected_status,
          team_member_support_lora_last_check_time: slave.team_member_support_lora_last_check_time || null,
          lora_last_disconnect_time: formatDateIfValid(slave.lora_last_disconnect_time) ||
                                     formatDateIfValidShort(slave.connected_lora_date, slave.connected_lora_time),
          connected_to: slave.connected_to || "",
          masterName: orderMap[master.hardwareId]?.masterName || "",
          type: "slave",
          typeOfWater: "",
          support_lora_last_check_time: null,
          category: issue?.category || "",
          startDate: issue?.assignedTo?.startDate
            ? moment(issue.assignedTo.startDate).format("YYYY-MM-DD HH:mm:ss")
            : null,
          endDate: issue?.assignedTo?.endDate
            ? moment(issue.assignedTo.endDate).format("YYYY-MM-DD HH:mm:ss")
            : null
        });
      }

      disconnectedIssues.push({
        hardwareId: master.hardwareId,
        masterName: orderMap[master.hardwareId]?.masterName || "",
        location: orderMap[master.hardwareId]?.location || "",
        type: "master",
        connected_status: master.connected_status,
        gsm_last_disconnect_time: formatDateIfValid(master.gsm_last_disconnect_time) ||
                                   formatDateIfValidShort(master.connected_gsm_date, master.connected_gsm_time),
        support_gsm_last_check_time: null,
        team_member_support_gsm_last_check_time: master.team_member_support_gsm_last_check_time || null,
        connected_slave_count: slaveDetails.length,
        connected_slaves: slaveDetails,
        category: masterIssue?.category || "",
        startDate: masterIssue?.assignedTo?.startDate
          ? moment(masterIssue.assignedTo.startDate).format("YYYY-MM-DD HH:mm:ss")
          : null,
        endDate: masterIssue?.assignedTo?.endDate
          ? moment(masterIssue.assignedTo.endDate).format("YYYY-MM-DD HH:mm:ss")
          : null
      });
    }

    return reply.send({
      status_code: 200,
      supportId,
      totalMasters: disconnectedIssues.length,
      disconnectedIssues
    });

  } catch (error) {
    console.error("Error in getCategorizedIssue:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};



exports.StatusTeamMember =  async (request, reply) => {
  try {
    const { support_teamMemberId } = request.params;
    const { status } = request.body;

    if ( !support_teamMemberId || !status) {
      return reply.code(400).send({
        success: false,
        message: " support_teamMemberId, and status are required."
      });
    }

    const result = await Support.findOneAndUpdate(
      {  'team_member.team_member.support_teamMemberId': support_teamMemberId },
      { $set: { 'team_member.team_member.$.status': status } },
      { new: true }
    );

    if (!result) {
      return reply.code(404).send({
        success: false,
        message: "Team member not found with given supportId and support_teamMemberId."
      });
    }

    return reply.send({
      success: true,
      message: "Team member status updated successfully.",
      updatedMember: result.team_member.team_member.find(
        tm => tm.support_teamMemberId === support_teamMemberId
      )
    });

  } catch (error) {
    console.error("Error updating team member status:", error);
    return reply.code(500).send({
      success: false,
      message: "Internal Server Error"
    });
  }
};


exports.updateComments = async (req, reply) => {
  try {
    const { supportId } = req.params;
    const { comments, customerId, hardwareId } = req.body;

    console.log("Incoming request body:", req.body);
    console.log("typeof comments:", typeof comments);
    console.log("value of comments:", comments);

    if (!supportId || !customerId || !hardwareId) {
      return reply.code(400).send({ error: "supportId, customerId and hardwareId are required" });
    }

    const trimmedComment = typeof comments === "string" ? comments.trim() : "";
    if (!trimmedComment) {
      return reply.code(400).send({ error: "comments must be a non-empty string" });
    }

    // Step 1: Validate sensor
    const sensor = await Insensors.findOne({
      customerId,
      $or: [{ hardwareId }, { tankhardwareId: hardwareId }]
    }).lean();

    if (!sensor) {
      return reply
        .code(404)
        .send({ error: "No sensor found with this hardwareId for this customerId" });
    }

    // Step 2: Load support record
    const supportRecord = await Support.findOne({ supportId });
    if (!supportRecord) {
      return reply.code(404).send({ error: "Support record not found" });
    }

    // Step 3: Check whether the hardwareId exists in issues or categorizedIssues
    const issueExists =
      supportRecord.issues?.some(
        (issue) => issue.hardwareId === hardwareId || issue.masterHardwareId === hardwareId
      ) ||
      supportRecord.categorizedIssues?.some(
        (issue) => issue.hardwareId === hardwareId || issue.masterHardwareId === hardwareId
      );

    if (!issueExists) {
      return reply
        .code(404)
        .send({ error: "HardwareId not found in issues or categorizedIssues for this support" });
    }

    // Step 4: Append comment object
    const commentObj = {
      text: trimmedComment,
      customerId,
      hardwareId,
      createdAt: new Date()
    };

    if (!Array.isArray(supportRecord.comments)) {
      supportRecord.comments = [];
    }

    supportRecord.comments.push(commentObj);

    await supportRecord.save();

    return reply.send({
      message: "Comment added successfully",
      comment: {
        ...commentObj,
        createdAt: moment(commentObj.createdAt).format("DD-MM-YYYY HH:mm")
      }
    });
  } catch (error) {
    console.error("Error updating comments:", error);
    return reply.code(500).send({ error: "Internal server error" });
  }
};



exports.resolvedIssuesForSupport = async (req, reply) => {
  try {
    const { supportId } = req.params;
    const { category, hardwareId } = req.body;

    if (!supportId || !category || !hardwareId) {
      return reply.code(400).send({
        message: "supportId (path), category and hardwareId (body) are required",
      });
    }

    if (!["Escalation", "Pending"].includes(category)) {
      return reply.code(400).send({
        message: "Invalid category. Only 'Escalation' or 'Pending' are allowed",
      });
    }

    const support = await Support.findOne({ supportId });
    if (!support) {
      return reply.code(404).send({ message: "Support record not found" });
    }

    if (!Array.isArray(support.categorizedIssues)) support.categorizedIssues = [];
    if (!Array.isArray(support.resolvedIssues)) support.resolvedIssues = [];

    const nowTime = moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");

    // Try to find issue in categorizedIssues
    let categorizedIndex = support.categorizedIssues.findIndex(
      (issue) => issue.hardwareId === hardwareId
    );

    // Try to find issue in resolvedIssues
    let resolvedIndex = support.resolvedIssues.findIndex(
      (issue) => issue.hardwareId === hardwareId
    );

    // Get the issue object from categorized or resolved
    let issue =
      categorizedIndex !== -1
        ? support.categorizedIssues[categorizedIndex]
        : resolvedIndex !== -1
        ? support.resolvedIssues[resolvedIndex]
        : null;

    if (!issue) {
      return reply.code(404).send({
        message: `No issue found with hardwareId: ${hardwareId}`,
      });
    }

    const masterHardwareId = issue.masterHardwareId || issue.hardwareId;

    // Fetch master and slaves
    const master = await Insensors.findOne({ hardwareId: masterHardwareId }).lean();
    if (!master) {
      return reply
        .code(404)
        .send({ message: `Master device not found with hardwareId ${masterHardwareId}` });
    }

    const slaves = await Insensors.find({ connected_to: masterHardwareId }).lean();

    const allConnected =
      master.connected_status === "connected" &&
      slaves.every((s) => s.connected_status === "connected");

    if (allConnected) {
      // If fully connected

      if (resolvedIndex === -1) {
        // Add to resolvedIssues only if not already present
        support.resolvedIssues.push({
          type: issue.type,
          hardwareId: issue.hardwareId,
          masterHardwareId,
          //ticketId: issue.ticketId,
          category: "Resolved",
          resolvedAt: nowTime,
          originalMovedAt: issue.movedAt || null,
          movedToCategory: true,
          slaveName: issue.slaveName || null,
          currentlyResolved: true,
          invalidatedAt: null,
        });
      } else {
        // If already in resolvedIssues, just mark as currently resolved again
        support.resolvedIssues[resolvedIndex].currentlyResolved = true;
        support.resolvedIssues[resolvedIndex].invalidatedAt = null;
        support.resolvedIssues[resolvedIndex].resolvedAt = nowTime;
      }

      // Remove from categorizedIssues if present
      if (categorizedIndex !== -1) {
        support.categorizedIssues.splice(categorizedIndex, 1);
      }

      await support.save();
      return reply.send({ message: "Issue moved to resolved category successfully" });
    } else {
      // One or more devices still disconnected

      // Mark in resolvedIssues as not currently resolved, don't remove it
      if (resolvedIndex !== -1) {
        support.resolvedIssues[resolvedIndex].currentlyResolved = false;
        support.resolvedIssues[resolvedIndex].invalidatedAt = nowTime;
      }

      // Move or update issue in categorizedIssues
      if (categorizedIndex === -1) {
        // Not in categorized — add with category from body
        support.categorizedIssues.push({
          type: issue.type,
          hardwareId: issue.hardwareId,
          masterHardwareId,
          //ticketId: issue.ticketId,
          category: category,
          movedAt: nowTime,
          movedToCategory: true,
          slaveName: issue.slaveName || null,
        });
      } else {
        // Already in categorized — update if category has changed
        if (support.categorizedIssues[categorizedIndex].category !== category) {
          support.categorizedIssues[categorizedIndex].category = category;
          support.categorizedIssues[categorizedIndex].movedAt = nowTime;
          support.categorizedIssues[categorizedIndex].movedToCategory = true;
        }
      }

      await support.save();
      return reply.send({
        message: `Master or some slaves are disconnected. Issue moved/kept in '${category}' category.`,
      });
    }
  } catch (err) {
    console.error("Error in resolvedIssuesForSupport:", err);
    return reply.code(500).send({ error: "Internal Server Error" });
  }
};


exports.resolveIssueIfAllConnected = async (req, reply) => {
  try {
    const { supportId } = req.params;
    const { hardwareId, reason, category } = req.body;

    if (!supportId || !hardwareId || !reason) {
      return reply.code(400).send({
        message: "supportId (path), hardwareId and reason (body) are required",
      });
    }

    const support = await Support.findOne({ supportId });
    if (!support) {
      return reply.code(404).send({ message: "Support record not found" });
    }

    if (!Array.isArray(support.categorizedIssues)) support.categorizedIssues = [];
    if (!Array.isArray(support.resolvedIssues)) support.resolvedIssues = [];

    const categorizedIndex = support.categorizedIssues.findIndex(
      (issue) => issue.hardwareId === hardwareId
    );

    if (categorizedIndex === -1) {
      return reply.code(404).send({
        message: `No categorized issue found for hardwareId: ${hardwareId}`,
      });
    }

    const issue = support.categorizedIssues[categorizedIndex];
    const masterHardwareId = issue.masterHardwareId || issue.hardwareId;

    const master = await Insensors.findOne({ hardwareId: masterHardwareId }).lean();
    if (!master) {
      return reply
        .code(404)
        .send({ message: `Master device not found with hardwareId ${masterHardwareId}` });
    }

    const slaves = await Insensors.find({ connected_to: masterHardwareId }).lean();

    const allConnected =
      master.connected_status === "connected" &&
      slaves.every((s) => s.connected_status === "connected");

    if (!allConnected) {
      return reply.code(400).send({
        message: "Not all devices are connected. Cannot resolve issue.",
      });
    }

    const nowTime = moment().tz("Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");

    support.resolvedIssues.push({
      type: issue.type,
      hardwareId: issue.hardwareId,
      masterHardwareId,
      category: category || "Resolved", // ✅ use passed category or fallback to "Resolved"
      resolvedAt: nowTime,
      originalMovedAt: issue.movedAt || null,
      movedToCategory: true,
      slaveName: issue.slaveName || null,
      currentlyResolved: true,
      invalidatedAt: null,
      reason: reason,
    });

    support.categorizedIssues.splice(categorizedIndex, 1);

    await support.save();

    return reply.send({ message: "Issue resolved and moved to resolvedIssues", resolvedAt: nowTime });

  } catch (err) {
    console.error("Error resolving issue:", err);
    return reply.code(500).send({ error: "Internal Server Error" });
  }
};
