const Patient = require("../models/patientModel");
const { errorResponse } = require("../utils/errorResponseHandler");
const { logUserAction } = require("../utils/userActionLogger");
const mongoose = require("mongoose");
const Appointment = require("../models/appointmentModel");


const createPatient = async (req, res) => {
    try {
        const userId = req.user._id;
        const orgId = req.user?.orgId || req.query.orgId || req.body.orgId;
        // const orgId = req.user.orgId;

        const {
            name,
            phone,
            email,
            address,
            status = "Active",
            admissionStatus,
            gender,
            dateOfBirth,
            // bloodGroup
        } = req.body;

        if (!name || !phone) {
            return errorResponse(res, "Name and phone are required", 400);
        }

        //  Prevent duplicate patient by phone in same org
        const existing = await Patient.findOne({
            phone,
            orgId,
            isDeleted: false,
        });

        if (existing) {
            return errorResponse(res, "Patient already exists", 409);
        }

        const patientCount = await Patient.countDocuments({ orgId });

        const patient = await Patient.create({
            patientId: `PAT-${String(patientCount + 1).padStart(5, "0")}`,
            name,
            phone,
            email,
            address,
            gender,
            dateOfBirth,
            // bloodGroup: req.body.bloodGroup || null,
            admissionStatus: admissionStatus || "Not Admitted",
            admittedAt: admissionStatus === "Admitted" ? new Date() : null,
            status,
            orgId,
            createdBy: userId,
        });

        await logUserAction(req, {
            action: "CREATE_PATIENT",
            module: "PATIENT",
            entityId: patient._id,
        });

        res.status(201).json({
            success: true,
            message: "Patient created successfully",
            data: patient,
        });
    } catch (error) {
        console.error(error);
        errorResponse(res, "Failed to create patient", 500, error);
    }
};

// const getPatients = async (req, res) => {
//     try {
//         const orgId = req.user.orgId;
//         let { page = 1, limit = 10, search = "" } = req.query;

//         page = parseInt(page);
//         limit = parseInt(limit);

//         const query = {
//             orgId,
//             isDeleted: false,
//         };

//         if (search) {
//             query.$or = [
//                 { name: { $regex: search, $options: "i" } },
//                 { phone: { $regex: search, $options: "i" } },
//                 { email: { $regex: search, $options: "i" } },
//             ];
//         }

//         const [patients, total] = await Promise.all([
//             Patient.find(query)
//                 .populate("createdBy", "firstName lastName email")
//                 .sort({ createdAt: -1 })
//                 .skip((page - 1) * limit)
//                 .limit(limit)
//                 .select("-__v"),
//             Patient.countDocuments(query),
//         ]);

//         res.status(200).json({
//             success: true,
//             data: patients,
//             pagination: {
//                 total,
//                 page,
//                 limit,
//                 totalPages: Math.ceil(total / limit),
//             },
//         });
//     } catch (error) {
//         console.error(error);
//         errorResponse(res, "Failed to fetch patients", 500, error);
//     }
// };
const getPatients = async (req, res) => {
  try {
    const orgId = req.user?.orgId || req.query.orgId || req.body.orgId;

    // const orgId = req.user.orgId;
    let { page = 1, limit = 10, search = "", filter } = req.query;

    page = parseInt(page);
    limit = parseInt(limit);

    const query = {
      orgId,
      isDeleted: false,
    };

    /* ---------------- SEARCH ---------------- */
    if (search) {
      query.$or = [
        { name: { $regex: search, $options: "i" } },
        { phone: { $regex: search, $options: "i" } },
        { email: { $regex: search, $options: "i" } },
      ];
    }

    /* ---------------- DASHBOARD FILTERS ---------------- */

    const today = new Date().toISOString().split("T")[0];

    //  New Patients Today
    if (filter === "new") {
      const start = new Date();
      start.setHours(0, 0, 0, 0);

      const end = new Date();
      end.setHours(23, 59, 59, 999);

      query.createdAt = { $gte: start, $lte: end };
    }

    //  Active Today (has any appointment today)
    if (filter === "active") {
      const patientIds = await Appointment.distinct("patient", {
        date: today,
        isDeleted: false,
      });

      query._id = { $in: patientIds };
    }

    //  Follow-ups Today (only if you have isFollowUp)
    if (filter === "followup") {
      const patientIds = await Appointment.distinct("patient", {
        date: today,
        isDeleted: false,
      });

      query._id = { $in: patientIds };
    }

    /* ---------------- FETCH ---------------- */

    const [patients, total] = await Promise.all([
      Patient.find(query)
        .populate("createdBy", "firstName lastName email")
        .sort({ createdAt: -1 })
        .skip((page - 1) * limit)
        .limit(limit)
        .select("-__v"),
      Patient.countDocuments(query),
    ]);

    res.status(200).json({
      success: true,
      data: patients,
      pagination: {
        total,
        page,
        limit,
        totalPages: Math.ceil(total / limit),
      },
    });
  } catch (error) {
    console.error(error);
    errorResponse(res, "Failed to fetch patients", 500, error);
  }
};


const getPatientById = async (req, res) => {
    try {
        const { id } = req.params;
        const orgId = req.user?.orgId || req.query.orgId || req.body.orgId;

        // const orgId = req.user.orgId;

        if (!mongoose.Types.ObjectId.isValid(id)) {
            return errorResponse(res, "Invalid patient ID", 400);
        }

        const patient = await Patient.findOne({
            _id: id,
            orgId,
            isDeleted: false,
        }).select("-__v")
         .populate("createdBy", "firstName lastName email")
         .lean();;

        if (!patient) {
            return errorResponse(res, "Patient not found", 404);
        }

        res.status(200).json({
            success: true,
            data: patient,
        });
    } catch (error) {
        console.error(error);
        errorResponse(res, "Failed to fetch patient", 500, error);
    }
};

const updatePatient = async (req, res) => {
    try {
        const { id } = req.params;
        const userId = req.user._id;
        // const orgId = req.user.orgId;
        const orgId = req.user?.orgId || req.query.orgId || req.body.orgId;


        if (!mongoose.Types.ObjectId.isValid(id)) {
            return errorResponse(res, "Invalid patient ID", 400);
        }

        const allowedFields = [
            "name",
            "phone",
            "email",
            "address",
            "status",
            "gender",
            "dateOfBirth",
            "bloodGroup",
            "admissionStatus"
        ];

        const updates = {};
        allowedFields.forEach((field) => {
            if (req.body[field] !== undefined) {
                updates[field] = req.body[field];
            }
        });


        if (req.body.admissionStatus === "Admitted") {
            updates.admittedAt = new Date();
            updates.dischargedAt = null;
        }
        if (req.body.admissionStatus === "Discharged") {
            updates.dischargedAt = new Date();
        }
        updates.updatedBy = userId;


        const patient = await Patient.findOneAndUpdate(
            { _id: id, orgId, isDeleted: false },
            updates,
            { new: true }
        );

        if (!patient) {
            return errorResponse(res, "Patient not found", 404);
        }

        await logUserAction(req, {
            action: "UPDATE_PATIENT",
            module: "PATIENT",
            entityId: patient._id,
        });

        res.status(200).json({
            success: true,
            message: "Patient updated successfully",
            data: patient,
        });
    } catch (error) {
        console.error(error);
        errorResponse(res, "Failed to update patient", 500, error);
    }
};


const deletePatient = async (req, res) => {
    try {
        const { id } = req.params;
        const userId = req.user._id;
        const orgId = req.user?.orgId || req.query.orgId || req.body.orgId;

        // const orgId = req.user.orgId;

        if (!mongoose.Types.ObjectId.isValid(id)) {
            return errorResponse(res, "Invalid patient ID", 400);
        }

        const patient = await Patient.findOneAndUpdate(
            { _id: id, orgId, isDeleted: false },
            { isDeleted: true, updatedBy: userId },
            { new: true }
        );

        if (!patient) {
            return errorResponse(res, "Patient not found", 404);
        }

        await logUserAction(req, {
            action: "DELETE_PATIENT",
            module: "PATIENT",
            entityId: patient._id,
        });

        res.status(200).json({
            success: true,
            message: "Patient deleted successfully",
        });
    } catch (error) {
        console.error(error);
        errorResponse(res, "Failed to delete patient", 500, error);
    }
};


module.exports = {
    createPatient,
    getPatients,
    getPatientById,
    updatePatient,
    deletePatient,
}