const db = require("./dbService.js");
const {
    getUserByChatTokenQuery,blockUserQuery,getJoinerDetailByID,setMuteOrUnmuteOwnerQuery,adminCheckIsMuteByOwnerQuery
    ,joinerCheckIsMuteByAdminQuery,setMuteOrUnmuteJoinerQuery,getRoomIDByUserIDQuery,createRoom,sendMessageQuery
   ,getRoomByRoomID,updateUserStatusOnline,updateUserOffileStatusbyuserID,checkRoomQuery,updateRoomStatus,chatListOnJoin,checkUserStatusInRoom,SaveMessage,
   SaveBooking,SaveDropLocation,getBookingQuery,getBookingsQuery,getDriverUpcomingBookingCount,getDropPointsQuery,getMsgList,getrecentChatList,UpdateReadStatus,
   getUserQuery,getCurrentBookingsQuery, updateBookingStatusDriver,updateBookingStatusRider,acceptBookingQuery, getUserDetailByID,getBookingDetailByID,
   cancelBookingQuery,delayBookingQuery,leaveRoomStatus,updateUserActivityQuery,getUserDetailbyIDQuery,insertNotificationQuery,getDrivers,deleteChatQuery, rejectBookingQuery} = require("./mysqlQueries.js");
   
// const {getBookingList} = require("./bookingController.js");

const {sendFcmNotification } = require("./notificationServices.js");
/**
 * @description - get crib detail by id
 */
const { JWT } = require('google-auth-library');
const { v4: uuidv4 } = require('uuid');

const promiseReponse = async(sqlQuery) => 
{
    return await new Promise((resolve, reject) => {
            db.query(sqlQuery, function (err, result) {
                if (err) return reject(err);
                resolve(result);
            });
        });
} 


/* Start chat flow */
const connectedRoomID = async (token) => 
{
    try
    {
        var rooms = [];
        var user = await getUserByChatTokenQuery(token);
        const connectUser = await promiseReponse(user);
        if(connectUser.length === 1 ) 
        {
            const row = JSON.parse(JSON.stringify(connectUser[0]));
            var room = await getRoomIDByUserIDQuery(row.id);
            const rooms = await promiseReponse(room);
            return rooms;
        }
    }
    catch(err)
    {
        return false;
    }
}
const userOnline= async (token) => 
{
    try
    {
        var userUpdate = await updateUserStatusOnline(token);
        console.log('query'+userUpdate);
        const update = await promiseReponse(userUpdate);
        
    }
    catch (error) 
    {
        console.error("Error fetching recent chat list: ", error);
        throw error;
    }
    console.log("User Online");
    return "User Online.";
}

const userOfflineStatus = async (token) => 
{
    try
    {
        var user = await getUserByChatTokenQuery(token);
        const connectUser = await promiseReponse(user);
        if(connectUser.length === 1 ) 
        {
            const row = JSON.parse(JSON.stringify(connectUser[0]));
            var sql1 = await updateUserOffileStatusbyuserID(row.id,0);
            const update1 = await promiseReponse(sql1);
            return {"status": 200,"message": "user offline successfully"};
        }
    }
    catch (err) 
    {
         console.log(err.message ,"OFFLINE USER CHECK");
        return { "status": 400,"message": err.message };
    }
}

const createOrJoinRoomService = async (request) => 
{

    try 
    {
          
        const checkSender = await checkRoomQuery(request.roomID,request.userID);
        // console.log(checkSender);
        const checkSenderResult = await promiseReponse(checkSender);
       
        if (checkSenderResult.length === 1) 
        {
           const updateRoomStatus1 = await updateRoomStatus(request.roomID,request.userID);
           await promiseReponse(updateRoomStatus1); 
            
        } else {
           
            const senderSql = await createRoom(request.roomID, request.userID);
            await promiseReponse(senderSql);
            
        }
        
         const senderSql = await chatListOnJoin(request.roomID);
         const msgList=await promiseReponse(senderSql);
         if(msgList.length === 0)
        {
            return { "status": 400,"message": "Data not found" };
        }
        else
        {
            return { data: JSON.parse(JSON.stringify(msgList)),"status": 200,"message": "Data Found"};    
        }
       
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};

const leaveRoom = async (request) => 
{

    try 
    {
          
        const checkSender = await checkRoomQuery(request.roomID,request.userID);
        const checkSenderResult = await promiseReponse(checkSender);
       
        if (checkSenderResult.length === 1) 
        {
           const updateRoomStatus1 = await leaveRoomStatus(request.roomID,request.userID);
           console.log(updateRoomStatus1);
           await promiseReponse(updateRoomStatus1); 
        return { "status": 200,"message": "User leave the room" };
            
        } else {
           
            return { "status": 400,"message": "User not exist in room" };
            
        }
        
        
       
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};



const sendMessage = async (request) => 
{
    try 
    {
        let sql = await checkUserStatusInRoom(request);
        let connectUser = await promiseReponse(sql);
        console.log(connectUser.length);
        if(connectUser.length === 3) 
        {
            request.readstatus = 1;
            let saveSql = await SaveMessage(request);
            console.log(saveSql);
            let saveData = await promiseReponse(saveSql);
            
            let getMsgQuery = await getMsgList(saveData.insertId);
            let getMsgLists = await promiseReponse(getMsgQuery);
            
            return { data: JSON.parse(JSON.stringify(getMsgLists)),"status": 200,"message": "Data Found"};    
        
        }
        else
        {
            request.readstatus = 0;
           let saveSql = await SaveMessage(request);
            console.log(saveSql);
            let saveData = await promiseReponse(saveSql);
            
            let getMsgQuery = await getMsgList(saveData.insertId);
            let getMsgLists = await promiseReponse(getMsgQuery);
            
            return { data: JSON.parse(JSON.stringify(getMsgLists)),"status": 200,"message": "Data Found"};   
        }
       /* var messageID = messageResult.insertId;
        const messageSql = await getMessageByMessageIDQuery(messageID);
        const messageData = await promiseReponse(messageSql);
        // send first time notifiation
        var userDetailQuery = await getUserDetailbyIDQuery(request.senderID);
        const userDetailData = await promiseReponse(userDetailQuery);
        const user = JSON.parse(JSON.stringify(userDetailData[0]));
        const username = user.firstName+" "+user.lastName;
        const checkIsFirstMessageSql = await checkIsFirstMessageOfSender(request.senderID, request.receiverID);
        const messagesCountResult = await promiseReponse(checkIsFirstMessageSql);
        const messageCount = messagesCountResult[0].total;
        if(messageCount === 1)
        {
            console.log('addNotficationFun');
            const checkNotification = await addNotficationFun(request.senderID,request.receiverID,'sendMessage',username,'',1,5,'messageID',messageID);   
        }
        else {
            var roomsql = await getRoomByRoomID(request.roomID);
            var roomData = await promiseReponse(roomsql);
            const roomrow = JSON.parse(JSON.stringify(roomData[0]));
            console.log(roomrow,'ROOM STATUS');
            if(roomrow.receiverStatus === 0) 
            {
                const checkNotification = await directNotification(request.senderID,request.receiverID,'sendMessage',request.message,username,request.senderID);    
            }
            if(roomrow.senderStatus === 0) 
            {
                const checkNotification = await directNotification(request.senderID,request.receiverID,'sendMessage',request.message,username,request.senderID);    
            }
        }
       
        return { data:messageData[0],"status": 200,"message": "Data Found"};*/
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};

const readMsg = async (request) => 
{
    try 
    {
        
            const saveSql = await UpdateReadStatus(request);
            console.log(saveSql,"updateReadQuery");
            const saveData = await promiseReponse(saveSql);
            console.log(saveData);
            
      
      
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};

const getUserDetails = async (request) => 
{
    try 
    {
        
            const saveSql = await getUserQuery(request);
            console.log(saveSql,"updateReadQuery");
            const saveData = await promiseReponse(saveSql);
            console.log(saveData);
            
      
      
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};

const recentchatList = async (request) => 
{
    try 
    {
        if(request.receiverID)
        {
           request.userID = request.receiverID; 
        }
         let getRecentChatQuery = await getrecentChatList(request);
         console.log(getRecentChatQuery);
         let getRecentChatLists = await promiseReponse(getRecentChatQuery);
        
        if(getRecentChatLists.length > 0 ) 
        {
            
            console.log("Sdfs");
            // Fetch drop-off points for all booking IDs
            let bookingIDs = getRecentChatLists.map(chat => chat.bookingID);
            let dropPointsData = await promiseReponse(await getDropPointsQuery(bookingIDs));
            
            // Fetch booking details for all booking IDs
            let bookingsData = await Promise.all(
                bookingIDs.map(async (bookingID) => {
                    const getLastInsertedSql = await getBookingQuery(bookingID);
                    const bookingDetail = await promiseReponse(getLastInsertedSql);
                    return bookingDetail.length ? bookingDetail[0] : null; // Return the first booking if found
                })
            );
            console.log(bookingsData);
            
            // Map recent chats with booking details and drop points
            let updatedChatLists = getRecentChatLists.map(chat => {
                // Find the related booking detail for the chat's booking ID
                let relatedBooking = bookingsData.find(booking => booking && booking.id === chat.bookingID);
            
                // Find related drop points for the chat's booking ID
                let relatedDropPoints = dropPointsData.filter(dp => dp.booking_id === chat.bookingID);
            
                // Combine chat, booking details, and drop points
                return {
                    ...chat,
                    booking: relatedBooking || null,
                    drop_points: relatedDropPoints
                };
            });

           
    //          // Fetch drop-off points
    //     let dropPointsData = await promiseReponse(await getDropPointsQuery(getRecentChatLists.map(chat => chat.bookingID)));
           
    //         let updatedChatLists = getRecentChatLists.map(chat => {
    //     // Find related drop points for each chat/booking using booking_id from getRecentChatLists
    //     let relatedDropPoints = dropPointsData.filter(dp => dp.booking_id === chat.bookingID);
      
    //     // Return the chat with drop points as a new parameter
    //     return { 
    //         ...chat, 
    //         drop_points: relatedDropPoints 
    //     };
    // });
             
            return { data: JSON.parse(JSON.stringify(updatedChatLists)),"status": 200,"message": "Data Found"};    
        
        }
        else
        {
           return { "status": 400,"message": "Data Not Found"};  
        }
       
   
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};



const createdBookingPaymentService = async (request) => 
{
    try 
    {
            //small booking id 
            const bookingId = request.booking_id;
            
            const getLastInsertedSql = await getBookingQuery(bookingId);
            const savedBookingDetail = await promiseReponse(getLastInsertedSql);
           
            console.log(savedBookingDetail[0],"1");
            console.log(savedBookingDetail[0].is_paid,"2");
           
             const isPaid = savedBookingDetail[0].is_paid;
            //  const isPaid1 = parseInt(savedBookingDetail[0].is_paid);
             console.log(isPaid);
             
            if(isPaid == "0")
            {
                  return { data: [],"status": 400,"message": "Payment not done"};   
                
            }
            
            
            const bookingIds = savedBookingDetail.map(booking => bookingId);

        // Fetch drop-off points
        const getDropPointsSql = await getDropPointsQuery(bookingIds);
        const dropPointsData = await promiseReponse(getDropPointsSql);
        
        
        // Combine bookings with their related drop-off points
        const result = savedBookingDetail.map(booking => {
            const relatedDropPoints = dropPointsData.filter(dp => dp.booking_id === booking.id);
            return { ...booking, drop_points: relatedDropPoints };
        });
        
        console.log(savedBookingDetail, "saved booking");
        const pickupLocation = savedBookingDetail[0].pickup_location; 
        const riderId = savedBookingDetail[0].rider_id; 
        const dropLocation = dropPointsData[0].drop_location; 
        
         const title = 'Booking Confirmation';
         const message = `Your ride from  ${pickupLocation} to ${dropLocation} is confirmed.`;
         await sendNotification({
            senderId: riderId,
            receiverId: riderId,
            bookingId: bookingId,
            title,
            message,
            saveToDb: true,
            sendToFcm: true,
        });
        
        // Get all active drivers
        const getDriversSql = await getDrivers();
        console.log(getDriversSql);
        const allActivedrivers = await promiseReponse(getDriversSql); // Ensure this returns an array of active drivers
        console.log(allActivedrivers);
        // Notification details
        const driversTitle = 'New Ride Request';
        const driversMessage = `You have a new ride request from ${pickupLocation} to ${dropLocation}`;
        
        // Loop through each active driver and send notifications
        for (const driver of allActivedrivers) {
            await sendNotification({
                senderId: request.rider_id, 
                receiverId: driver.id, 
                bookingId: bookingId, 
                title: driversTitle,
                message: driversMessage, 
                saveToDb: true, 
                sendToFcm: true,
            });
        }


        return { data: result,"status": 200,"message": "Data Found"};   
     
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};





const scheduleBookingService = async (request) => 
{
    try 
    {
            const saveSql = await SaveBooking(request);
            const saveBookingData = await promiseReponse(saveSql);
            
             // Extract the booking_id from the insert response
            const bookingID = saveBookingData.insertId;
    
            // Step 2: Save the drop locations
            if (request.drop_locations && Array.isArray(request.drop_locations)) {
                const dropLocationsQueries = await SaveDropLocation(bookingID, request.drop_locations);
    
                // Loop through each query and execute it sequentially
                for (const query of dropLocationsQueries) {
                    // console.log(query, "Executing Drop Location Query");
                    await promiseReponse(query); // Use the existing promiseReponse function
                }
                console.log("droplocation saved.")
            }
            
             // Fetch dynamic fares
            const fares = await fetchFares();
            console.log(fares,"fares");
            // Calculate fare
            const fareData = fareCalculation({ drop_points: request.drop_locations }, fares);
            
            console.log(fareData);
                // Update booking with fare details
            const updateBookingSql = `
                UPDATE bookings
                SET 
                    total_fare = ${fareData.totalFee},
                    base_fare = ${fareData.baseFare},
                    platform_fee = ${fareData.platformFee},
                    driver_fee = ${fareData.driverFee},
                    additional_stop_count = ${fareData.additionalStops},
                    additional_stop_fee = ${fareData.additionalStopsFee}
                WHERE id = ${bookingID}
            `;
            await promiseReponse(updateBookingSql);
    
            // Save booking charge
            const chargesSql = `
                INSERT INTO booking_charges 
                    (booking_id, user_id, user_type, amount,platform_fee, charge_type, reason) 
                VALUES 
                    (${bookingID}, ${request.rider_id}, 1, ${fareData.baseFare},${fares.booking_fee_cut}, 'debit', 'booking_fee')`;
            await promiseReponse(chargesSql);
            
                if(fareData.additionalStops > 0){
                    const additionalStopFeeCut = fareData.additionalStops * fares.additional_stop_fee_cut;
                    
                     // Save additional stops charge
                    const additionalChargesSql = `
                        INSERT INTO booking_charges 
                            (booking_id, user_id, user_type, amount,platform_fee, charge_type, reason) 
                        VALUES 
                            (${bookingID}, ${request.rider_id}, 1, ${fareData.additionalStopsFee},${additionalStopFeeCut}, 'debit', 'additional_stop_fee')`;
                    await promiseReponse(additionalChargesSql);
                }
            
            
            const getLastInsertedSql = await getBookingQuery(bookingID);
            const savedBookingDetail = await promiseReponse(getLastInsertedSql);
            
            
            const bookingIds = savedBookingDetail.map(booking => bookingID);

        // Fetch drop-off points
        const getDropPointsSql = await getDropPointsQuery(bookingIds);
        const dropPointsData = await promiseReponse(getDropPointsSql);
        
        
        // Combine bookings with their related drop-off points
        const result = savedBookingDetail.map(booking => {
            const relatedDropPoints = dropPointsData.filter(dp => dp.booking_id === booking.id);
            return { ...booking, drop_points: relatedDropPoints };
        });
        
        console.log(savedBookingDetail, "saved booking");
        // const pickupLocation = savedBookingDetail[0].pickup_location; 
        // const dropLocation = dropPointsData[0].drop_location; 
        
        //  const title = 'Booking Confirmation';
        //  const message = `Your ride from  ${pickupLocation} to ${dropLocation} is confirmed.`;
        //  await sendNotification({
        //     senderId: request.rider_id,
        //     receiverId: request.rider_id,
        //     bookingId: bookingID,
        //     title,
        //     message,
        //     saveToDb: true,
        //     sendToFcm: true,
        // });
        
        // // Get all active drivers
        // const getDriversSql = await getDrivers();
        // console.log(getDriversSql);
        // const allActivedrivers = await promiseReponse(getDriversSql); // Ensure this returns an array of active drivers
        // console.log(allActivedrivers);
        // // Notification details
        // const driversTitle = 'New Ride Request';
        // const driversMessage = `You have a new ride request from ${pickupLocation} to ${dropLocation}`;
        
        // // Loop through each active driver and send notifications
        // for (const driver of allActivedrivers) {
        //     await sendNotification({
        //         senderId: request.rider_id, 
        //         receiverId: driver.id, 
        //         bookingId: bookingID, 
        //         title: driversTitle,
        //         message: driversMessage, 
        //         saveToDb: true, 
        //         sendToFcm: true,
        //     });
        // }


        return { data: result,"status": 200,"message": "Data Found"};   
     
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};




const fetchFares = async () => {
    const sql = `SELECT fee_name, fee_price FROM booking_fees`;
    const results = await promiseReponse(sql);

    return results.reduce((fares, fee) => {
        fares[fee.fee_name] = parseFloat(fee.fee_price);
        return fares;
    }, {});
};


const fareCalculation = (data, fares) => {
    try {
        let totalFee = 0.0;
        let additionalStopFeeCut = 0.0;
        let additionalStopFee = 0.0;

        // Base fares
        const bookingFeeCut = fares.booking_fee_cut;
        const bookingFee = fares.booking_fee;
        
        totalFee += bookingFee;

        // Additional stop fee calculation
        const stops = data.drop_points ? data.drop_points.length - 1 : 0;
        stopsFee = 0;
        // console.log(stops);
        if (stops > 0) {
            additionalStopFee = fares.additional_stop_fee;
            
            stopsFee = stops * additionalStopFee;
            
            totalFee += stopsFee;
            
            additionalStopFeeCut += stops * fares.additional_stop_fee_cut;
        }

        const platformFee = bookingFeeCut + additionalStopFeeCut;
        
        const driverFee = totalFee - platformFee;
        
        return {
            baseFare: bookingFee,
            platformFee,
            driverFee,
            totalFee,
            additionalStops: stops,
            additionalStopsFee: stopsFee,
        };
    } catch (err) {
        console.error('Error in fare calculation:', err.message);
        throw new Error('Fare calculation failed.');
    }
};



const updateBookingStatusService = async (request) => {
    try {
        console.log(request , "update booking service");
        
          // Fetch booking details
        const bookingID = request.booking_id;
        const getBookingDetailSql = await getBookingQuery(bookingID);
        const savedBookingDetail = await promiseReponse(getBookingDetailSql);

        // Check if booking data is found
        if (!savedBookingDetail.length) {
            return { 
                data: null, status: 404, message: "Booking not found" };
        }
        
        const bookingPickupDate = savedBookingDetail[0].pickup_date; // YYYY-MM-DD format
        const bookingPickupTime = savedBookingDetail[0].pickup_time; // HH:MM:SS format
        const isDelayed = savedBookingDetail[0].is_delayed;
        const bookingDelayTime = savedBookingDetail[0].delay_time; // Delay time (HH:MM:SS format)
        
        const fares = await fetchFares();
        
        function createDateTime(date, time) {
            return new Date(`${date}T${time}`);
        }
        
        function calculateLateCharges(reachedTime, referenceTime, graceTime, latePeriod, lateFee) {
            const reachedDateTime = createDateTime(bookingPickupDate, reachedTime);
            const referenceDateTime = createDateTime(bookingPickupDate, referenceTime);
        
            // Calculate difference in minutes
            const differenceTimeInMinutes = Math.floor((reachedDateTime - referenceDateTime) / 60000);
        
            if (differenceTimeInMinutes > graceTime) {
                const lateTime = differenceTimeInMinutes - graceTime;
                const lateCount = Math.ceil(lateTime / latePeriod); // Number of periods
                return lateCount * lateFee;
            }
        
            return 0; // No charge if within grace time
        }
        
        // Handle user type: driver
        if (request.user_type == 2) {
            if (request.status === "2") {
                const reachedTime = request.reached_time;
        
                const getSettingsSql = `SELECT * FROM booking_settings`;
                const bookingSettings = await promiseReponse(getSettingsSql);
                const driverLateGraceTime = bookingSettings.length ? bookingSettings[0].driver_late_grace : 5;
                const driverLatePeriod = bookingSettings.length ? bookingSettings[0].driver_late_period : 15;
        
                let lateCharges = 0;
        
                if (isDelayed == 1) {
                    lateCharges = calculateLateCharges(reachedTime, bookingDelayTime, driverLateGraceTime, driverLatePeriod, fares.driver_late_fee);
                } else {
                    lateCharges = calculateLateCharges(reachedTime, bookingPickupTime, driverLateGraceTime, driverLatePeriod, fares.driver_late_fee);
                }
        
                console.log(`Driver Late Charges: $${lateCharges}`);
            }
        
            const updateBookingStatusDriverSql = await updateBookingStatusDriver(request);
            const updateStatusUserData = await promiseReponse(updateBookingStatusDriverSql);
            console.log(updateStatusUserData, "Driver query response");
        }
        
        // Handle user type: rider
        if (request.user_type == 1) {
            if (request.status === "1") {
                const reachedTime = request.reached_time;
        
                const getSettingsSql = `SELECT * FROM booking_settings`;
                const bookingSettings = await promiseReponse(getSettingsSql);
                const riderLateGraceTime = bookingSettings.length ? bookingSettings[0].rider_late_grace : 10;
                const riderLatePeriod = bookingSettings.length ? bookingSettings[0].rider_late_period : 30;
        
                let lateCharges = 0;
        
                if (isDelayed == 1) {
                    lateCharges = calculateLateCharges(reachedTime, bookingDelayTime, riderLateGraceTime, riderLatePeriod, fares.rider_late_fee);
                } else {
                    lateCharges = calculateLateCharges(reachedTime, bookingPickupTime, riderLateGraceTime, riderLatePeriod, fares.rider_late_fee);
                }
        
                console.log(`Rider Late Charges: $${lateCharges}`);
            }
        
            const updateBookingStatusRiderSql = await updateBookingStatusRider(request);
            const updateStatusUserData = await promiseReponse(updateBookingStatusRiderSql);
            console.log(updateStatusUserData, "Rider query response");
        }


      
        

        // Extract driver and rider details
        const driverID = savedBookingDetail[0].driver_id;
        const riderID = savedBookingDetail[0].rider_id;
        
     

        const getDriverDetailSql = await getUserDetailByID(driverID);
        const driverData = await promiseReponse(getDriverDetailSql);

        const getRiderDetailSql = await getUserDetailByID(riderID);
        const riderData = await promiseReponse(getRiderDetailSql);

        // Fetch drop-off points
        const bookingIds = savedBookingDetail.map((booking) => booking.id);
        const getDropPointsSql = await getDropPointsQuery(bookingIds);
        const dropPointsData = await promiseReponse(getDropPointsSql);

        // Combine booking with its related drop-off points, driver, and rider details
        const booking = savedBookingDetail[0];
        const relatedDropPoints = dropPointsData.filter((dp) => dp.booking_id === booking.id);
        
        const pickupLocation = booking.pickup_location;
        const dropLocation = relatedDropPoints[0].drop_location;
        
           //send notification when ride is completed  
        if(savedBookingDetail[0].status == 3){
             const title = 'Booking Completed';
             const message = `Your ride from  ${pickupLocation} to ${dropLocation} is completed.`;
             //send notification to rider
             await sendNotification({
                senderId: driverID,
                receiverId: riderID,
                bookingId: bookingID,
                title,
                message,
                saveToDb: true,
                sendToFcm: true,
            });
            
            //send notification to driver
             await sendNotification({
                senderId: driverID,
                receiverId: driverID,
                bookingId: bookingID,
                title,
                message,
                saveToDb: true,
                sendToFcm: true,
            });
        
        }
        const result = {
            ...booking,
            drop_points: relatedDropPoints,
            driver: driverData[0] || null, // Include driver details
            rider: riderData[0] || null,   // Include rider details
        };

        return { data: result, status: 200, message: "Data Found" };
    } catch (err) {
        console.error(err.message);
        return { status: 400, message: err.message };
    }
};



const acceptBookingService = async (request) => {
    try {
         // Extract driver and rider details
        const driverID = request.driver_id;
        const riderID = request.rider_id;
        
        const sameRoomBookingSql = `
            SELECT COUNT(*) AS bookingCount 
            FROM bookings
            WHERE driver_id = ${driverID} AND rider_id = ${riderID}`;
        const sameRoomBookingCount = await promiseReponse(sameRoomBookingSql);

          console.log(sameRoomBookingCount);
          if (sameRoomBookingCount.length > 0 && sameRoomBookingCount[0].bookingCount >= 1) {
                // Remove old chat
                const roomID = `${request.driver_id}-${request.rider_id}`;
                console.log(roomID, "room ID");
            
                const deleteChatQuerySql = await deleteChatQuery(roomID);
                await promiseReponse(deleteChatQuerySql);
            }
            
            const alreadyAcceptedBookingSql = `
            SELECT COUNT(*) AS acceptedBookingCount 
            FROM bookings
            WHERE driver_id = ${driverID} AND status = 1`;
            const alreadyAcceptedBooking = await promiseReponse(alreadyAcceptedBookingSql);
            
            //show alert if they have already have one accepted booking 
            if(alreadyAcceptedBooking.length > 0 && alreadyAcceptedBooking[0].acceptedBookingCount > 0){
                return {status: 200, message: "You have already accepted one booking." }; 
            }
            
        // Update the booking record for driver accepting the ride
        const acceptBookingSql = await acceptBookingQuery(request);
        await promiseReponse(acceptBookingSql);

        // Get the updated booking
        const bookingID = request.booking_id;
        const getBookingDetail = await getBookingQuery(bookingID);
        const savedBookingDetail = await promiseReponse(getBookingDetail);

        if (!savedBookingDetail.length) {
            return { data: null, status: 404, message: "Booking not found" };
        }

        const bookingData = savedBookingDetail[0]; // Single booking detail

        // Fetch drop-off points
        const getDropPointsSql = await getDropPointsQuery([bookingData.id]);
        const dropPointsData = await promiseReponse(getDropPointsSql);

        // Add drop-off points to the booking
        bookingData.drop_points = dropPointsData.filter(dp => dp.booking_id === bookingData.id);

       
        console.log(driverID,riderID,"rider driver id");
        const bookingId = bookingData.id;

        const getDriverDetailSql = await getUserDetailByID(driverID);
        const driverData = await promiseReponse(getDriverDetailSql);

        const getRiderDetailSql = await getUserDetailByID(riderID);
        const riderData = await promiseReponse(getRiderDetailSql);

        // Add driver and rider details to the booking
        bookingData.driver = driverData[0] || null;
        bookingData.rider = riderData[0] || null;
        
        console.log(bookingData)
        
        const pickupLocation = savedBookingDetail[0].pickup_location; 
        const dropLocation = dropPointsData[0].drop_location; 
        
        //send Notificaton To Rider 
         const title = 'Ride Accepted';
         const message = `Your ride from  ${pickupLocation} to ${dropLocation} is accepted.`;
         await sendNotification({
            senderId: driverID,
            receiverId: riderID,
            bookingId: bookingId,
            title,
            message,
            saveToDb: true,
            sendToFcm: true,
        });

        console.log(bookingData, "accept booking");

        return { data: bookingData, status: 200, message: "Data Found" };
    } catch (err) {
        console.error(err.message, "Error in acceptBookingService");
        return { status: 400, message: err.message };
    }
};



const delayBookingService = async (request) => 
{
    try 
    {
        console.log(request,"2");
        const bookingID = request.booking_id;
        const getDelayTimeSql = `SELECT rider_delay_time FROM booking_settings LIMIT 1`;
        const delayTimeData = await promiseReponse(getDelayTimeSql);
        const delayTime = delayTimeData.length ? delayTimeData[0].rider_delay_time : 30; 
        request.delayTime = delayTime;
        const fares = await fetchFares();
          
          const riderDelayFee = fares.rider_delay_fee;
          const riderDelayFeeCut = fares.rider_delay_fee_cut;
          request.delayFee = riderDelayFee;
    
    
            //update the booking record for driver accepted the ride 
            const delayBookingSql = await delayBookingQuery(request);
            const delayBookingData = await promiseReponse(delayBookingSql);
            
           
              // Save delay booking charge
            const chargesSql = `
                INSERT INTO booking_charges 
                    (booking_id, user_id, user_type, amount,platform_fee,charge_type, reason) 
                VALUES 
                    (${bookingID}, ${request.rider_id}, 1, ${riderDelayFee},${riderDelayFeeCut},'debit', 'delay_fee')`;
            await promiseReponse(chargesSql);
            
        // Fetch booking details
       
        const getBookingDetailSql = await getBookingQuery(bookingID);
        const savedBookingDetail = await promiseReponse(getBookingDetailSql);

        // Check if booking data is found
        if (!savedBookingDetail.length) {
            return { data: null, status: 404, message: "Booking not found" };
        }

        // Extract driver and rider details
        const driverID = savedBookingDetail[0].driver_id;
        const riderID = savedBookingDetail[0].rider_id;

        const getDriverDetailSql = await getUserDetailByID(driverID);
        const driverData = await promiseReponse(getDriverDetailSql);

        const getRiderDetailSql = await getUserDetailByID(riderID);
        const riderData = await promiseReponse(getRiderDetailSql);

        // Fetch drop-off points
        const bookingIds = savedBookingDetail.map((booking) => booking.id);
        const getDropPointsSql = await getDropPointsQuery(bookingIds);
        const dropPointsData = await promiseReponse(getDropPointsSql);

        // Combine booking with its related drop-off points, driver, and rider details
        const booking = savedBookingDetail[0];
        const rideDelayTimeCount = booking.rider_delay_time;
        const relatedDropPoints = dropPointsData.filter((dp) => dp.booking_id === booking.id);
        const pickupLocation = booking.pickup_location;
        const dropLocation = relatedDropPoints.drop_location;
        const result = {
            ...booking,
            drop_points: relatedDropPoints,
            driver: driverData[0] || null, // Include driver details
            rider: riderData[0] || null,   // Include rider details
        };
        
        const title = 'Ride Delayed';
        const message = `You have delayed your ride for ${rideDelayTimeCount} Minutes.`;
        
        try {
            await sendNotification({
                senderId: riderID,
                receiverId: riderID,
                bookingId: booking.id,
                title,
                message,
                saveToDb: true,
                sendToFcm: true,
            });
        } catch (error) {
            console.error('Error sending notification to the rider:', error);
        }
        
        const driverTitle = 'Ride Delayed';
        const driverMessage = `The ride from ${pickupLocation} to ${dropLocation} has been delayed by the user for ${rideDelayTimeCount} Minutes.`;
        
        try {
            await sendNotification({
                senderId: riderID,
                receiverId: driverID,
                bookingId: booking.id,
                title: driverTitle,
                message: driverMessage,
                saveToDb: true,
                sendToFcm: true,
            });
        } catch (error) {
            console.error('Error sending notification to the driver:', error);
        }

        
        // console.log(delayBookingData, "delay booking service");
        

            

        return { data: result ,"status": 200,"message": "Data Found"};   
     
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};


const cancelBookingService = async (request) => 
{
    try 
    {
        // Fetch booking details
        const bookingId = request.booking_id;
        const getBookingDetailSql = await getBookingQuery(bookingId);
        const savedBookingDetail = await promiseReponse(getBookingDetailSql);
        
        // Check if booking data is found
        if (!savedBookingDetail.length) {
            return { data: null, status: 404, message: "Booking not found" };
        }
        
        // Extract driver and rider details
        const driverID = savedBookingDetail[0].driver_id;
        const riderID = savedBookingDetail[0].rider_id;
        const bookingID = savedBookingDetail[0].booking_id;
        const bookingStatus = savedBookingDetail[0].status;
        //included additional stop fee
        const bookingFee = parseFloat(savedBookingDetail[0].total_fare) || 0;
        // const delayFee = parseFloat(savedBookingDetail[0].rider_delay_fee) || 0;
        
        console.log(bookingFee, "booking fee");
        // console.log(delayFee, "delay fee");
        // const totalBookingFee = bookingFee + delayFee;
        
        // console.log(totalBookingFee, "total booking fee");
        
        
        // Fetch fares
        const fares = await fetchFares();
        const cancelationFee = parseFloat(fares.cancelation_fee) || 0; // Default to 0 if undefined
      
        console.log(cancelationFee, "cancel fee");
        // console.log(bookingCancelationFeeCut, "cancel fee cut");
        
        let finalCancelationFee = 0;
        let bookingCancelationFeeCut = 0 ;
        
        //amount to charge from rider from booking fee to give partial refund
        let cancelBookingFee = 0 ;
         
         //cancelation charges will be only on the ride is accpted
        if(bookingStatus == 1){
            
            console.log("in booking status 1");
            
            finalCancelationFee = cancelationFee;
            
            // cancelBookingFee = bookingFee - cancelationFee;
             
             bookingCancelationFeeCut = parseFloat(fares.booking_cancelation_fee_cut) || 0;
        }
        
        // console.log(finalCancelationFee)
        
        // Convert `created_at` and `pickup_date + pickup_time` to Date objects in UTC
        // const bookingCreatedTime = new Date(savedBookingDetail[0]?.created_at); // Assume `created_at` is in UTC
        // console.log("Created Date:", bookingCreatedTime);
            // // Extract pickupDate and pickupTime
            // const pickupDate = savedBookingDetail[0]?.pickup_date; 
            // const pickupTime = savedBookingDetail[0]?.pickup_time; 
            
            // // Parse pickupDate and format it to YYYY-MM-DD
            // const parsedDate = new Date(pickupDate); 
            
            // const formattedDate = parsedDate.toISOString().split('T')[0]; // Extract YYYY-MM-DD
            // console.log("Formatted Date:", formattedDate);
            
            // const pickupDateTimeString = `${formattedDate}T${pickupTime}Z`; // Combine
            // console.log("Combined DateTime String:", pickupDateTimeString);
            
            // // Parse the combined string into a Date object
            // const bookingPickupDateTime = new Date(pickupDateTimeString);
        //  console.log(bookingPickupDateTime, "pickup time ");
        
        // Get rider cancellation period (default to 90 minutes if not provided)
        // const getCancelationPeriodSql = `SELECT rider_cancelation_period FROM booking_settings`;
        // const getCancelationPeriod = await promiseReponse(getCancelationPeriodSql);
        // const riderCancelationPeriod = parseInt(getCancelationPeriod?.[0]?.rider_cancelation_period, 10) || 90; // Default to 90 minutes
        
        // Calculate time difference in minutes
        // const timeDifference = bookingPickupDateTime - bookingCreatedTime; // Convert milliseconds to minutes
        // const timeDifferenceInMinute = timeDifference / (1000 * 60);
        // console.log(timeDifferenceInMinute, "time diffrence in min");
        // const currentUtcTime = new Date();
        
        // console.log(timeDifference, "difference time ");
        //  console.log(currentUtcTime, "current  time ");
        // // Initialize cancellation fee
        // let finalCancelationFee = 0;
        
        // Check if the time difference is less than the cancellation period
        // if (timeDifference < riderCancelationPeriod) {
        //     console.log("No booking fee will be charged.booking time is less than 90 min.");
        //     finalCancelationFee = 0;
        // } else {
        //     console.log("Booking fee scenario.");
        //     // Check if the current UTC time is within 90 minutes of the booking creation time
        //     const currentToCreatedDiff = (bookingPickupDateTime - currentUtcTime) / (1000 * 60); // Difference in minutes
        
        //     if (currentToCreatedDiff < 90) {
        //         console.log("Booking fee will be charged.");
        //         finalCancelationFee = cancelationFee;
        //     } else {
        //         console.log("No booking fee charged as current time exceeds 90 minutes.");
        //         finalCancelationFee = 0;                                                            
        //     }
        // }
        
        // console.log(finalCancelationFee, "final fare");
        
        
                
        request.cancelationFee = finalCancelationFee;
        request.cancelationFeeCut = bookingCancelationFeeCut;
        // Calculate refund amount
        // const refundAmount = totalBookingFee - finalCancelationFee;
        // if (refundAmount > 0) {
        //     console.log(`Refund amount: ${refundAmount}`);
        // } else {
        //     console.log("No refund available.");
        // }
        
        // Cancel ride
        const cancelBookingSql = await cancelBookingQuery(request);
        const cancelBookingData = await promiseReponse(cancelBookingSql);
        
        // Save cancellation charge
        const chargesSql = `
            INSERT INTO booking_charges 
                (booking_id, user_id, user_type, amount, platform_fee, charge_type, reason) 
            VALUES 
                (${bookingId}, ${riderID}, 1, ${finalCancelationFee}, ${bookingCancelationFeeCut}, 'debit', 'cancelation_fee')`;
        await promiseReponse(chargesSql);

        const getDriverDetailSql = await getUserDetailByID(driverID);
        const driverData = await promiseReponse(getDriverDetailSql);

        const getRiderDetailSql = await getUserDetailByID(riderID);
        const riderData = await promiseReponse(getRiderDetailSql);

        // Fetch drop-off points
        const bookingIds = savedBookingDetail.map((booking) => booking.id);
        const getDropPointsSql = await getDropPointsQuery(bookingIds);
        const dropPointsData = await promiseReponse(getDropPointsSql);

        // Combine booking with its related drop-off points, driver, and rider details
        const booking = savedBookingDetail[0];
        const relatedDropPoints = dropPointsData.filter((dp) => dp.booking_id === booking.id);
        const result = {
            ...booking,
            drop_points: relatedDropPoints,
            driver: driverData[0] || null, // Include driver details
            rider: riderData[0] || null,   // Include rider details
            cancelation_fee: finalCancelationFee,
        };
           
        const pickupLocation = savedBookingDetail[0].pickup_location; 
        const dropLocation = dropPointsData[0].drop_location; 
        // console.log(pickupLocation,dropLocation )
        
        await sendNotification({
            senderId: riderID,
            receiverId: riderID,
            bookingId: bookingId,
            title: 'Ride Cancellation',
            message: 'Your ride has been cancelled.',
            saveToDb: true,
            sendToFcm: true,
        });
                 
                 //send notification only when driver accepted the ride  
               if(driverID !== null) {
                    const title = 'Ride Cancelled by User';
                    const message = `The ride from ${pickupLocation} to ${dropLocation} has been cancelled by the user.`;
                    await sendNotification({
                        senderId: riderID,
                        receiverId: driverID,
                        bookingId: bookingId,
                        title,
                        message,
                        saveToDb: true,
                        sendToFcm: true,
                    }); 
               }
          

        return { data: result ,"status": 200,"message": "Data Found"};   
     
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};

const rejectBookingService = async (request) => 
{
    try 
    {
        //reject ride
        const rejectBookingSql = await rejectBookingQuery(request);
        const cancelBookingData = await promiseReponse(rejectBookingSql);
            

        return { data: [] ,"status": 200,"message": "Data Found"};   
     
    } catch (err) {
        console.log(err.message);
        return { "status": 400,"message": err.message };
    }
};

const getBookingList = async (request) => 
{
    
    const getBookingsSql = await getBookingsQuery(request.driver_id);
    const bookingsData = await promiseReponse(getBookingsSql);
    
    console.log(bookingsData);
    
    if (!bookingsData.length) {
         return { 
            data: {
                available_bookings: [], 
                upcoming_trip_count: 0
            }, 
            status: 404, 
            message: "No Data Found" 
        };
    }
    
     const updateUserActivitySql = await updateUserActivityQuery(request.driver_id);
     const updateUserActivityData = await promiseReponse(updateUserActivitySql);
    
    // Extract booking IDs
    const bookingIds = bookingsData.map(booking => booking.id);
    
    // Fetch drop-off points
    const getDropPointsSql = await getDropPointsQuery(bookingIds);
    const dropPointsData = await promiseReponse(getDropPointsSql);
    
    // Add driver and rider details
    const availableBookings = [];
    // Loop through bookings to fetch details
    for (const booking of bookingsData) {
        const riderID = booking.rider_id;
    
        // Fetch rider details (always required)
        const getRiderDetailSql = await getUserDetailByID(riderID);
        const riderData = await promiseReponse(getRiderDetailSql);
    
        let driverData = null; // Default driver data to null
        if (booking.rider_id !== null) {
            const driverID = booking.driver_id;
    
            // Fetch driver details if rider_id is not null
            const getDriverDetailSql = await getUserDetailByID(driverID);
            driverData = await promiseReponse(getDriverDetailSql);
        }
    
        // Combine booking, drop-off points, and user details
        const relatedDropPoints = dropPointsData.filter(dp => dp.booking_id === booking.id);
        availableBookings.push({
            ...booking,
            drop_points: relatedDropPoints,
            driver: driverData && driverData.length ? driverData[0] : null,
            rider: riderData.length ? riderData[0] : null
        });
    }

    
    // Fetch upcoming trip count
    const getDriverUpcomingBookingSql = await getDriverUpcomingBookingCount(request.driver_id);
    const upcomingBookingCountData = await promiseReponse(getDriverUpcomingBookingSql);
    // console.log(upcomingBookingCountData,"upcoming count");
    // Extract the count (assuming `upcoming_booking_count` is the key for the count)
    const upcomingTripCount = upcomingBookingCountData[0]?.upcoming_booking_count || 0;
    
   return { 
        data: {
            available_bookings: availableBookings, 
            upcoming_trip_count: upcomingTripCount
        }, 
        status: 200, 
        message: "Data Found" 
    };

};



const getCurrentBookingList = async (request) => {
    try {
        // Log the incoming request
        console.log(request, "Incoming request");

        // Fetch current bookings for the rider
        const getCurrentBookingsSql = await getCurrentBookingsQuery(request.rider_id);
        const currentBookingsData = await promiseReponse(getCurrentBookingsSql);

        // Check if no current bookings were found
        if (!currentBookingsData.length) {
            return {
                data: [],
                status: 404,
                message: "No Current Bookings Found"
            };
        }

        // Extract booking IDs
        const bookingIds = currentBookingsData.map(booking => booking.id);

        // Fetch drop-off points for these bookings
        const getDropPointsSql = await getDropPointsQuery(bookingIds);
        const dropPointsData = await promiseReponse(getDropPointsSql);

        // Combine bookings with their related drop-off points and user details
        const currentBookings = await Promise.all(currentBookingsData.map(async (booking) => {
            // Fetch drop-off points for the current booking
            const relatedDropPoints = dropPointsData.filter(dp => dp.booking_id === booking.id);

            // Get driver and rider details
            const driverID = booking.driver_id;
            const riderID = booking.rider_id;

            const getDriverDetailSql = await getUserDetailByID(driverID);
            const driverData = await promiseReponse(getDriverDetailSql);

            const getRiderDetailSql = await getUserDetailByID(riderID);
            const riderData = await promiseReponse(getRiderDetailSql);

            return {
                ...booking,
                drop_points: relatedDropPoints,
                driver: driverData[0] || null, // Include driver details
                rider: riderData[0] || null   // Include rider details
            };
        }));

        // Return the structured data
        return {
            data: currentBookings,
            status: 200,
            message: "Current Bookings Found"
        };
    } catch (error) {
        console.error(error, "Error in getCurrentBookingList");
        return {
            data: null,
            status: 500,
            message: "An error occurred while fetching current bookings"
        };
    }
};



const getBookingDetailService = async (request) => {
    try {

        // Fetch booking details
        const getBookingDetailSql = await getBookingDetailByID(request.booking_id);
        const bookingData = await promiseReponse(getBookingDetailSql);
        
        console.log(bookingData);
        
        // Check if no booking data was found
        if (!bookingData.length) {
            return {
                data: [],
                status: 404,
                message: "No Bookings Found"
            };
        }

        const getBookingData = bookingData[0]; // Assuming only one booking is returned
        console.log(getBookingData, "0");
        // Get driver and rider details
        const driverID = getBookingData.driver_id;
        const riderID = getBookingData.rider_id;

        const getDriverDetailSql = await getUserDetailByID(driverID);
        const driverData = await promiseReponse(getDriverDetailSql);

        const getRiderDetailSql = await getUserDetailByID(riderID);
        const riderData = await promiseReponse(getRiderDetailSql);

        // Fetch drop-off points for the booking
        const getDropPointsSql = await getDropPointsQuery([getBookingData.id]);
        const dropPointsData = await promiseReponse(getDropPointsSql);

        // Combine booking with related details
        const bookingDetail = {
            ...getBookingData,
            driver: driverData[0] || null, // Add driver details under the 'driver' key
            rider: riderData[0] || null,   // Add rider details under the 'rider' key
            drop_points: dropPointsData   // Add drop-off points
        };

        // Return the structured data
        return {
            data: bookingDetail,
            status: 200,
            message: "Booking Detail Found"
        };
    } catch (error) {
        console.error(error, "Error in getBookingDetail");
        return {
            data: null,
            status: 500,
            message: "An error occurred while fetching booking detail"
        };
    }
};




// const getBookingDetailService = async (request) => {
//     try {
//         // Log the incoming request
//         console.log(request, "Incoming request");

//         // Fetch current bookings for the rider
//         const getBookingDetailSql = await getBookingDetailQy(request.booking_id);
//         const getBookingData = await promiseReponse(getBookingDetailSql);
        
//         // console.log(getBookingData, "booking detail");
        
//         // Check if no current bookings were found
//         if (!getBookingData.length) {
//             return {
//                 data: [],
//                 status: 404,
//                 message: "No Bookings Found"
//             };
//         }
        
//         // get driver rider detail with 
//         const driverID = getBookingData.driver_id;
//         const riderID = getBookingData.rider_id;
        
        
//         const getDriverDetailSql = await getUserDetailByID(driverID);
//         const driverData = await promiseReponse(getDriverDetailSql);
        
        
//         const getRiderDetailSql = await getUserDetailByID(riderID);
//         const riderData = await promiseReponse(getRiderDetailSql);
        
//         // Extract booking IDs
//         const bookingIds = currentBookingsData.map(booking => booking.id);

//         // Fetch drop-off points for these bookings
//         const getDropPointsSql = await getDropPointsQuery(bookingIds);
//         const dropPointsData = await promiseReponse(getDropPointsSql);

//         // Combine bookings with their related drop-off points
//         const currentBookings = currentBookingsData.map(booking => {
//             const relatedDropPoints = dropPointsData.filter(dp => dp.booking_id === booking.id);
//             return { ...booking, drop_points: relatedDropPoints };
//         });
        

//         // Return the structured data
//         return {
//             data: JSON.parse(JSON.stringify(currentBookings)),
//             status: 200,
//             message: "Bookings Detail Found"
//         };
//     } catch (error) {
//         console.error(error, "Error in getBookingDetail");
//         return {
//             data: null,
//             status: 500,
//             message: "An error occurred while fetching booking detail"
//         };
//     }
// };

// socialcrib


/*const sendMessage = async (request) => 
{
    try 
    {
        const sql = await sendMessageQuery(request);
        const messageResult = await promiseReponse(sql);
        
        var messageID = messageResult.insertId;
        const messageSql = await getMessageByMessageIDQuery(messageID);
        const messageData = await promiseReponse(messageSql);
        // send first time notifiation
        var userDetailQuery = await getUserDetailbyIDQuery(request.senderID);
        const userDetailData = await promiseReponse(userDetailQuery);
        const user = JSON.parse(JSON.stringify(userDetailData[0]));
        const username = user.firstName+" "+user.lastName;
        const checkIsFirstMessageSql = await checkIsFirstMessageOfSender(request.senderID, request.receiverID);
        const messagesCountResult = await promiseReponse(checkIsFirstMessageSql);
        const messageCount = messagesCountResult[0].total;
        if(messageCount === 1)
        {
            console.log('addNotficationFun');
            const checkNotification = await addNotficationFun(request.senderID,request.receiverID,'sendMessage',username,'',1,5,'messageID',messageID);   
        }
        else {
            var roomsql = await getRoomByRoomID(request.roomID);
            var roomData = await promiseReponse(roomsql);
            const roomrow = JSON.parse(JSON.stringify(roomData[0]));
            console.log(roomrow,'ROOM STATUS');
            if(roomrow.receiverStatus === 0) 
            {
                const checkNotification = await directNotification(request.senderID,request.receiverID,'sendMessage',request.message,username,request.senderID);    
            }
            if(roomrow.senderStatus === 0) 
            {
                const checkNotification = await directNotification(request.senderID,request.receiverID,'sendMessage',request.message,username,request.senderID);    
            }
        }
       
        return { data:messageData[0],"status": 200,"message": "Data Found"};
    } catch (err) {
        return { "status": 400,"message": err.message };
    }
};
*/
const getMessages = async (request,callback) => 
{
    try 
    {
        const sql = await getMessagesQuery(request);
        const messages = await promiseReponse(sql);
        if(messages.length === 0)
        {
            return { "status": 400,"message": "Data not found" };
        }
        else
        {
            return { data: JSON.parse(JSON.stringify(messages)),"status": 200,"message": "Data Found"};    
        }
        
    } catch (err) {
        return { "status": 400,"message": err.message };
    }
}
/*const getRecentChatList = async (request, callback) =>
{
    try 
    {
        var messages = [];
        var roomQuery =`SELECT tbl_chatRoom.*, tbl_chatMessages.message, tbl_chatMessages.id as messageID,tbl_chatMessages.time FROM tbl_chatRoom LEFT JOIN tbl_chatMessages ON tbl_chatRoom.roomID = tbl_chatMessages.roomID JOIN ( SELECT roomID, MAX(id) as maxMessageID FROM tbl_chatMessages GROUP BY roomID ) as latestMessages ON tbl_chatMessages.id = latestMessages.maxMessageID WHERE tbl_chatRoom.userID = "${request.userID}" AND tbl_chatRoom.type = "${request.type}" ORDER BY tbl_chatMessages.id DESC`;
        
        const rooms = await new Promise((resolve, reject) => {
            db.query(roomQuery, function (error, roomResult) {
                if (error) return reject(error);
                resolve(roomResult);
            });
        });
        //console.log(rooms,"ROOM-QUERY");
        for (const element of rooms) {
            var sql = request.type == 1
                ? `SELECT receiver.name as receiverName, receiver.id as receiverID, receiver.logo as receiverProfilePicture 
                   FROM tbl_chatRoom room 
                   INNER JOIN tbl_business receiver ON room.userID = receiver.id  
                   WHERE room.type=0 AND room.roomID = "${element.roomID}"`
                : `SELECT receiver.fullName as receiverName, receiver.id as receiverID, receiver.profilePicture as receiverProfilePicture 
                   FROM tbl_chatRoom room 
                   INNER JOIN tbl_workers receiver ON room.userID = receiver.id 
                   WHERE room.type=1 AND room.roomID = "${element.roomID}"`;

            const messageDetails = await new Promise((resolve, reject) => {
                db.query(sql, function (err, result) {
                    if (err) return reject(err);
                    resolve(result);
                });
            });
            var unread=`SELECT count(id) as count FROM tbl_chatMessages WHERE receiverID="${request.userID}" AND roomID="${element.roomID}" AND status =0`;
            const unreadCount = await new Promise((resolve, reject) => {
                db.query(unread, function (readError, countResult) {
                    if (readError) return reject(readError);
                    resolve(countResult);
                });
            });
            const data = {
                receiverID: messageDetails[0].receiverID,
                receiverName: messageDetails[0].receiverName,
                profilePicture: messageDetails[0].receiverProfilePicture,
                message: element.message,
                roomID: element.roomID,
                time: element.time,
                unreadCount: unreadCount[0].count,
                created_at: element.created_at
            };
            messages.push(data);
        }
        return messages;
    } 
    catch (error) 
    {
        return { "status": 400,"message": err.message };
    }
};*/
// Exit from room

const closeConnection = async (request,callback) => 
{
    try
    {
        var sql = await getRoomByRoomID(request.roomID);
        var room = await promiseReponse(sql);
        if(room.length == 1)
        {
            const row = JSON.parse(JSON.stringify(room[0]));
            if(row.userID == request.userID)
            {
                var sql1 = await senderCloseConnectionQuery(request);
                const update = await promiseReponse(sql1);
                return {"status": 200,"message": "Connection close successfully"};
            }
            else if(row.receiverID == request.userID)
            {
                var sql1 = await receiverCloseConnectionQuery(request);
                const update = await promiseReponse(sql1);
                return {"status": 200,"message": "Connection close successfully"};
            }
            else
            {   
                return {"status": 400,"message": "Something went wrong"};
            }
        }
        else
        {
            return {"status": 400,"message": "Room not exist"};
        }
    }
    catch (err) 
    {
        return { "status": 400,"message": err.message };
    }
}
const updateOfflineStatus = async (request,callback) => 
{
    try
    {
        var sql = await updateChatStatusbyuserID(request,0);
        const update = await promiseReponse(sql);
        var sql1 = await updateUserStatusbyuserID(request,0);
        const update1 = await promiseReponse(sql1);
        return {"status": 200,"message": "user offline successfully"};
    }
    catch (err) 
    {
        return { "status": 400,"message": err.message };
    }
}
const userConnectedRooms = async (request,callback) => 
{
    try
    {
        var sql = await getRoomIDByUserIDQuery(request);
        const data = await promiseReponse(sql);
        return data;
    }
    catch (err) 
    {
        return { "status": 400,"message": err.message };
    }
}

// Check Online Status
const checkOnlineStatus = async (request,callback) => 
{
    try
    {
        var sql = await getUserDetailbyIDQuery(request.userID);
        const user = await promiseReponse(sql);
        if(user.length == 1)
        {
            const row = JSON.parse(JSON.stringify(user[0]));
           /* const data = {
                roomID : request.roomID,
                userID: request.userID,
                isOnline : row.isOnline 
            }*/
            return {roomID : request.roomID,userID: request.userID,isOnline : row.isOnline , "status": 200,"message": "Data Found"};    
        }
        else
        {
            return {roomID : request.roomID,userID: request.userID,"status": 200,"message": "Data Not Found"};
        }
    }
    catch (err) 
    {
        return { "status": 400,"message": err.message };
    }
}
// clear chat 
const clearChat = async (request,callback) => 
{
    try
    {
        var roomsql = await getRoomByRoomID(request.roomID);
        var roomdata = await promiseReponse(roomsql);
        let fieldName = '';
        if(roomdata.length == 1)
        {
            const roomrow = JSON.parse(JSON.stringify(roomdata[0]));
            if(roomrow.userID === request.userID)
            {
                fieldName = `deleteBySender`;
            }
            else {
                fieldName = `deleteByReceiver`;
            }
            var sql = await clearChatQuery(request.userID,request.roomID,fieldName);
            const user = await promiseReponse(sql);
            return {roomID : request.roomID,userID: request.userID,"status": 200,"message": "Chat deleted successfully"}; 
        }
        else {
            return {roomID : request.roomID,userID: request.userID,"status": 200,"message": "Data Not Found"};
        }
    }
    catch (err) 
    {
        return { "status": 400,"message": err.message };
    }
}


const sendNotification = async ({
    senderId,
    receiverId,
    bookingId = null,
    title,
    message,
    type = 'message',
    saveToDb = true,
    sendToFcm = true,
}) => {
    try {
        // Save notification to DB if `saveToDb` is true
        if (saveToDb) {
            const request = {
                userID: senderId,
                otherUserID: receiverId,
                bookingId,
                title,
                message,
                type,
            };
            const insertNotificationSql = await insertNotificationQuery(request);
            await promiseReponse(insertNotificationSql); // Save notification in DB
        }

        // Get device token and notification settings for receiver
        if (sendToFcm) {
            const getDeviceTokenQuery = await getUserDetailbyIDQuery(receiverId);
            const userDeviceToken = await promiseReponse(getDeviceTokenQuery);

            if (userDeviceToken.length > 0) {
                const deviceToken = userDeviceToken[0].device_token;
                const deviceType = userDeviceToken[0].device_type;
                const notificationStatus = userDeviceToken[0].notificationStatus;

                if (deviceToken && notificationStatus == 1) {
                    await sendFcmNotification(deviceToken, deviceType, title, message, type, senderId);
                }
            }
        }
    } catch (error) {
        console.error("Error sending notification:", error);
    }
};







/* Stop chat flow */

/* stop group chat flow*/
module.exports = {
   connectedRoomID,userOnline,createOrJoinRoomService,sendMessage,getMessages,closeConnection,updateOfflineStatus,userConnectedRooms,checkOnlineStatus,
    clearChat,userOfflineStatus,recentchatList,scheduleBookingService,createdBookingPaymentService, getBookingList,readMsg,leaveRoom,getUserDetails, getCurrentBookingList, updateBookingStatusService
    ,acceptBookingService,getBookingDetailService, cancelBookingService, delayBookingService,rejectBookingService
}


