var pool = require('../config/dbConnection');
const baseModel = require("../models/baseModel");
const { format,subMonths } = require("date-fns");

class Booking extends baseModel{

    async save(fieldValues){
        try {
            const result = await pool.query('insert into bookings SET ?',fieldValues);
            const guest = await pool.query('select * from bookings where id = ?',[result[0].insertId]);
            return guest[0][0];
        } catch (error) {
            console.log("error in saveBookingGuests:",error);
            throw error;
        }
    }

    async saveBookingGuests(fieldValues){
        try {
            const result = await pool.query('insert into booking_guests_temp SET ?',fieldValues);
            const guest = await pool.query('select * from booking_guests_temp where id = ?',[result[0].insertId]);
            return guest[0][0];
        } catch (error) {
            console.log("error in saveBookingGuests:",error);
            throw error;
        }
    }

    async saveBookingPayments(booking_id,transaction_id,amount){
        const result = await pool.query('insert into booking_payments (booking_id,transaction_id,amount,payment_status) values (?,?,?,1)',[booking_id,transaction_id,amount]);
        return result[0];
    }
    
    async getAll(params={}) {
        try{
            var query = 'SELECT * FROM properties';
            var whereAppended = false;
            if(params.id){
                query += ` where id = ${params.id}`;
                whereAppended = true;
            }else{
                if(params.channelIds){
                    if(whereAppended){
                        query += ` and channel_id in (${params.channelIds})`;
                    }else{
                        query += ` where channel_id in (${params.channelIds})`;
                    }
                    whereAppended = true;
                }
                if(params.destination){
                    if(whereAppended){
                        query += ` and destination = ${params.destination}`;
                    }else{
                        query += ` where destination = ${params.destination}`;
                    }
                    whereAppended = true;
                }
                if(params.featured){
                    if(whereAppended){
                        query += ` and featured_property = ${params.destination}`;
                    }else{
                        query += ` where featured_property = ${params.featured}`;
                    }
                    whereAppended = true;
                }
            }
            const results = await pool.query(query);
            return results[0];
        }catch(error){
            console.log("error in get all");
            throw error;
        }   
    }

    async forBookingInfoDisplay(id){
        const result = await pool.query('select id,property_id,DATE_FORMAT(check_in_date,"%d %M %Y") as check_in_date, DATE_FORMAT(check_out_date,"%d %M %Y") as check_out_date,number_adults,number_children from bookings where id = ?', [id]);
        var booking = result[0][0];
        const lead_guest = await pool.query('select * from booking_guests where lead_guest = 1 and booking_id=?',[id]);
        var lead = lead_guest[0][0];
        booking["lead_guest"] = lead.user_id;
        console.log(new Date(booking.check_in_date,"m-d-Y"));
        return booking;
    }

    async bookingOccupancy(booking_id){
        try {
            const result = await pool.query('select * from booking_rentalInfo where booking_id = ? limit 1',[booking_id]);
            return result[0];
        } catch (error) {
            console.log(error);
        }
    }

    /** gets Booking by ezee id(uniqueId) */
    async bookingById(uniqueId){
        try {
            const result = await pool.query('select * from bookings where uniqueId = ?',[uniqueId]);
            return result[0];
        } catch (error) {
            console.log(error);
        }
    }

    /** gets Booking by ezee id(uniqueId) */
    async tempBookingById(uniqueId){
        try {
            const result = await pool.query('select * from booking_temp where uniqueId = ?',[uniqueId]);
            return result[0][0];
        } catch (error) {
            console.log(error);
        }
    }

    async logEzeeBookingInput(log){       
        const operation = log.operation;
        const data = log.data.Reservations;
        var uniqueId = 0;
        for(let i=0; i<data.Reservation.length; i++){
            const reservation = data.Reservation[i];
            uniqueId = reservation.UniqueID;
            break;
        }
        console.log(`UniqueID: ${uniqueId} Operation: ${operation}`);
        const result = await pool.query('insert into bookings_log (UniqueID,operation,log) values (?,?,?)',[uniqueId,operation,JSON.stringify(log, null, 4)]);
        return result[0].insertId; 
    }

    async writeEzeeBooking(values){
        const result = await pool.query('INSERT INTO temp_booking SET ?', values);
        return result[0].insertId;
    }

    async writeEzeeBookingTable(table,values){
        const result = await pool.query('INSERT INTO '+table+' SET ?', values);
        return result[0].insertId;
    }

    /** When a booking gets modified delete the older records for the booking and write new ones */
    async clearEzeeBooking(uniqueId){
        try {
            await pool.query('delete from temp_BookByInfo where UniqueID = ?',[uniqueId]);
            await pool.query('delete from temp_BookingTran where UniqueID = ?',[uniqueId]);
            await pool.query('delete from temp_RentalInfo where UniqueID = ?',[uniqueId]);
            await pool.query('delete from temp_taxDetails where UniqueID = ?',[uniqueId]);
            await pool.query('delete from temp_paymentDetails where UniqueID = ?',[uniqueId]);
            return;
        } catch (error) {
            throw error;
        }
    }

    async calendarAvailability(check_in_date, check_out_date, propertyId){
        const result = await pool.query("select DATE_FORMAT(EffectiveDate, '%Y-%m-%d') as EffectiveDate from temp_RentalInfo where RoomTypeCode = ? and (EffectiveDate BETWEEN ? and ?)",[propertyId,check_in_date, check_out_date]);
        return result[0];
    }

    async propertyAvailability(propertyId,start=null){
        if(!start){
            start = format(new Date(),'yyyy-MM-dd');
        }
        const result = await pool.query("select start,end,currentStatus from bookings where property_id = ? and start >= ?)",[propertyId,start]);
        return result[0];
    }

    async propertyCalendar(propertyId){
        try {
            const result = await pool.query("select id,DATE_FORMAT(start, '%Y-%m-%d') as start,DATE_FORMAT(end, '%Y-%m-%d') as end,status,currentStatus from bookings where property_id = ? and currentStatus not in ('Cancel','Void')",[propertyId]);
            return result[0];
        } catch (error) {
            console.log(error);
            throw error;
        }
    }

    async getSyncLog(id){
        const restult = await pool.query("select * from booking_log where id = ?",[id]);
        return restult[0];
    }

    async getAllSyncLogs(){
        const restult = await pool.query("select * from bookings_log where imported = 0 limit 0,5");
        return restult[0];
    }

    async markAsImported(id){
        try {
            await pool.query('update  bookings_log set imported = 1 where id = ?',[id]);
            return;
        } catch (error) {
            throw error;
        }
    }

    async insertTempCheck(id){
        const result = await pool.query('INSERT INTO temp_check (UniqueID) values (?) ', [id]);
        return result[0].insertId;
    }

    async manageTempCheck(){
        const results = await pool.query("update temp_check set imported = 1 where imported = 0 and UniqueID in (select UniqueID from temp_RentalInfo)");
        return;
    }

    async doneUpto(){
        const results = await pool.query("select DATE_FORMAT(done_upto, '%Y-%m-%d') as done_upto from temp_table");
        return results[0][0].done_upto;
    }

    async updateUpto(upto){
        const results = await pool.query("update temp_table set done_upto = ?",[upto]);
        return;
    }

    async missing5(){
        const restult = await pool.query("select * from temp_check where imported = 0 and UniqueID not in (select UniqueID from temp_RentalInfo) limit 0,5");
        return restult[0];
    }

    async markMissedAsImported(id){
        try {
            await pool.query('update temp_check set imported = 1 where UniqueID = ?',[id]);
            return;
        } catch (error) {
            throw error;
        }
    }

    async futureOccupiedDates(propertyId){
        const today = format(new Date(),'yyyy-MM-dd');
        const results = await pool.query("select DATE_FORMAT(EffectiveDate, '%Y-%m-%d') as EffectiveDate from temp_RentalInfo where RoomTypeCode = ? and EffectiveDate >= ? order by EffectiveDate",[propertyId,today]);
        return results[0];
    }

    /** START - Importing Bookings into real booking tables from booking logs */
    async readBookingLog(id){
        try {
            const results = await pool.query("select * from bookings_log where id = ?",[id]);
            return results[0];
        } catch (error) {
            throw error;
        }
    }

    async bookingByEzeeIds(uniqueId,subBookingId){
        try {
            const results = await pool.query("select * from bookings where uniqueId = ? and subBookingId = ?",[uniqueId,subBookingId]);
            return results[0];
        } catch (error) {
            throw error;
        }
    }

    async fetchFromTable(table,key,value,single=false){
        try{
            const results = await pool.query('select * from '+table+' where '+key+' = ?',[value]);
            if(single){
                return results[0][0];
            }
            return results[0];
        } catch (error){
            throw error;
        }
    }

    async fetchFromTableWithClause(table,where){
        try{
            const results = await pool.query('select * from '+table+' where ?',[where]);
            return results[0];
        } catch (error){
            throw error;
        }
    }

    async writeTableEntry(table,values){
        try{
            const result = await pool.query('INSERT INTO '+table+' SET ?', values);
            return result[0].insertId;
        } catch (error) {
            throw error;
        }
    }

    async deleteFromBookingTable(table,booking_id){
        try{
            const result = await pool.query('delete from '+table+' where booking_id = ?', [booking_id]);
            return result;
        } catch (error) {
            throw error;
        }
    }

    async updateBookingTable(table,values,id){
        try{
            const result = await pool.query('update '+table+' SET ? where id = ?', [values,id]);
            return result[0];
        } catch (error) {
            throw error;
        }
    }

    async guestFromPhone(phone,mobile){
        if((!phone || phone=="") && (!mobile || mobile=="")){
            return null;
        }
        var whereClause = 'where role = 268 and (';
        var clauseAdded = false;
        if(phone && phone !=''){
            whereClause += ` phone = '${phone}' || phone1 = '${phone}' || phone2 = '${phone}' `;
            clauseAdded = true;
        }
        if(mobile && mobile !=''){
            if(clauseAdded){
                whereClause += ' || ';
            }
            whereClause += ` phone1 = '${mobile}' || phone1 = '${mobile}' || phone2 = '${mobile}' `;
        }
        whereClause += ')';
        try{
            const result = await pool.query('select * from users '+whereClause);
            return result[0];
        } catch (error) {
            throw error;
        }
    }

    async getLogsForImport(no){
        try {
            const results = await pool.query('select id from bookings_log where imported in (0,1) limit ?',[no]);
            return results[0];
        } catch (error) {
            console.log(error);
            throw error;
        }
    }

    async markImported(id,status=2){
        try{
            const result = await pool.query('update bookings_log SET imported = ? where id = ?', [status,id]);
            return result[0];
        } catch (error) {
            throw error;
        }
    }
    /** END - Importing Bookings into real booking tables from booking logs */
    /** START - Admin panel booking screen functions */

    async adminBookingsList(){
        try {
            const today = format(new Date(), 'yyyy-MM-dd');
            const baseQuery = "SELECT b.id,b.uniqueId,b.currentStatus, u.firstname, u.lastname,DATE_FORMAT(b.start,'%d %b %y') as start,DATE_FORMAT(b.end,'%d %b %y') as end,b.createDatetime,s.display as property_type,p.listing_name,bt.totalPayment,bt.totalAmountAfterTax,bt.taCommision FROM bookings b, users u,properties p,booking_tariffs bt, settings s where b.guest_id = u.id and b.property_id = p.id and b.id = bt.booking_id and s.setting = 'property_type' and p.property_type = s.id";
            
            const past = await pool.query(baseQuery + ' and b.start < ?  order by b.start desc limit 50',[today]);
            const upcoming = await pool.query(baseQuery + ' and b.start > ?',[today]);
            const recent = await pool.query(baseQuery + ' order by b.createDatetime desc limit 50');
            const ongoing = await pool.query(baseQuery + ' and b.start <= ? and b.end >= ?',[today,today]);
            return {recent:recent[0],upcoming:upcoming[0],ongoing:ongoing[0],past:past[0]};
        } catch (error) {
            console.log(error);
            throw error;
        }
    }

    async adminManageBookingsList(){
        try {
            const today = format(new Date(), 'yyyy-MM-dd');
            const startOfMonth = format(subMonths(new Date(),1), 'yyyy-MM-01');
            //const startOfMonth = format(new Date(), 'yyyy-MM-01');
            console.log(`looking for dates between ${startOfMonth} and ${today}`);
            const baseQuery = "SELECT b.id,b.uniqueId,b.currentStatus,b.source, u.firstname, u.lastname,DATE_FORMAT(b.start,'%d %b %y') as start,DATE_FORMAT(b.end,'%d %b %y') as end,b.createDatetime,s.display as property_type,p.listing_name,bt.totalPayment,bt.totalAmountAfterTax,bt.totalAmountBeforeTax,bt.totalTax,bt.taCommision FROM bookings b, users u,properties p,booking_tariffs bt, settings s where b.guest_id = u.id and b.property_id = p.id and b.id = bt.booking_id and s.setting = 'property_type' and p.property_type = s.id and end >= ? and end <= ?";
            const bookings = await pool.query(baseQuery,[startOfMonth,today]);
            return bookings[0]; 
        } catch (error) {
            console.log(error);
            throw error;
        }
    }

    async bookingWithPricing(id){
        try {
            const booking = await pool.query("SELECT b.id,b.uniqueId,b.currentStatus,b.source, u.firstname, u.lastname,u.phone,u.email,DATE_FORMAT(b.start,'%d %b %y') as start,DATE_FORMAT(b.end,'%d %b %y') as end,b.createDatetime,p.listing_name,bt.totalPayment,bt.totalAmountAfterTax,bt.totalAmountBeforeTax,bt.totalTax,bt.taCommision FROM bookings b, users u,properties p,booking_tariffs bt where b.guest_id = u.id and b.property_id = p.id and b.id = bt.booking_id and b.id = ?",[id]);
            return booking[0][0];
        } catch (error) {
            console.log(error);
            throw error;
        }
    }
    /** END - Admin panel booking screen functions */

    /** START - Dashboard related data functions */
    async todaysCheckouts(){
        try{
            const today = format(new Date(), 'yyyy-MM-dd');
            const bookings = await pool.query("select * from bookings where end = ? and uniqueId > 0 and currentStatus not in ('Void','Cancel')",[today]);
            const tarrifs = await pool.query("select *,(totalAmountBeforeTax - taCommision) as nbv from booking_tariffs where booking_id in (select id from bookings where end = ? and currentStatus not in ('Void','Cancel'))",[today]);
            const rentals = await pool.query("select *, DATE_FORMAT(effectiveDate,'%Y-%m-%d') as effDate from booking_rentalInfo where booking_id in (select id from bookings where end = ? and currentStatus not in ('Void','Cancel'))",[today]);
            return {bookings:bookings[0],tarrifs:tarrifs[0],rentals:rentals[0]};
        }catch (error) {
            console.log(error);
            throw error;
        }
    }

    async todaysBookings(){
        try {
            const today = format(new Date(), 'yyyy-MM-dd');
            //and b.currentStatus not in ('Cancel','Void') 
            const bookingStats = await pool.query("SELECT b.id,b.uniqueId,b.start,b.end,b.voucherNo,b.packageName,b.roomName,b.currentStatus,t.totalAmountAfterTax,t.taCommision, concat(u.firstname,' ',u.lastname) as guest,u.phone,u.email FROM bookings b,booking_tariffs t, users u where b.start <= ? and b.end >= ? and b.id = t.booking_id and b.guest_id = u.id",[today,today]);
            const rentalStats = await pool.query("SELECT booking_id,max(effectiveDate) as eDate, max(adult) as adults, max(child) as children FROM `booking_rentalInfo` where booking_id in (select id from bookings where start <= ? and end >= ?) group by booking_id;",[today,today]);
            return {bookingStats:bookingStats[0],rentalStats:rentalStats[0]};    
        } catch (error) {
            console.log(error);
            throw error;
        }
    }

    async revenueByDay(start,end){
        try {
            const results = await pool.query(`SELECT b.end,sum(t.totalAmountBeforeTax-t.taCommision) as revenue FROM bookings b, booking_tariffs t where b.end >= ? and b.end <= ? and b.currentStatus not in ('Void','Cancel') and b.id = t.booking_id group by b.end order by b.end`,[start,end]);
            return results[0];
        } catch (error) {
            console.log(error);
            throw error;
        }
    }

    async revenueByMonth(start,end){
        try {
            const today = format(new Date(), 'yyyy-MM-dd');
            /*
             * The temp_RentalInfo table in production does not have a TariffGross column – it stores the nightly
             * pre-tax amount in the RentPreTax column. The previous query crashed the dashboard with an
             * “Unknown column 'ri.TariffGross'” SQL error. We now use RentPreTax as the revenue basis to
             * eliminate the crash while keeping the business logic intact.
             */
            const result = await pool.query("select MONTH(ri.EffectiveDate) as month, YEAR(ri.EffectiveDate) as year, DATE_FORMAT(ri.EffectiveDate, '%M') as monthName, sum(ri.RentPreTax) as revenue from temp_RentalInfo ri where ri.EffectiveDate between ? and ? group by MONTH(ri.EffectiveDate), YEAR(ri.EffectiveDate) order by YEAR(ri.EffectiveDate), MONTH(ri.EffectiveDate)",[start,end]);
            return result[0];
        } catch (error) {
            console.log(error);
            throw error;
        }
    }

    // New method for stacked chart data by property
    async revenueByPropertyStacked(start, end, propertyId = null) {
        try {
            let query = `
                SELECT 
                    DATE(ri.EffectiveDate) as date,
                    p.id as property_id,
                    p.listing_name,
                    SUM(ri.RentPreTax) as revenue
                FROM temp_RentalInfo ri
                JOIN properties p ON p.channel_id = ri.RoomTypeCode
                WHERE ri.EffectiveDate BETWEEN ? AND ?
            `;
            
            const params = [start, end];
            
            if (propertyId) {
                query += ` AND p.id = ?`;
                params.push(propertyId);
            }
            
            query += ` 
                GROUP BY DATE(ri.EffectiveDate), p.id, p.listing_name
                ORDER BY ri.EffectiveDate, p.listing_name
            `;
            
            const result = await pool.query(query, params);
            return result[0];
        } catch (error) {
            console.log('Error in revenueByPropertyStacked:', error);
            throw error;
        }
    }

    // Get historical pricing data for revenue loss calculation
    async getHistoricalPricing(propertyId, startDate, endDate) {
        try {
            // Get average pricing from last year for same dates
            const lastYearStart = new Date(startDate);
            lastYearStart.setFullYear(lastYearStart.getFullYear() - 1);
            const lastYearEnd = new Date(endDate);
            lastYearEnd.setFullYear(lastYearEnd.getFullYear() - 1);

            const query = `
                SELECT 
                    AVG(ri.RentPreTax) as avgRate,
                    COUNT(*) as bookingCount
                FROM temp_RentalInfo ri
                JOIN properties p ON p.channel_id = ri.RoomTypeCode
                WHERE p.id = ? 
                AND ri.EffectiveDate BETWEEN ? AND ?
                AND ri.RentPreTax > 0
            `;
            
            const result = await pool.query(query, [propertyId, format(lastYearStart, 'yyyy-MM-dd'), format(lastYearEnd, 'yyyy-MM-dd')]);
            return result[0];
        } catch (error) {
            console.log('Error in getHistoricalPricing:', error);
            return [];
        }
    }

    // Get monthly bookings for a property
    async getMonthlyBookings(propertyId, startDate, endDate) {
        try {
            const query = `
                SELECT 
                    b.id,
                    b.uniqueId,
                    b.start,
                    b.end,
                    b.currentStatus,
                    b.totalAmountAfterTax,
                    b.totalAmountBeforeTax,
                    DATEDIFF(b.end, b.start) as nights
                FROM bookings b
                WHERE b.property_id = ?
                AND (
                    (b.start BETWEEN ? AND ?) 
                    OR (b.end BETWEEN ? AND ?)
                    OR (b.start <= ? AND b.end >= ?)
                )
                AND b.currentStatus NOT IN ('Cancel', 'Void')
                ORDER BY b.start
            `;
            
            const result = await pool.query(query, [
                propertyId, 
                startDate, endDate, 
                startDate, endDate,
                startDate, endDate
            ]);
            return result[0];
        } catch (error) {
            console.log('Error in getMonthlyBookings:', error);
            throw error;
        }
    }

    // Get monthly revenue data for a property
    async getMonthlyRevenue(propertyId, startDate, endDate) {
        try {
            const query = `
                SELECT 
                    DATE(ri.EffectiveDate) as date,
                    SUM(ri.RentPreTax) as revenue,
                    COUNT(*) as bookingCount
                FROM temp_RentalInfo ri
                JOIN properties p ON p.channel_id = ri.RoomTypeCode
                WHERE p.id = ? 
                AND ri.EffectiveDate BETWEEN ? AND ?
                GROUP BY DATE(ri.EffectiveDate)
                ORDER BY ri.EffectiveDate
            `;
            
            const result = await pool.query(query, [propertyId, startDate, endDate]);
            return result[0];
        } catch (error) {
            console.log('Error in getMonthlyRevenue:', error);
            throw error;
        }
    }

    async pieChartsData(){
        try {
            const props = await pool.query("select p.listing_name as category,count(r.id) as count from bookings b, booking_rentalInfo r, properties p WHERE b.currentStatus not in ('Void','Cancel') and b.id = r.booking_id and b.property_id = p.id group by category");
            const channels = await pool.query("SELECT source as category,count(*) as count FROM bookings group by category");
            const propTypes = await pool.query("select s.display as category,count(r.id) as count from bookings b, booking_rentalInfo r, properties p, settings s WHERE b.currentStatus not in ('Void','Cancel') and b.id = r.booking_id and b.property_id = p.id and p.property_type = s.id group by display");
            return {props:props[0],channels:channels[0],propTypes:propTypes[0]};
        } catch (error) {
            console.log(error);
            throw error;
        }
    }
    /** END - Dashboard related data functions */

    /** START - My trips related data functions */
    async myTrips(userId){
        try {
            const trips = await pool.query("SELECT b.id,b.start,b.end, b.currentStatus as status, p.id as property_id,p.listing_name,p.google_latitude,p.google_longitude, pm.media_filename FROM bookings b, properties p, property_media pm where b.guest_id = ? and b.property_id = p.id and b.property_id = pm.property_id and pm.media_type_id = 4",[userId]);
            const occupancy = await pool.query("SELECT max(adult) as adults,max(child) as children,booking_id FROM `booking_rentalInfo` where booking_id in (select id from bookings where guest_id = ?) group by booking_id",[userId]);
            return {trips:trips[0],occupancy:occupancy[0]};
        } catch (error) {
            console.log(error);
            throw error;
        }
    }
    /** END - My trips related data functions */

    async bookingDetailsForHost(bookingId){ 
        try {
            // Get basic booking details
            const results = await pool.query("select b.id,b.start,b.end,b.source,p.listing_name,DATE_FORMAT(b.start, '%d %M %Y') as check_in_date,DATE_FORMAT(b.end, '%d %M %Y') as check_out_date from bookings b join properties p on b.property_id = p.id where b.id = ?",[bookingId]);
            
            // Get tariff details
            const tariffs = await pool.query("select totalAmountBeforeTax,taCommision,totalAmountAfterTax from booking_tariffs where booking_id = ?",[bookingId]);
            
            // Get rental info
            const rentalInfo = await pool.query("select effectiveDate,adult as adults,child as children,rent from booking_rentalInfo where booking_id = ? order by effectiveDate",[bookingId]);
            
            // Get guest details with group_type and purpose_of_visit
            const guests = await pool.query("select bg.id,bg.lead_guest,u.firstname,u.lastname,u.email,u.phone,bg.group_type,bg.purpose_of_visit from booking_guests bg join users u on bg.user_id = u.id where bg.booking_id = ?",[bookingId]);
            
            // Get property details
            const property = await pool.query("select id,listing_name,address_line_1,address_line_2,city,state,country from properties where id = (select property_id from bookings where id = ?)",[bookingId]);
            
            if (results[0].length === 0) {
                throw new Error('Booking not found');
            }
            
            const booking = results[0][0];
            
            // Add tariff information
            if(tariffs[0].length > 0){
                booking["tariff"] = tariffs[0][0];
            } else {
                booking["tariff"] = {};
            }
            
            // Add rental information
            if(rentalInfo[0].length > 0){
                booking["rentalInfo"] = rentalInfo[0];
            } else {
                booking["rentalInfo"] = [];
            }
            
            // Find lead guest and add their details to booking
            const leadGuest = guests[0].find(guest => guest.lead_guest === 1);
            if (leadGuest) {
                booking["guest"] = {
                    firstname: leadGuest.firstname,
                    lastname: leadGuest.lastname,
                    email: leadGuest.email,
                    phone: leadGuest.phone,
                    group_type: leadGuest.group_type,
                    purpose_of_visit: leadGuest.purpose_of_visit
                };
            } else {
                booking["guest"] = {};
            }
            
            // Add all guests array
            booking["guests"] = guests[0] || [];
            
            // Add property information
            if(property[0].length > 0){
                booking["property"] = property[0][0];
            } else {
                booking["property"] = {};
            }
            
            return {
                booking: booking,
                rentalInfo: booking.rentalInfo || [],
                tariff: booking.tariff || {},
                property: booking.property || {},
                guest: booking.guest || {}
            };
        } catch (error) {
            console.log(error);
            throw error;
        }
    }
}
module.exports = Booking;