const Labour = require('../models/Labour');
const Payment = require('../models/Payment');
const WorkOrder = require('../models/WorkOrder');
const Customer = require('../models/Customer');
const LabourType = require('../models/LabourType');
const emailService = require('../utils/emailService');

// Approve labourer
exports.approveLabour = async (req, res) => {
    try {
        const labourId = req.params.id;
        const updatedLabour = await Labour.findByIdAndUpdate(
            labourId,
            { approved: true },
            { new: true }
        );

        if (!updatedLabour) {
            return res.status(404).json({ message: 'Labourer not found' });
        }

        // --- Send Approval Email ---
        try {
            await emailService.sendEmail({
                to: updatedLabour.email,
                subject: 'Your Account has been Approved!',
                html: `
                    <div style="font-family: Arial, sans-serif; line-height: 1.6;">
                        <h2>Congratulations, ${updatedLabour.name}!</h2>
                        <p>We are pleased to inform you that your account on <strong>LaborPK</strong> has been approved.</p>
                        <p>You can now log in to the app, set your availability, and start receiving job requests from customers in your area.</p>
                        <p>Welcome to the team!</p>
                        <br>
                        <p>Best regards,</p>
                        <p><strong>The LaborPK Team</strong></p>
                    </div>
                `
            });
        } catch (emailError) {
            console.error('Failed to send approval email:', emailError);
            // We will still proceed with the approval even if the email fails.
        }
        // --- End of Email Logic ---

        const io = req.app.get('io');
        io.to(`labourer_${labourId}`).emit('labourerApproved', {
            labourerId: updatedLabour._id,
            approved: updatedLabour.approved,
            message: 'Congratulations! Your profile has been approved by the admin.'
        });
        console.log(`Emitted 'labourerApproved' to labourer_${labourId}`);

        res.json({ message: 'Labour approved', labourer: updatedLabour });
    } catch (error) {
        console.error('Error approving labour:', error);
        res.status(500).json({ message: 'Failed to approve labour', error: error.message });
    }
};

// Get all customers
exports.getAllCustomers = async (req, res) => {
    try {
        const customers = await Customer.find().sort({ createdAt: -1 });
        res.json(customers);
    } catch (error) {
        console.error('Error fetching customers:', error);
        res.status(500).json({ message: 'Failed to fetch customers', error: error.message });
    }
};

// Get all labourers
exports.getAllLabours = async (req, res) => {
    try {
        const labours = await Labour.find().sort({ approved: 1, createdAt: -1 });
        res.json(labours);
    } catch (error) {
        console.error('Error fetching labours:', error);
        res.status(500).json({ message: 'Failed to fetch labours', error: error.message });
    }
};

// Get all work orders
exports.getAllWorkOrders = async (req, res) => {
    try {
        const workOrders = await WorkOrder.find()
            .populate('customerId', 'name phone')
            .populate('labourerId', 'name phone labourType')
            .sort({ createdAt: -1 });
        res.json(workOrders);
    } catch (error) {
        console.error('Error fetching work orders:', error);
        res.status(500).json({ message: 'Failed to fetch work orders', error: error.message });
    }
};

// Get all payments
exports.getAllPayments = async (req, res) => {
    try {
        const payments = await Payment.find()
            .populate('labourerId', 'name phone')
            .populate('workOrderId', 'workDescription requiredLaborType')
            .sort({ createdAt: -1 });
        res.json(payments);
    } catch (error) {
        console.error('Error fetching payments:', error);
        res.status(500).json({ message: 'Failed to fetch payments', error: error.message });
    }
};

// Get dashboard statistics
exports.getDashboardStats = async (req, res) => {
    try {
        const [customersCount, laboursCount, pendingApprovalsCount, workOrdersCount] = await Promise.all([
            Customer.countDocuments(),
            Labour.countDocuments(),
            Labour.countDocuments({ approved: false }),
            WorkOrder.countDocuments()
        ]);

        const recentWorkOrders = await WorkOrder.find()
            .sort({ createdAt: -1 })
            .limit(5)
            .populate('customerId', 'name phone');

        res.json({
            customersCount,
            laboursCount,
            pendingApprovalsCount,
            workOrdersCount,
            recentWorkOrders
        });
    } catch (error) {
        console.error('Error fetching dashboard stats:', error);
        res.status(500).json({ message: 'Failed to fetch dashboard stats', error: error.message });
    }
};

// Reject labourer
exports.rejectLabour = async (req, res) => {
    try {
        const labourId = req.params.id;
        const { reason } = req.body;

        // Step 1: Find the labourer first to get their details for the email
        const labour = await Labour.findById(labourId);
        if (!labour) {
            return res.status(404).json({ message: 'Labourer not found' });
        }

        // Step 2: Send the rejection email
        try {
            await emailService.sendEmail({
                to: labour.email,
                subject: 'An Update on Your laborPK Application',
                html: `
                    <div style="font-family: Arial, sans-serif; line-height: 1.6;">
                        <h2>Hello ${labour.name},</h2>
                        <p>Thank you for your interest in joining the laborPK platform. After a review of your application, we regret to inform you that we are unable to approve your account at this time.</p>
                        ${reason ? `<p><strong>Reason:</strong> ${reason}</p>` : '<p>If you have questions, please contact our support team.</p>'}
                        <p>We appreciate you taking the time to apply.</p>
                        <br>
                        <p>Sincerely,</p>
                        <p><strong>The LaborPK Team</strong></p>
                    </div>
                `
            });
        } catch (emailError) {
            console.error('Failed to send rejection email:', emailError);
            // We will still proceed with the rejection even if the email fails.
        }

        // Step 3: Emit the socket event
        const io = req.app.get('io');
        io.to(`labourer_${labourId}`).emit('labourerRejected', {
            labourerId: labour._id,
            message: `Your profile has been rejected by the admin. ${reason ? `Reason: ${reason}` : ''}`
        });

        // Step 4: Delete the labourer from the database
        await Labour.findByIdAndDelete(labourId);

        res.json({ message: 'Labourer rejected and removed successfully', labourerId: labour._id });
        
    } catch (error) {
        console.error('Error rejecting labour:', error);
        res.status(500).json({ message: 'Failed to reject labour', error: error.message });
    }
};

// adminController.js

exports.updatePaymentStatus = async (req, res) => {
    try {
        const { paymentId } = req.params;
        const { status } = req.body;

        if (!['pending', 'completed', 'failed'].includes(status)) {
            return res.status(400).json({ message: 'Invalid status' });
        }

        const updatedPayment = await Payment.findByIdAndUpdate(
            paymentId,
            { status },
            { new: true }
        ).populate('labourerId workOrderId');

        if (!updatedPayment) {
            return res.status(404).json({ message: 'Payment not found' });
        }

        // Notify relevant parties
        const io = req.app.get('io');
        if (updatedPayment.labourerId) {
            io.to(`labourer_${updatedPayment.labourerId._id}`).emit('paymentUpdated', {
                paymentId: updatedPayment._id,
                status: updatedPayment.status,
                amount: updatedPayment.amount
            });
        }

        res.json({ message: 'Payment status updated', payment: updatedPayment });
    } catch (error) {
        console.error('Error updating payment status:', error);
        res.status(500).json({ message: 'Failed to update payment status', error: error.message });
    }
};

exports.bulkUpdatePaymentStatus = async (req, res) => {
    try {
        const { labourerId } = req.params;
        const { status, paymentIds } = req.body;
        console.log(status)

        if (!['pending', 'completed', 'failed'].includes(status)) {
            return res.status(400).json({ message: 'Invalid status' });
        }

        // If specific payment IDs are provided, update only those
        const filter = paymentIds && paymentIds.length > 0 
            ? { _id: { $in: paymentIds }, labourerId }
            : { labourerId };

        const updateResult = await Payment.updateMany(
            filter,
            { status },
            { new: true }
        );

        if (updateResult.modifiedCount === 0) {
            return res.status(404).json({ message: 'No payments found to update' });
        }

        // Notify labourer
        const io = req.app.get('io');
        io.to(`labourer_${labourerId}`).emit('bulkPaymentsUpdated', {
            count: updateResult.modifiedCount,
            status
        });

        res.json({ 
            message: `Updated ${updateResult.modifiedCount} payments`,
            modifiedCount: updateResult.modifiedCount
        });
    } catch (error) {
        console.error('Error bulk updating payment status:', error);
        res.status(500).json({ message: 'Failed to bulk update payment status', error: error.message });
    }
};







// Get all labour types (for admin management panels)
exports.getAllLabourTypes = async (req, res) => {
    try {
        const types = await LabourType.find().sort('name');
        res.json(types);
    } catch (error) {
        console.error('Error fetching all labour types:', error);
        res.status(500).json({ message: 'Failed to fetch labour types', error: error.message });
    }
};

// Create a new labour type (Admin Only)
exports.createLabourType = async (req, res) => {
    const { name } = req.body;
    if (!name || name.trim() === '') {
        return res.status(400).json({ message: 'Labour type name is required.' });
    }

    try {
        const formattedName = name.toLowerCase().trim();
        const existingType = await LabourType.findOne({ name: formattedName });
        if (existingType) {
            return res.status(409).json({ message: 'This labour type already exists.' });
        }

        const newType = new LabourType({ name: formattedName });
        await newType.save();

        res.status(201).json({ message: 'Labour type created successfully.', labourType: newType });
    } catch (error) {
        console.error('Error creating labour type:', error);
        res.status(500).json({ message: 'Failed to create labour type.', error: error.message });
    }
};

// Delete a labour type (Admin Only)
exports.deleteLabourType = async (req, res) => {
    try {
        const { id } = req.params;
        const deletedType = await LabourType.findByIdAndDelete(id);

        if (!deletedType) {
            return res.status(404).json({ message: 'Labour type not found.' });
        }
        
        // Optional: Remove this type from any labourer who has it
        await Labour.updateMany(
            { labourType: deletedType.name },
            { $pull: { labourType: deletedType.name } }
        );

        res.json({ message: 'Labour type deleted successfully.' });
    } catch (error) {
        console.error('Error deleting labour type:', error);
        res.status(500).json({ message: 'Failed to delete labour type.', error: error.message });
    }
};
