const Shift = require("../../models/admin/shiftModel");
const { errorResponse } = require("../../utils/errorResponseHandler");
const { logUserAction } = require("../../utils/userActionLogger");

// Create Shift
const createShift = async (req, res) => {
    try {
        const { shiftName, startTime, endTime, orgId } = req.body;

        // Validations
        if (!shiftName) return errorResponse(res, "Shift name is required", 400);
        if (!startTime) return errorResponse(res, "Start time is required", 400);
        if (!endTime) return errorResponse(res, "End time is required", 400);
        if (!orgId) return errorResponse(res, "Organization ID is required", 400);

        const userId = req.user?._id;

        // Check duplicate shift in same org
        const existingShift = await Shift.findOne({ shiftName, orgId, isDeleted: false });
        if (existingShift) {
            return errorResponse(res, "Shift name already exists in this organization", 409);
        }

        const shift = await Shift.create({
            shiftName,
            startTime,
            endTime,
            orgId,
            createdBy: userId || null,
            updatedBy: userId || null,
        });

        // Log action
        await logUserAction({
            userId,
            orgId,
            action: "CREATE",
            model: "Shift",
            details: { shiftId: shift._id, shiftName },
            req,
        });

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

// Get All Shifts with Pagination
const getShifts = async (req, res) => {
    try {
        let { page = 1, limit = 10 } = req.query;
       
        page = parseInt(page);
        limit = parseInt(limit);
        const skip = (page - 1) * limit;

        const query = { isDeleted: false };

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

        // Log action
        await logUserAction({
            userId: req.user?._id,
            orgId: req.user?.orgId || null,
            action: "READ",
            model: "Shift",
            details: { page, limit, count: shifts.length },
            req,
        });

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

// Get Shift by ID
const getShiftById = async (req, res) => {
    try {
        const shift = await Shift.findById(req.params.id)
            .populate("createdBy", "firstName lastName email")
            .populate("updatedBy", "firstName lastName email")
            .populate("orgId", "orgName");

        if (!shift) return errorResponse(res, "Shift not found", 404);

        // Log action
        await logUserAction({
            userId: req.user?._id,
            orgId: shift.orgId?._id || null,
            action: "READ",
            model: "Shift",
            details: { shiftId: shift._id },
            req,
        });

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

// Update Shift
const updateShift = async (req, res) => {
    try {
        const { shiftName, startTime, endTime, status } = req.body;
        const userId = req.user?._id;

        const updateData = { updatedBy: userId || null };

        if (shiftName) updateData.shiftName = shiftName;
        if (startTime) updateData.startTime = startTime;
        if (endTime) updateData.endTime = endTime;
        if (status !== undefined) updateData.status = status;

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

        if (!shift) return errorResponse(res, "Shift not found", 404);

        // Log action
        await logUserAction({
            userId,
            orgId: shift.orgId?._id || null,
            action: "UPDATE",
            model: "Shift",
            details: { shiftId: shift._id, updatedFields: updateData },
            req,
        });

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

// Soft Delete Shift
const deleteShift = async (req, res) => {
    try {
        const userId = req.user?._id;

        const shift = await Shift.findByIdAndUpdate(
            req.params.id,
            { isDeleted: true, updatedBy: userId || null },
            { new: true }
        );

        if (!shift) return errorResponse(res, "Shift not found", 404);

        // Log action
        await logUserAction({
            userId,
            orgId: shift.orgId?._id || null,
            action: "DELETE",
            model: "Shift",
            details: { shiftId: shift._id },
            req,
        });

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

module.exports = {
    createShift,
    getShifts,
    getShiftById,
    updateShift,
    deleteShift,
};
