const QualityCheck = require("../../models/securityops/qcModel");
const { errorResponse } = require("../../utils/errorResponseHandler");
const { logUserAction } = require("../../utils/userActionLogger");
const qcService = require("../../services/securityops/qcService");
const CommercialVehicle = require("../../models/securityops/vehicleModel");
const { pool } = require("../../config/db");

const createSample = async (req, res) => {
  try {
    const { vehicleId, parameters } = req.body;

    if (!vehicleId) {
      return res.status(400).json({
        success: false,
        message: "vehicleId is required",
      });
    }

    const vehicle = await CommercialVehicle.findById(vehicleId);

    if (!vehicle) {
      return res.status(404).json({
        success: false,
        message: "Vehicle not found",
      });
    }

    if (!vehicle.referenceNo) {
      return res.status(400).json({
        success: false,
        message: "PO Number missing in vehicle entry",
      });
    }

    /* ===== Generate SampleId ===== */

    const last = await QualityCheck.findOne()
      .sort({ createdAt: -1 })
      .select("sampleId");

    let next = 1;

    if (last?.sampleId) {
      next = parseInt(last.sampleId.split("-")[1]) + 1;
    }

    const sampleId = `SMP-${String(next).padStart(3, "0")}`;

    /* ===== Format Parameters ===== */

    const formattedParams = parameters.map((p) => ({
      parameterName: p.parameterName,
      history: [
        {
          value: String(p.value),
          tempStatus: p.tempStatus || "Pending",
        },
      ],
    }));

    /* ===== Create QC ===== */

    const qc = await QualityCheck.create({
      sampleId,
      poNumber: vehicle.referenceNo,
      vendor: vehicle.materialDetails.supplierName,
      vehicleNumber: vehicle.vehicleNumber,
      vehicleId: vehicle._id,
      parameters: formattedParams,
      status: "IN PROGRESS",
      createdBy: req.user?._id,
      approvedBy: req.user?._id,
    });

    /* ===== Update Vehicle Snapshot ===== */

    await CommercialVehicle.findByIdAndUpdate(vehicleId, {
      qcId: qc._id,
      qcStatus: qc.status,
    });

    return res.json({
      success: true,
      message: "QC Sample created",
      data: qc,
    });
  } catch (err) {
    console.error(err);
    return res.status(500).json({
      success: false,
      message: err.message,
    });
  }
};

// const getAllSamples = async (req, res) => {
//   try {
//     const {
//       page = 1,
//       limit = 10,
//       search = "",
//       sortBy = "createdAt",
//       order = "desc",
//     } = req.query;

//     const pageNumber = parseInt(page);
//     const pageSize = parseInt(limit);
//     const sortOrder = order === "asc" ? 1 : -1;

//     /* ================= QC FILTER ================= */

//     const qcFilter = { isActive: true };

//     if (search) {
//       qcFilter.$or = [
//         { sampleId: { $regex: search, $options: "i" } },
//         { poNumber: { $regex: search, $options: "i" } },
//         { vehicleNumber: { $regex: search, $options: "i" } },
//         { vendor: { $regex: search, $options: "i" } },
//       ];
//     }

//     /* ================= FETCH QC ================= */

//     const qcTotal = await QualityCheck.countDocuments(qcFilter);

//     const qcSamples = await QualityCheck.find(qcFilter)
//       .populate("createdBy", "firstName lastName")
//       .sort({ [sortBy]: sortOrder })
//       // .skip((pageNumber - 1) * pageSize)
//       // .limit(pageSize)
//       .lean();

//     const formattedQC = qcSamples.map((q) => ({
//       ...q,
//       createdBy: q.createdBy
//         ? `${q.createdBy.firstName || ""} ${q.createdBy.lastName || ""}`.trim()
//         : "-",
//       isPending: false,
//     }));

//     /* ================= FETCH PENDING VEHICLES ================= */

//     const vehicleFilter = {
//       qcId: null,
//       gateStatus: "Inside",
//       isDeleted: false,
//     };

//     if (search) {
//       vehicleFilter.$or = [
//         { vehicleNumber: { $regex: search, $options: "i" } },
//         { "materialDetails.poNumber": { $regex: search, $options: "i" } },
//         { "materialDetails.supplierName": { $regex: search, $options: "i" } },
//       ];
//     }

//     // const pendingVehicles = await CommercialVehicle.find(vehicleFilter)
//     //   .sort({ createdAt: -1 })
//     //   .limit(pageSize) // safe limit
//     //   .lean();
//     const pendingVehicles = await CommercialVehicle.find(vehicleFilter)
//       .populate("createdBy", "firstName lastName")
//       .sort({ createdAt: -1 })
//       // .limit(pageSize)
//       .lean();

//     const formattedPending = pendingVehicles.map((v) => ({
//       _id: v._id,
//       vehicleId: v._id, // ⭐ important
//       sampleId: null,
//       poNumber: v.referenceNo || "-",
//       vendor: v.materialDetails?.supplierName || "-",
//       vehicleNumber: v.vehicleNumber,
//       parameters: [],
//       status: "ENTRY DONE",
//       isPending: true,
//       // createdBy: v.createdBy,
//       createdBy: v.createdBy
//         ? `${v.createdBy.firstName || ""} ${v.createdBy.lastName || ""}`.trim()
//         : "-",
//       createdAt: v.createdAt,
//     }));

//     const merged = [...formattedQC, ...formattedPending];

//     merged.sort((a, b) => {
//       return order === "asc"
//         ? new Date(a.createdAt) - new Date(b.createdAt)
//         : new Date(b.createdAt) - new Date(a.createdAt);
//     });

//     const totalRecords = merged.length;

//     const paginatedData = merged.slice(
//       (pageNumber - 1) * pageSize,
//       pageNumber * pageSize,
//     );

//     // return res.status(200).json({
//     //   success: true,
//     //   data: finalData,
//     //   pagination: {
//     //     totalRecords: qcTotal + formattedPending.length,
//     //     currentPage: pageNumber,
//     //     totalPages: Math.ceil((qcTotal + formattedPending.length) / pageSize),
//     //     pageSize,
//     //   },
//     // });
//     return res.status(200).json({
//       success: true,
//       data: paginatedData,
//       pagination: {
//         totalRecords,
//         currentPage: pageNumber,
//         totalPages: Math.ceil(totalRecords / pageSize),
//         pageSize,
//       },
//     });
//   } catch (error) {
//     console.error("QC GET ERROR:", error);
//     return errorResponse(res, 500, "Failed to fetch QC Samples");
//   }
// };




const getPendingVehiclesForQC = async (req, res) => {
  try {
    const vehicles = await CommercialVehicle.find({
      qcId: null,
      gateStatus: "Inside",
      isDeleted: false,
    }).select("_id vehicleNumber materialDetails");

    const formatted = vehicles.map((v) => ({
      _id: v._id,
      vehicleNumber: v.vehicleNumber,
      poNumber: v.materialDetails?.poNumber || "-",
      vendor: v.materialDetails?.supplierName || "-",
      isPending: true,
    }));

    res.json({ success: true, data: formatted });
  } catch (err) {
    res.status(500).json({ success: false, message: err.message });
  }
};

// const updateSample = async (req, res) => {
//   try {
//     const { id } = req.params;

//     const existingSample = await QualityCheck.findById(id);

//     if (!existingSample || !existingSample.isActive) {
//       return errorResponse(res, 404, "QC Sample not found");
//     }
//     // Allowed Fields (Future Safe)
//     // const allowedFields = [
//     //   "poNumber",
//     //   "vehicleNumber",
//     //   "vendor",
//     //   "parameters",
//     //   "status",
//     //   "source",
//     //   "tests",
//     // ];
//     const allowedFields = [
//       "poNumber",
//       "vehicleNumber",
//       "vendor",
//       "parameters",
//       "status",
//     ];

//     const updateData = {};

//     for (let key of allowedFields) {
//       if (req.body[key] !== undefined) {
//         updateData[key] = req.body[key];
//       }
//     }

//     if (updateData.poNumber) {
//       updateData.poNumber = updateData.poNumber.trim().toUpperCase();
//     }
//     if (updateData.vehicleNumber) {
//       updateData.vehicleNumber = updateData.vehicleNumber.trim().toUpperCase();
//     }
//     // if (updateData.poNumber || updateData.vehicleNumber) {
//     //   const duplicateCheck = await QCSample.findOne({
//     //     _id: { $ne: id },
//     //     poNumber: updateData.poNumber || existingSample.poNumber,
//     //     vehicleNumber:
//     //       updateData.vehicleNumber || existingSample.vehicleNumber,
//     //     isActive: true,
//     //   });

//     //   if (duplicateCheck) {
//     //     return errorResponse(
//     //       res,
//     //       409,
//     //       "Another QC Sample exists with same PO and Vehicle"
//     //     );
//     //   }
//     // }
//     const updatedSample = await QualityCheck.findByIdAndUpdate(
//       id,
//       {
//         $set: {
//           ...updateData,
//           updatedBy: req.user?.id || null,
//         },
//       },
//       { new: true },
//     );

//     // Audit Log
//     // await logUserAction({
//     //   userId: req.user?.id,
//     //   action: "UPDATE_QC_SAMPLE",
//     //   module: "QC",
//     //   description: `QC Sample ${updatedSample.sampleId} updated`,
//     //   metadata: {
//     //     sampleId: updatedSample.sampleId,
//     //   },
//     // });
//     return res.status(200).json({
//       success: true,
//       message: "QC Sample updated successfully",
//       data: updatedSample,
//     });
//   } catch (error) {
//     console.error("QC UPDATE ERROR:", error);
//     return errorResponse(res, 500, "Failed to update QC Sample");
//   }
// };
const updateSample = async (req, res) => {
  try {
    const { id } = req.params;

    const { poNumber, vehicleNumber, vendor, status, parameters } = req.body;

    const existingSample = await QualityCheck.findById(id);

    if (!existingSample || !existingSample.isActive) {
      return errorResponse(res, 404, "QC Sample not found");
    }

    // Normalize fields
    const updateFields = {};

    if (poNumber) updateFields.poNumber = poNumber.trim().toUpperCase();
    if (vehicleNumber)
      updateFields.vehicleNumber = vehicleNumber.trim().toUpperCase();
    if (vendor) updateFields.vendor = vendor;
    if (status) updateFields.status = status;

    // updateFields.updatedBy = req.user?.id || null;
    if (req.user?.id) {
      updateFields.updatedBy = req.user.id;
    }

    // 🔹 Update basic fields
    await QualityCheck.updateOne({ _id: id }, { $set: updateFields });

    if (parameters && parameters.length > 0) {
      for (const param of parameters) {
        const { parameterName, value } = param;

        let tempStatus = param.tempStatus;

        /*  fallback logic */
        if (!tempStatus) {
          tempStatus = "Approved"; // default for old flows
        }

        await QualityCheck.updateOne(
          {
            _id: id,
            "parameters.parameterName": parameterName,
          },
          {
            $push: {
              "parameters.$.history": {
                value,
                tempStatus,
                testedAt: new Date(),
                testedBy: req.user?._id,
              },
            },
          },
        );
      }
    }

    const updatedSample = await QualityCheck.findById(id);

    return res.status(200).json({
      success: true,
      message: "QC Sample updated successfully",
      data: updatedSample,
    });
  } catch (error) {
    console.error("QC UPDATE ERROR:", error);
    return errorResponse(res, 500, "Failed to update QC Sample");
  }
};

// const deleteSample = async (req, res) => {
//   try {
//     const { id } = req.params;

//     const sample = await QualityCheck.findById(id);
//     if (!sample) {
//       return errorResponse(res, 404, "QC Sample not found");
//     }

//     if (sample.isDeleted) {
//       return errorResponse(res, 400, "QC Sample already deleted");
//     }

//     sample.isDeleted = true;
//     sample.isActive = false;
//     // sample.deletedAt = new Date();
//     // sample.deletedBy = req.user?.id || null;
//     await sample.save();

//     await logUserAction({
//       userId: req.user?.id,
//       action: "DELETE_QC_SAMPLE",
//       module: "QC",
//       description: `QC Sample ${sample.sampleId} deleted`,
//       metadata: {
//         sampleId: sample.sampleId,
//       },
//     });

//     return res.status(200).json({
//       success: true,
//       message: "QC Sample deleted successfully",
//     });
//   } catch (error) {
//     console.error("QC DELETE ERROR:", error);
//     return errorResponse(res, 500, "Failed to delete QC Sample");
//   }
// };
const deleteSample = async (req, res) => {
  try {
    const { id } = req.params;

    const sample = await QualityCheck.findOne({
      _id: id,
      isDeleted: false,
    });

    if (!sample) {
      return errorResponse(res, 404, "QC Sample not found or already deleted");
    }

    sample.isDeleted = true;
    sample.isActive = false;
    sample.deletedAt = new Date();
    sample.deletedBy = req.user?.id || null;

    await sample.save();

    if (req.user?.id) {
      await logUserAction({
        userId: req.user.id,
        action: "DELETE_QC_SAMPLE",
        module: "QC",
        description: `QC Sample ${sample.sampleId} deleted`,
        metadata: {
          sampleId: sample.sampleId,
        },
      });
    }

    return res.status(200).json({
      success: true,
      message: "QC Sample deleted successfully",
    });
  } catch (error) {
    console.error("QC DELETE ERROR:", error);
    return errorResponse(res, 500, "Failed to delete QC Sample");
  }
};

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

    const sample = await QualityCheck.findOne({
      _id: id,
      isActive: true,
      isDeleted: false,
    })
      .populate("createdBy", "name email")
      .populate("approvedBy", "name email")
      .lean();

    if (!sample) {
      return errorResponse(res, 404, "QC Sample not found");
    }

    return res.status(200).json({
      success: true,
      data: sample,
    });
  } catch (error) {
    console.error("QC GET BY ID ERROR:", error);
    return errorResponse(res, 500, "Failed to fetch QC Sample");
  }
};

const updateQCParameter = async (req, res) => {
  try {
    const { sampleId, parameterId, value, result } = req.body;

    const data = await qcService.updateQCParameter(
      sampleId,
      parameterId,
      value,
      result,
    );

    res.json({
      success: true,
      message: "QC parameter updated",
      data,
    });
  } catch (err) {
    res.status(500).json({
      success: false,
      message: "Failed to update QC",
    });
  }
};

const getParameterHistory = async (req, res) => {
  try {
    const { sampleId } = req.params;

    const history = await qcService.getParameterHistory(sampleId);

    return res.status(200).json({
      success: true,
      count: history.length,
      data: history,
    });
  } catch (error) {
    console.error("QC HISTORY ERROR:", error);

    return res.status(500).json({
      success: false,
      message: "Failed to fetch QC history",
    });
  }
};

// const completeQC = async (req, res) => {
//   try {
//     const { id } = req.params;

//     const sample = await QualityCheck.findById(id);

//     if (!sample || sample.isDeleted) {
//       return res.status(404).json({
//         success: false,
//         message: "Sample not found",
//       });
//     }

//     if (
//       sample.status === "APPROVED" ||
//       sample.status === "REJECTED"
//     ) {
//       return res.status(400).json({
//         success: false,
//         message: "QC already completed",
//       });
//     }

//     // ⭐ get latest status of each parameter
//     let hasRejected = false;
//     let hasPending = false;

//     sample.parameters.forEach((p) => {
//       const latest = p.history[p.history.length - 1];

//       if (!latest) hasPending = true;
//       else if (latest.tempStatus === "Rejected") hasRejected = true;
//       else if (latest.tempStatus === "Pending") hasPending = true;
//     });

//     if (hasPending) {
//       return res.status(400).json({
//         success: false,
//         message: "All parameters must be tested",
//       });
//     }

//     const finalStatus = hasRejected ? "REJECTED" : "APPROVED";

//     sample.status = finalStatus;
//     sample.approvedDate = new Date();
//     sample.approvedBy = req.user?.id || null;

//     await sample.save();

//     return res.json({
//       success: true,
//       message: `QC ${finalStatus}`,
//       data: sample,
//     });
//   } catch (err) {
//     console.log(err);
//     res.status(500).json({
//       success: false,
//       message: "Failed to complete QC",
//     });
//   }
// };


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

    const sample = await QualityCheck.findById(id);

    if (!sample || sample.isDeleted) {
      return res.status(404).json({
        success: false,
        message: "Sample not found",
      });
    }

    //  Already completed check
    if (sample.completeStatus === "Completed") {
      return res.status(400).json({
        success: false,
        message: "QC already completed",
      });
    }

    let finalStatus = "APPROVED";

    for (const param of sample.parameters) {
      if (!param.history || param.history.length === 0) continue;

      const last = param.history[param.history.length - 1];

      if (last.tempStatus === "Rejected") {
        finalStatus = "REJECTED";
        break;
      }

      if (last.tempStatus === "Pending") {
        return res.status(400).json({
          success: false,
          message: "Some parameters still pending",
        });
      }
    }

    //  ONLY THIS LINE IMPORTANT
    sample.status = finalStatus;
    sample.completeStatus = "Completed";

    await sample.save();

    /* VERY IMPORTANT — UPDATE VEHICLE */
    await CommercialVehicle.findByIdAndUpdate(sample.vehicleId, {
      qcStatus: finalStatus,
    });

    return res.json({
      success: true,
      message: "QC Completed Successfully",
      data: sample,
    });
  } catch (err) {
    console.log(err);
    res.status(500).json({
      success: false,
      message: "Failed to complete QC",
    });
  }
};

module.exports = {
  createSample,
  // getAllSamples,
  updateSample,
  deleteSample,
  getSampleById,
  getParameterHistory,
  getPendingVehiclesForQC,
  completeQC,
};
