const Specialization = require("../../models/specializationModel");
const { errorResponse } = require("../../utils/errorResponseHandler");
const { logUserAction } = require("../../utils/userActionLogger");

/* ================= CREATE SPECIALIZATION ================= */
const createSpecialization = async (req, res) => {
  try {
    const { name, orgId } = req.body;

    if (!name) return errorResponse(res, "Specialization name is required", 400);
    if (!orgId) return errorResponse(res, "Organization ID is required", 400);

    const userId = req.user?._id;

    // Duplicate check (case-insensitive, per org)
    const existing = await Specialization.findOne({
      name: { $regex: `^${name}$`, $options: "i" },
      orgId,
      isDeleted: false,
    });

    if (existing) {
      return errorResponse(
        res,
        "Specialization already exists in this organization",
        409
      );
    }

    const specialization = await Specialization.create({
      name,
      orgId,
      createdBy: userId || null,
      updatedBy: null,
    });

    await logUserAction({
      userId,
      orgId,
      action: "CREATE",
      model: "Specialization",
      details: { specializationId: specialization._id, name },
      req,
    });

    res.status(201).json({ success: true, data: specialization });
  } catch (error) {
    return errorResponse(res, "Failed to create specialization", 400, error);
  }
};

/* ================= GET ALL SPECIALIZATIONS ================= */
const getSpecializations = async (req, res) => {
  try {
    let { page = 1, limit = 10 , orgId} = req.query;
    page = parseInt(page);
    limit = parseInt(limit);
    const skip = (page - 1) * limit;
    // const orgId = "68b546e06c3ca038387c3173";
    const finalOrgId = orgId || req.user?.orgId;
    const query = {
      isDeleted: false,
      orgId: finalOrgId,
    };

    const [data, total] = await Promise.all([
      Specialization.find(query)
        .populate("createdBy", "firstName lastName email")
        .populate("updatedBy", "firstName lastName email")
        .sort({ createdAt: -1 })
        .skip(skip)
        .limit(limit),
      Specialization.countDocuments(query),
    ]);

    await logUserAction({
      userId: req.user?._id,
      orgId: req.user?.orgId,
      action: "READ",
      model: "Specialization",
      details: { page, limit, count: data.length },
      req,
    });

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

/* ================= GET BY ID ================= */
const getSpecializationById = async (req, res) => {
  try {
    const specialization = await Specialization.findById(req.params.id)
      .populate("createdBy", "firstName lastName email")
      .populate("updatedBy", "firstName lastName email");

    if (!specialization)
      return errorResponse(res, "Specialization not found", 404);

    await logUserAction({
      userId: req.user?._id,
      orgId: specialization.orgId,
      action: "READ",
      model: "Specialization",
      details: { specializationId: specialization._id },
      req,
    });

    res.status(200).json({ success: true, data: specialization });
  } catch (error) {
    return errorResponse(res, "Error fetching specialization", 500, error);
  }
};

/* ================= UPDATE ================= */
const updateSpecialization = async (req, res) => {
  try {
    const { name, status } = req.body;
    const userId = req.user?._id;

    // Duplicate check
    if (name) {
      const duplicate = await Specialization.findOne({
        _id: { $ne: req.params.id },
        name: { $regex: `^${name}$`, $options: "i" },
        orgId: req.user.orgId,
        isDeleted: false,
      });

      if (duplicate) {
        return errorResponse(
          res,
          "Specialization already exists in this organization",
          409
        );
      }
    }

    const updateData = {
      updatedBy: userId || null,
      updatedAt: new Date(),
    };

    if (name) updateData.name = name;
    if (status !== undefined) updateData.status = status;

    const specialization = await Specialization.findByIdAndUpdate(
      req.params.id,
      updateData,
      { new: true, runValidators: true }
    )
      .populate("createdBy", "firstName lastName email")
      .populate("updatedBy", "firstName lastName email");

    if (!specialization)
      return errorResponse(res, "Specialization not found", 404);

    await logUserAction({
      userId,
      orgId: specialization.orgId,
      action: "UPDATE",
      model: "Specialization",
      details: { specializationId: specialization._id, updatedFields: updateData },
      req,
    });

    res.status(200).json({ success: true, data: specialization });
  } catch (error) {
    return errorResponse(res, "Failed to update specialization", 400, error);
  }
};

/* ================= SOFT DELETE ================= */
const deleteSpecialization = async (req, res) => {
  try {
    const userId = req.user?._id;

    const specialization = await Specialization.findByIdAndUpdate(
      req.params.id,
      { isDeleted: true, updatedBy: userId },
      { new: true }
    );

    if (!specialization)
      return errorResponse(res, "Specialization not found", 404);

    await logUserAction({
      userId,
      orgId: specialization.orgId,
      action: "DELETE",
      model: "Specialization",
      details: { specializationId: specialization._id },
      req,
    });

    res.status(200).json({
      success: true,
      message: "Specialization deleted successfully",
      data: specialization,
    });
  } catch (error) {
    return errorResponse(res, "Failed to delete specialization", 500, error);
  }
};

module.exports = {
  createSpecialization,
  getSpecializations,
  getSpecializationById,
  updateSpecialization,
  deleteSpecialization,
};
