const AmbulanceRequest = require('../models/AmbulanceRequest');
const Driver = require('../models/Driver');
const { sendPushToUser } = require('../config/push');
const { sendDeveloperNotificationEmail } = require('../config/email');

const ambulanceRequestController = {
    // Get all ambulance requests
    getAll: (req, res) => {
        AmbulanceRequest.findAll((err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            res.json(results);
        });
    },

    // Get ambulance request by ID with full details
    getById: (req, res) => {
        const requestId = req.params.id;
        AmbulanceRequest.findByIdWithDetails(requestId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (results.length === 0) {
                return res.status(404).json({ error: 'Ambulance request not found' });
            }

            const row = results[0];

            // Format response
            const response = {
                request: {
                    id: row.request_id,
                    request_by: row.request_by,
                    created_by: row.created_by,
                    is_urgent: Boolean(row.is_urgent),
                    location: row.location,
                    destination: row.destination,
                    latitude: parseFloat(row.latitude),
                    longitude: parseFloat(row.longitude),
                    destination_latitude: row.destination_latitude ? parseFloat(row.destination_latitude) : null,
                    destination_longitude: row.destination_longitude ? parseFloat(row.destination_longitude) : null,
                    status: row.request_status,
                    comment: row.comment,
                    created_at: row.request_created_at,
                    updated_at: row.request_updated_at
                },
                created_by_user: row.created_by_user_id ? {
                    id: row.created_by_user_id,
                    first_name: row.created_by_first_name,
                    last_name: row.created_by_last_name,
                    email: row.created_by_email
                } : null,
                client: {
                    user: {
                        id: row.user_id,
                        first_name: row.first_name,
                        last_name: row.last_name,
                        email: row.email,
                        role: row.role,
                        is_verified: Boolean(row.is_verified)
                    },
                    client_details: row.client_id ? {
                        id: row.client_id,
                        phone_number: row.phone_number,
                        insurance_scheme_id: row.insurance_scheme_id,
                        is_cash_client: Boolean(row.is_cash_client),
                        membership_number: row.membership_number,
                        suffix: row.suffix,
                        address: row.address,
                        date_of_birth: row.date_of_birth,
                        emergency_contact_name: row.emergency_contact_name,
                        emergency_contact_phone: row.emergency_contact_phone
                    } : null
                },
                dispatch: row.dispatch_id ? {
                    id: row.dispatch_id,
                    ambulance_id: row.ambulance_id,
                    driver_id: row.driver_id,
                    created_at: row.dispatch_created_at,
                    updated_at: row.dispatch_updated_at,
                    ambulance: {
                        id: row.ambulance_id,
                        vehicle_number: row.vehicle_number,
                        license_plate: row.license_plate,
                        model: row.ambulance_model,
                        make: row.ambulance_make,
                        status: row.ambulance_status,
                        latitude: row.ambulance_latitude ? parseFloat(row.ambulance_latitude) : null,
                        longitude: row.ambulance_longitude ? parseFloat(row.ambulance_longitude) : null
                    },
                    driver: {
                        id: row.driver_table_id,
                        user_id: row.driver_user_id,
                        license_number: row.license_number,
                        status: row.driver_status,
                        user: {
                            id: row.driver_user_id,
                            first_name: row.driver_first_name,
                            last_name: row.driver_last_name,
                            email: row.driver_email
                        }
                    }
                } : null
            };

            res.json(response);
        });
    },

    // Create new ambulance request
    create: (req, res) => {
        const { request_by, is_urgent, location, destination, latitude, longitude, destination_latitude, destination_longitude, status } = req.body;
        
        // Validate required fields
        if (!request_by || !location || !latitude || !longitude) {
            return res.status(400).json({ error: 'Missing required fields: request_by, location, latitude, and longitude are required' });
        }
        
        // Validate destination coordinates are required
        if (destination_latitude === undefined || destination_latitude === null || destination_latitude === '') {
            return res.status(400).json({ error: 'Missing required field: destination_latitude is required' });
        }
        
        if (destination_longitude === undefined || destination_longitude === null || destination_longitude === '') {
            return res.status(400).json({ error: 'Missing required field: destination_longitude is required' });
        }
        
        // Validate destination coordinates are valid numbers
        if (isNaN(parseFloat(destination_latitude)) || parseFloat(destination_latitude) < -90 || parseFloat(destination_latitude) > 90) {
            return res.status(400).json({ error: 'Invalid destination_latitude: must be a number between -90 and 90' });
        }
        
        if (isNaN(parseFloat(destination_longitude)) || parseFloat(destination_longitude) < -180 || parseFloat(destination_longitude) > 180) {
            return res.status(400).json({ error: 'Invalid destination_longitude: must be a number between -180 and 180' });
        }

        AmbulanceRequest.create({
            request_by,
            is_urgent,
            location,
            destination,
            latitude,
            longitude,
            destination_latitude: parseFloat(destination_latitude),
            destination_longitude: parseFloat(destination_longitude),
            status
        }, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            
            const requestId = results.insertId;
            const broadcast = req.broadcastNewAmbulanceRequest || (() => {});
            
            // Fetch the created request with details for broadcasting
            AmbulanceRequest.findByIdWithDetails(requestId, (fetchErr, requestResults) => {
                if (!fetchErr && requestResults.length > 0) {
                    const requestData = requestResults[0];
                    const formattedRequest = {
                        id: requestData.request_id,
                        request_by: requestData.request_by,
                        is_urgent: Boolean(requestData.is_urgent),
                        location: requestData.location,
                        destination: requestData.destination,
                        latitude: parseFloat(requestData.latitude),
                        longitude: parseFloat(requestData.longitude),
                        destination_latitude: requestData.destination_latitude ? parseFloat(requestData.destination_latitude) : null,
                        destination_longitude: requestData.destination_longitude ? parseFloat(requestData.destination_longitude) : null,
                        status: requestData.request_status,
                        created_at: requestData.request_created_at,
                        client: {
                            first_name: requestData.first_name,
                            last_name: requestData.last_name,
                            email: requestData.email
                        }
                    };
                    
                    // Broadcast via websocket to all drivers
                    broadcast(formattedRequest);
                    
                    // Send push notifications to all drivers
                    Driver.findAll((driverErr, drivers) => {
                        if (!driverErr && drivers && drivers.length > 0) {
                            const pushPromises = drivers.map((driver) => {
                                const driverUserId = driver.user_id || driver.id;
                                return sendPushToUser(driverUserId, {
                                    notification: {
                                        title: 'New Ambulance Request',
                                        body: `New request at ${formattedRequest.location}${formattedRequest.is_urgent ? ' (URGENT)' : ''}`
                                    },
                                    data: {
                                        type: 'new_ambulance_request',
                                        request_id: String(formattedRequest.id),
                                        location: formattedRequest.location
                                    }
                                });
                            });
                            Promise.all(pushPromises).catch((pushErr) => {
                                console.error('Error sending push notifications to drivers:', pushErr);
                            });
                        }
                    });
                }
            });
            
            res.status(201).json({ 
                message: 'Ambulance request created successfully', 
                id: requestId 
            });
        });
    },

    // Update ambulance request
    update: (req, res) => {
        const requestId = req.params.id;
        const { is_urgent, location, destination, latitude, longitude, destination_latitude, destination_longitude, status } = req.body;
        
        // Check if status is being updated to 'completed' to send developer notification
        const isCompleting = status && status.toLowerCase() === 'completed';
        
        // If completing, fetch the request details first for the email notification
        if (isCompleting) {
            AmbulanceRequest.findById(requestId, (err, requestResults) => {
                if (err || requestResults.length === 0) {
                    console.error('Failed to fetch request for developer notification:', err?.message);
                } else {
                    // Send developer email notification concurrently
                    sendDeveloperNotificationEmail('completed', requestResults[0]).catch(emailErr => {
                        console.error('Failed to send developer notification for completion:', emailErr.message);
                    });
                }
            });
        }
        
        AmbulanceRequest.update(requestId, {
            is_urgent,
            location,
            destination,
            latitude,
            longitude,
            destination_latitude,
            destination_longitude,
            status
        }, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (results.affectedRows === 0) {
                return res.status(200).json({ message: 'Ambulance request not found' });
            }
            res.json({ message: 'Ambulance request updated successfully' });
        });
    },

    // Delete ambulance request
    delete: (req, res) => {
        const requestId = req.params.id;
        AmbulanceRequest.delete(requestId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (results.affectedRows === 0) {
                return res.status(200).json({ message: 'Ambulance request not found' });
            }
            res.json({ message: 'Ambulance request deleted successfully' });
        });
    },

    // Get ambulance requests by user ID
    getByUserId: (req, res) => {
        const userId = req.params.id;
        AmbulanceRequest.findByUserId(userId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            res.json(results);
        });
    },

    // Get all ambulance requests with full client data
    getAllWithClients: (req, res) => {
        AmbulanceRequest.findAllWithClients((err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            
            // Transform flat data to nested structure expected by frontend
            const transformedResults = results.map(row => ({
                id: row.id,
                request_by: row.request_by,
                created_by: row.created_by,
                is_urgent: Boolean(row.is_urgent),
                location: row.location,
                destination: row.destination,
                latitude: parseFloat(row.latitude),
                longitude: parseFloat(row.longitude),
                destination_latitude: row.destination_latitude ? parseFloat(row.destination_latitude) : null,
                destination_longitude: row.destination_longitude ? parseFloat(row.destination_longitude) : null,
                status: row.status,
                comment: row.comment,
                created_at: row.created_at,
                updated_at: row.updated_at,
                client: {
                    user: {
                        id: row.user_id,
                        first_name: row.first_name,
                        last_name: row.last_name,
                        email: row.email,
                        role: row.role,
                        is_verified: Boolean(row.is_verified)
                    },
                    client_details: row.client_id ? {
                        id: row.client_id,
                        phone_number: row.phone_number,
                        insurance_scheme_id: row.insurance_scheme_id,
                        is_cash_client: Boolean(row.is_cash_client),
                        membership_number: row.membership_number,
                        suffix: row.suffix,
                        address: row.address,
                        date_of_birth: row.date_of_birth,
                        emergency_contact_name: row.emergency_contact_name,
                        emergency_contact_phone: row.emergency_contact_phone
                    } : null
                },
                created_by_user: row.created_by_first_name ? {
                    id: row.created_by,
                    first_name: row.created_by_first_name,
                    last_name: row.created_by_last_name,
                    email: row.created_by_email
                } : null
            }));
            
            res.json(transformedResults);
        });
    },

    // Get authenticated user's own ambulance requests with dispatch information
    getMyRequests: (req, res) => {
        // Get user ID from authenticated token (set by authMiddleware)
        const userId = req.user.id;
        
        if (!userId) {
            return res.status(401).json({ 
                error: 'User ID not found in token',
                message: 'Please login again to get a valid token.'
            });
        }

        AmbulanceRequest.findByUserIdWithDispatch(userId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }

            // Format the results to include dispatch information
            const formattedRequests = results.map(row => {
                const request = {
                    id: row.request_id,
                    request_by: row.request_by,
                    is_urgent: Boolean(row.is_urgent),
                    location: row.location,
                    destination: row.destination,
                    latitude: parseFloat(row.latitude),
                    longitude: parseFloat(row.longitude),
                    destination_latitude: row.destination_latitude ? parseFloat(row.destination_latitude) : null,
                    destination_longitude: row.destination_longitude ? parseFloat(row.destination_longitude) : null,
                    status: row.request_status,
                    comment: row.comment,
                    created_at: row.request_created_at,
                    updated_at: row.request_updated_at,
                    dispatch: row.dispatch_id ? {
                        id: row.dispatch_id,
                        ambulance_id: row.ambulance_id,
                        driver_id: row.driver_id,
                        created_at: row.dispatch_created_at,
                        updated_at: row.dispatch_updated_at,
                        ambulance: {
                            id: row.ambulance_id,
                            vehicle_number: row.vehicle_number,
                            license_plate: row.license_plate,
                            model: row.ambulance_model,
                            make: row.ambulance_make,
                            status: row.ambulance_status,
                            latitude: row.ambulance_latitude ? parseFloat(row.ambulance_latitude) : null,
                            longitude: row.ambulance_longitude ? parseFloat(row.ambulance_longitude) : null
                        },
                        driver: {
                            id: row.driver_table_id,
                            user_id: row.driver_user_id,
                            license_number: row.license_number,
                            status: row.driver_status,
                            user: {
                                id: row.driver_user_id,
                                first_name: row.driver_first_name,
                                last_name: row.driver_last_name,
                                email: row.driver_email
                            }
                        }
                    } : null
                };
                return request;
            });

            res.json({
                message: 'Your ambulance requests retrieved successfully',
                count: formattedRequests.length,
                requests: formattedRequests
            });
        });
    },

    // Get authenticated user's most recent pending or dispatched request with dispatch information
    getMyRecentRequest: (req, res) => {
        // Get user ID from authenticated token (set by authMiddleware)
        const userId = req.user.id;
        
        if (!userId) {
            return res.status(401).json({ 
                error: 'User ID not found in token',
                message: 'Please login again to get a valid token.'
            });
        }

        AmbulanceRequest.findRecentPendingOrDispatchedByUserId(userId, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }

            if (results.length === 0) {
                return res.status(200).json({
                    message: 'No pending or dispatched requests found',
                    request: null
                });
            }

            const row = results[0];

            // Format the result to include dispatch information
            const request = {
                id: row.request_id,
                request_by: row.request_by,
                is_urgent: Boolean(row.is_urgent),
                location: row.location,
                destination: row.destination,
                latitude: parseFloat(row.latitude),
                longitude: parseFloat(row.longitude),
                status: row.request_status,
                comment: row.comment,
                created_at: row.request_created_at,
                updated_at: row.request_updated_at,
                dispatch: row.dispatch_id ? {
                    id: row.dispatch_id,
                    ambulance_id: row.ambulance_id,
                    driver_id: row.driver_id,
                    created_at: row.dispatch_created_at,
                    updated_at: row.dispatch_updated_at,
                    ambulance: {
                        id: row.ambulance_id,
                        vehicle_number: row.vehicle_number,
                        license_plate: row.license_plate,
                        model: row.ambulance_model,
                        make: row.ambulance_make,
                        status: row.ambulance_status,
                        latitude: row.ambulance_latitude ? parseFloat(row.ambulance_latitude) : null,
                        longitude: row.ambulance_longitude ? parseFloat(row.ambulance_longitude) : null
                    },
                    driver: {
                        id: row.driver_table_id,
                        user_id: row.driver_user_id,
                        license_number: row.license_number,
                        status: row.driver_status,
                        user: {
                            id: row.driver_user_id,
                            first_name: row.driver_first_name,
                            last_name: row.driver_last_name,
                            email: row.driver_email
                        }
                    }
                } : null
            };

            res.status(200).json({
                message: 'Recent request retrieved successfully',
                request: request
            });
        });
    },

    // Cancel authenticated user's request (only if status is pending)
    cancelMyRequest: (req, res) => {
        // Get user ID from authenticated token (set by authMiddleware)
        const userId = req.user.id;
        
        if (!userId) {
            return res.status(401).json({ 
                error: 'User ID not found in token',
                message: 'Please login again to get a valid token.'
            });
        }

        const { request_id } = req.body;

        if (!request_id) {
            return res.status(400).json({ 
                error: 'Missing required field: request_id',
                message: 'Please provide the request_id in the request body.'
            });
        }

        // First, verify the request exists and belongs to the user
        AmbulanceRequest.findRequestById(request_id, (err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }

            if (results.length === 0) {
                return res.status(200).json({ 
                    message: 'Ambulance request not found'
                });
            }

            const request = results[0];

            // Verify the request belongs to the authenticated user
            if (request.request_by !== userId) {
                return res.status(403).json({ 
                    error: 'Forbidden',
                    message: 'You can only cancel your own requests.'
                });
            }

            // Check if status is pending
            if (request.status !== 'pending') {
                return res.status(400).json({ 
                    error: 'Invalid request status',
                    message: `Request can only be cancelled when status is 'pending'. Current status: '${request.status}'`
                });
            }

            // Update status to cancelled
            AmbulanceRequest.updateStatus(request_id, 'cancelled', null, (err, updateResults) => {
                if (err) {
                    return res.status(500).json({ error: err.message });
                }

                if (updateResults.affectedRows === 0) {
                    return res.status(200).json({ 
                        message: 'Request could not be updated'
                    });
                }

                res.status(200).json({
                    message: 'Request cancelled successfully',
                    request_id: request_id
                });
            });
        });
    },

    // Create new ambulance request by admin (sets created_by to admin user)
    createByAdmin: (req, res) => {
        // Get admin user ID from authenticated token
        const adminUserId = req.user.id;
        
        if (!adminUserId) {
            return res.status(401).json({ 
                error: 'User ID not found in token',
                message: 'Please login again to get a valid token.'
            });
        }

        const { request_by, is_urgent, location, destination, latitude, longitude, destination_latitude, destination_longitude, status } = req.body;
        
        // Validate required fields (request_by is now compulsory for admin-created requests)
        if (!request_by || !location || !latitude || !longitude) {
            return res.status(400).json({ error: 'Missing required fields: request_by, location, latitude, and longitude are required' });
        }
        
        // Validate destination coordinates are required
        if (destination_latitude === undefined || destination_latitude === null || destination_latitude === '') {
            return res.status(400).json({ error: 'Missing required field: destination_latitude is required' });
        }
        
        if (destination_longitude === undefined || destination_longitude === null || destination_longitude === '') {
            return res.status(400).json({ error: 'Missing required field: destination_longitude is required' });
        }
        
        // Validate destination coordinates are valid numbers
        if (isNaN(parseFloat(destination_latitude)) || parseFloat(destination_latitude) < -90 || parseFloat(destination_latitude) > 90) {
            return res.status(400).json({ error: 'Invalid destination_latitude: must be a number between -90 and 90' });
        }
        
        if (isNaN(parseFloat(destination_longitude)) || parseFloat(destination_longitude) < -180 || parseFloat(destination_longitude) > 180) {
            return res.status(400).json({ error: 'Invalid destination_longitude: must be a number between -180 and 180' });
        }

        // Validate that request_by user exists
        const User = require('../models/User');
        User.findById(request_by, (err, userResults) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            if (userResults.length === 0) {
                return res.status(404).json({ error: 'User not found', message: `User with ID ${request_by} does not exist` });
            }

            // Create request with created_by set to admin user
            AmbulanceRequest.create({
                request_by,
                created_by: adminUserId,
                is_urgent,
                location,
                destination,
                latitude,
                longitude,
                destination_latitude: parseFloat(destination_latitude),
                destination_longitude: parseFloat(destination_longitude),
                status
            }, (err, results) => {
                if (err) {
                    return res.status(500).json({ error: err.message });
                }
                
                const requestId = results.insertId;
                const broadcast = req.broadcastNewAmbulanceRequest || (() => {});
                
                // Fetch the created request with details for broadcasting
                AmbulanceRequest.findByIdWithDetails(requestId, (fetchErr, requestResults) => {
                    if (!fetchErr && requestResults.length > 0) {
                        const requestData = requestResults[0];
                        const formattedRequest = {
                            id: requestData.request_id,
                            request_by: requestData.request_by,
                            is_urgent: Boolean(requestData.is_urgent),
                            location: requestData.location,
                            destination: requestData.destination,
                            latitude: parseFloat(requestData.latitude),
                            longitude: parseFloat(requestData.longitude),
                            destination_latitude: requestData.destination_latitude ? parseFloat(requestData.destination_latitude) : null,
                            destination_longitude: requestData.destination_longitude ? parseFloat(requestData.destination_longitude) : null,
                            status: requestData.request_status,
                            created_at: requestData.request_created_at,
                            client: {
                                first_name: requestData.first_name,
                                last_name: requestData.last_name,
                                email: requestData.email
                            }
                        };
                        
                        // Broadcast via websocket to all drivers
                        broadcast(formattedRequest);
                        
                        // Send push notifications to all drivers
                        Driver.findAll((driverErr, drivers) => {
                            if (!driverErr && drivers && drivers.length > 0) {
                                const pushPromises = drivers.map((driver) => {
                                    const driverUserId = driver.user_id || driver.id;
                                    return sendPushToUser(driverUserId, {
                                        notification: {
                                            title: 'New Ambulance Request',
                                            body: `New request at ${formattedRequest.location}${formattedRequest.is_urgent ? ' (URGENT)' : ''}`
                                        },
                                        data: {
                                            type: 'new_ambulance_request',
                                            request_id: String(formattedRequest.id),
                                            location: formattedRequest.location
                                        }
                                    });
                                });
                                Promise.all(pushPromises).catch((pushErr) => {
                                    console.error('Error sending push notifications to drivers:', pushErr);
                                });
                            }
                        });
                    }
                });
                
                res.status(201).json({ 
                    message: 'Ambulance request created successfully by admin', 
                    id: requestId,
                    created_by: adminUserId,
                    request_by: request_by
                });
            });
        });
    },

    // Get all pending requests (for drivers to self-assign)
    getPendingRequests: (req, res) => {
        AmbulanceRequest.findPendingRequests((err, results) => {
            if (err) {
                return res.status(500).json({ error: err.message });
            }
            res.json(results);
        });
    }
};

module.exports = ambulanceRequestController;

