const _ = require('lodash');
const { Blog } = require('../../models/admin/blog');
const { User } = require('../../models/user');
const { apiResponse } = require("../../core/response/response")
const { BookingAppointment } = require('../../models/booking');
const { BookingHistory } = require("../../models/booking-histories");
const { SUCCESS, REDIRECTION, CLIENT_ERROR, SERVER_ERROR } = require("../../core/response/statusCode")
const { ERROR_MSG, SUCCESS_MSG } = require("../../core/response/messages")
const mongoose = require("mongoose");
const {completedAppointmentDoctorTemplate,completedAppointmentDoctorTemplate_fr,completedAppointmentDoctorTemplate_ar,completedAppointmentPatientTemplate,completedAppointmentPatientTemplate_fr,completedAppointmentPatientTemplate_ar} = require('../../core/email-templates/email-web')

const { Role } = require('../../models/role');
const { CronEmail } = require('../../models/email')
const { sendEmail } = require('../../core/utilities/emailService');
const moment = require('moment');
const { Fcm } = require("../../models/fcm-tokens")
const { sendPushNotification } = require("../../core/utilities/pushNotification");
const { MobileOtp } = require("../../core/utilities/mobileOtp");
const { addNotification } = require("../common/notification.controller")
const { DOCTOR_NOTIFY, PATIENT_NOTIFY } = require("../../core/response/messages")
export { }


exports.completedAppointmentCronJob = async (req, res) => {
    let lang = req.headers["accept-language"] || 'en';
    try {
        const currentDate = new Date();
        const currentTime = moment(currentDate).format('HH:mm'); // Current time in HH:mm AM/PM format

        let filteredQuery = {
            $or: [
                {
                    $and: [
                        { reschedule_date: { $eq: null } },
                        { booking_date: { $lte: currentDate } },
                        {
                            slot: {
                                $not: { $regex: " - " } // Exclude slots with a range
                            }
                        },
                        {
                            slot: {
                                $lt: moment(currentDate).subtract(15, 'minutes').format('HH:mm') // Comparing current time with slot time
                            }
                        }
                    ]
                },
                {
                    $and: [
                        { reschedule_date: { $lte: currentDate } },
                        {
                            slot: {
                                $not: { $regex: " - " } // Exclude slots with a range
                            }
                        },
                        {
                            reschedule_slot: {
                                $lt: moment(currentDate).subtract(15, 'minutes').format('HH:mm') // Comparing current time with reschedule slot time
                            }
                        }
                    ]
                },
                {
                    $and: [
                        { reschedule_date: { $lte: currentDate } },
                        {
                            
                            reschedule_slot: { $regex: / - / }, // Ensures format "07:00 - 19:00"
                            $expr: {
                                $lt: [
                                    { $arrayElemAt: [{ $split: ["$slot", " - "] }, 1] }, // Extract "19:00"
                                    currentTime
                                ]
                            }
                            
                        }
                    ]
                },
                {
                    $and: [
                        { reschedule_date: { $eq: null } },
                        { booking_date: { $lte: currentDate } },
                        {
                            slot: { $regex: / - / }, // Ensures format "07:00 - 19:00"
                            $expr: {
                                $lt: [
                                    { $arrayElemAt: [{ $split: ["$slot", " - "] }, 1] }, // Extract "19:00"
                                    currentTime
                                ]
                            }
                        }
                    ]
                },
            ],
            status: "APPROVED"
        };

        // {
        //     slot: { $regex: / - / }, // Ensures format "07:00 - 19:00"
        //     $expr: {
        //         $gt: [
        //             { $arrayElemAt: [{ $split: ["$slot", " - "] }, 1] }, // Extract "19:00"
        //             currentTime
        //         ]
        //     }
        // },



        let data = await BookingAppointment.find(filteredQuery, { _id: 1, patient_id: 1, status: 1, hospital_doctor_id: 1 ,reschedule_date:1,reschedule_slot:1,booking_date:1,slot:1});
       
        // let data = await BookingAppointment.find(filteredQuery, { _id: 1, patient_id: 1, status: 1, hospital_doctor_id: 1});
        
        for (let booking of data) {
            let patient = await User.findOne({ _id: booking.patient_id }, { first_name: 1, last_name: 1, email: 1 });
            let hospitalDoctor = await User.findOne({ _id: booking.hospital_doctor_id }, { first_name: 1, last_name: 1, email: 1,hospital_name:1,clinic_name:1 }).populate('user_role');
            let  doctorClinicName = hospitalDoctor.hospital_name?.trim() ? hospitalDoctor.hospital_name : hospitalDoctor.clinic_name
            // let action = await BookingAppointment.findOneAndUpdate({ _id: booking._id }, { status: "COMPLETED" }, { new: true });
            let action = await BookingAppointment.findOneAndUpdate({ _id: booking._id }, { status: "COMPLETED", reschedule_date: booking.reschedule_date,reschedule_slot:booking.reschedule_slot,booking_date:booking.booking_date,slot:booking.slot }, { new: true });
            let patientFullName = `${patient.first_name}`.charAt(0).toUpperCase() + `${patient.first_name}`.slice(1) + " " +`${patient.last_name}`.charAt(0).toUpperCase() + `${patient.last_name}`.slice(1);
            let doctorFullName = `${hospitalDoctor.first_name}`.charAt(0).toUpperCase() + `${hospitalDoctor.first_name}`.slice(1) + " " + `${hospitalDoctor.last_name}`.charAt(0).toUpperCase() + `${hospitalDoctor.last_name}`.slice(1);
            let roleFindOfDoctorHospital = await Role.findOne({ _id: new mongoose.Types.ObjectId(hospitalDoctor.user_role) }, { _id: 1, title: 1 });
            let user_role = hospitalDoctor.user_role.title;
            let hospital_name = hospitalDoctor.hospital_name;
            // let appointmentType = await Role.findOne({ _id: new mongoose.Types.ObjectId(action.booking_role_type) }, { title: 1 })
            let condition = {}
        condition['_id'] = new mongoose.Types.ObjectId(booking.patient_id);
        let conditionDoc = {}
        conditionDoc['_id'] = new mongoose.Types.ObjectId(booking.hospital_doctor_id);

        // Fetch patient and doctor language preferences
        const [record, recordDoc] = await Promise.all([
            User.findOne(condition, { _id: 1, selected_language: 1,phone_number:1 }),
            User.findOne(conditionDoc, { _id: 1, selected_language: 1,phone_number:1 })
        ]);

        if (!record || !recordDoc) {
            console.error("Patient or Doctor record not found");
            return; 
        }

    const patientLanguage = record.selected_language || 'en';
    const doctorLanguage = recordDoc.selected_language || 'en';
    let appointmentDate;
    let appointmentSlot;
    if(action.reschedule_date != null){
    const dateStringRe = action.reschedule_date;
    const dateRe = new Date(dateStringRe);
    const rescheduleformattedDate = `${dateRe.getDate()}/${dateRe.getMonth() + 1}/${dateRe.getFullYear()}`;
    appointmentDate =  rescheduleformattedDate;
    appointmentSlot =action.reschedule_slot;
    }else{
    const dateString = action.booking_date;
    const date = new Date(dateString);


    const formattedDate = `${date.getDate()}/${date.getMonth() + 1}/${date.getFullYear()}`;
        appointmentDate =  formattedDate;
        appointmentSlot = action.slot;
    }

    const [templateDataSMS, templateDataPatientSMS] = await Promise.all([
        doctorLanguage === 'fr'
            ? await MobileOtp(recordDoc.phone_number.e164Number, `Bonjour Dr. ${doctorFullName},

    Cela confirme que le rendez-vous avec ${patientFullName} a été complété avec succès.

    Détails du rendez-vous :
    Médecin : Dr. ${doctorFullName}
    Date : ${appointmentDate}
    Heure : ${appointmentSlot}
    Type de rendez-vous : ${doctorClinicName}

    Merci de votre attention à cette question.

                
                                                `)
            : doctorLanguage === 'ar'
            ? await MobileOtp(recordDoc.phone_number.e164Number, `مرحبًا د. ${doctorFullName}،

    هذا لتأكيد أن الموعد مع ${patientFullName} قد تم بنجاح.

    تفاصيل الموعد:
    الطبيب: د. ${doctorFullName}
    التاريخ: ${appointmentDate}
    الوقت: ${appointmentSlot}
    نوع الموعد: ${doctorClinicName}

    شكرًا لاهتمامك بهذا الأمر.

                
                                                `)
            : await MobileOtp(recordDoc.phone_number.e164Number, `Hello Dr. ${doctorFullName},

    This is to confirm that the appointment with ${patientFullName} has been successfully completed.

    Appointment Details:
    Doctor: Dr. ${doctorFullName}
    Date: ${appointmentDate}
    Time: ${appointmentSlot}
    Appointment Type: ${doctorClinicName}

    Thank you for your attention to this matter.

                
                                                `),

        patientLanguage === 'fr'
            ? await MobileOtp(record.phone_number.e164Number, `Bonjour ${patientFullName},

    Nous avons le plaisir de vous informer que votre rendez-vous avec le Dr. ${doctorFullName} a été complété avec succès.

    Détails du rendez-vous :
    Médecin : Dr. ${doctorFullName}
    Date : ${appointmentDate}
    Heure : ${appointmentSlot}
    Type de rendez-vous : ${doctorClinicName}

    Merci d'avoir choisi Dr. Hivey. Nous avons hâte de vous voir à votre prochain rendez-vous.

                                    `)
            : patientLanguage === 'ar'
            ? await MobileOtp(record.phone_number.e164Number, `مرحبًا ${patientFullName}،

    يسرنا أن نعلمك أن موعدك مع د. ${doctorFullName} قد تم بنجاح.

    تفاصيل الموعد:
    الطبيب: د. ${doctorFullName}
    التاريخ: ${appointmentDate}
    الوقت: ${appointmentSlot}
    نوع الموعد: ${doctorClinicName}

    شكرًا لاختيارك Dr. Hivey. نحن نتطلع إلى رؤيتك في موعدك القادم.

                                    `)
            : await MobileOtp(record.phone_number.e164Number, `Hello ${patientFullName},

    We are pleased to inform you that your appointment with Dr. ${doctorFullName} has been successfully completed.

    Appointment Details:
    Doctor: Dr. ${doctorFullName}
    Date: ${appointmentDate}
    Time: ${appointmentSlot}
    Appointment Type: ${doctorClinicName}

    Thank you for choosing Dr. Hivey. We look forward to seeing you at your next appointment.

                                    `)
    ]);
            // Fetch templates for each language
        const [templateData, templateDataPatient] = await Promise.all([
            doctorLanguage === 'fr'
                ? completedAppointmentDoctorTemplate_fr({ patientFullName, doctorFullName, action, doctorClinicName , hospital_name , user_role })
                : doctorLanguage === 'ar'
                ? completedAppointmentDoctorTemplate_ar({ patientFullName, doctorFullName, action, doctorClinicName ,hospital_name , user_role})
                : completedAppointmentDoctorTemplate({ patientFullName, doctorFullName, action, doctorClinicName,hospital_name , user_role }),

            patientLanguage === 'fr'
                ? completedAppointmentPatientTemplate_fr({ patientFullName, doctorFullName, action, doctorClinicName,hospital_name , user_role })
                : patientLanguage === 'ar'
                ? completedAppointmentPatientTemplate_ar({ patientFullName, doctorFullName, action, doctorClinicName ,hospital_name , user_role})
                : completedAppointmentPatientTemplate({ patientFullName, doctorFullName, action, doctorClinicName,hospital_name , user_role })
        ]);

            
            const [emailSentDoctor, emailSentPatient] = await Promise.all([
                sendEmailAndSave(
                    hospitalDoctor._id,
                    hospitalDoctor.email,
                    templateData.subject,
                    templateData.html,
                    "appointment completed"
                ),
                sendEmailAndSave(
                    patient._id,
                    patient.email,
                    templateDataPatient.subject,
                    templateDataPatient.html,
                    "appointment completed"
                )
            ]);
            
            async function sendEmailAndSave(userId, email, subject, htmlContent, emailType) {
                const mailOptions = {
                    to: email,
                    subject: subject,
                    html: htmlContent
                };
            
                let sentStatus = 'PENDING';
                const isEmailSent = await sendEmail(mailOptions, res);
                if (isEmailSent) {
                    sentStatus = 'SUCCESS';
                }
            
               
                const cronPostParams = {
                    "user_id": userId,
                    "email_to": email,
                    "email_subject": subject,
                    "email_content": htmlContent,
                    "cron_email_type": emailType,
                    "cron_email_status": sentStatus
                };
                let saveEmail = new CronEmail(cronPostParams);
                await saveEmail.save();
            
                return sentStatus; 
            }
            





            let saveHistoryDataCondition = {
                booking_id : action._id,
                patient_id : action.patient_id,
                hospital_doctor_id : action.hospital_doctor_id,
                action_by : 'doctor',
                status : 'COMPLETED'
            }
    
            let bookingModal = new BookingHistory(saveHistoryDataCondition);
    
            await bookingModal.save();

            let schema = {
                user_id:  action.patient_id,
                notify_en: PATIENT_NOTIFY[`BOOKING-COMPLETED-en`],
                notify_ar: PATIENT_NOTIFY[`BOOKING-COMPLETED-ar`],
                notify_fr: PATIENT_NOTIFY[`BOOKING-COMPLETED-fr`]
            }
             const userTokenDetails = await Fcm.find({ user_id: action.patient_id });
                        userTokenDetails.length && userTokenDetails.forEach(async (token) => {
                            await sendPushNotification(token?.device_token, 'Dr. Hivey', schema?.[`notify_${lang}`], { booking_id: String(action._id), d_screen_url: String('COMPLETED') });
                        });
            await addNotification(schema, req, res)



        }
        return apiResponse(res, false, [], '', SUCCESS.OK, 1, [], req);
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req);
    }
};



exports.rejectAppointmentCronJob = async (req, res) => {
    try
    {
            const currentDate = new Date();
            const currentTime = moment(currentDate).format('HH:mm');
            let filteredQuery = {
                $or: [
                   
                    {
                        $and: [
                            { reschedule_date: { $eq: null } },
                            { booking_date: { $lte: currentDate } },
                            {
                                slot: {
                                    $not: { $regex: " - " } // Exclude slots with a range
                                }
                            },
                            {
                                slot: {
                                    $lte: currentTime // Comparing current time with slot time
                                }
                            }
                        ]
                    },
                   
                    {
                        $and: [
                            { reschedule_date: { $lte: currentDate } },
                            {
                                slot: {
                                    $not: { $regex: " - " } // Exclude slots with a range
                                }
                            },
                            {
                                reschedule_slot: {
                                    $lte: currentTime // Comparing current time with reschedule slot time
                                }
                            }
                        ]
                    },
                    // full time end

                    
                    {
                        $and: [
                            { reschedule_date: { $eq: null } },
                            { booking_date: { $lte: currentDate } },
                            {
                                slot: { $regex: / - / }, // Ensures format "07:00 - 19:00"
                                $expr: {
                                    $lte: [
                                        { $arrayElemAt: [{ $split: ["$slot", " - "] }, 1] }, // Extract "19:00"
                                        currentTime
                                    ]
                                }
                            }
                        ]
                    },
                    {
                        $and: [
                            { reschedule_date: { $lte: currentDate } },
                            {
                                
                                reschedule_slot: { $regex: / - / }, // Ensures format "07:00 - 19:00"
                                $expr: {
                                    $lte: [
                                        { $arrayElemAt: [{ $split: ["$slot", " - "] }, 1] }, // Extract "19:00"
                                        currentTime
                                    ]
                                }
                                
                            }
                        ]
                    },
                    

                    //part time end 
                ],
                status: "PENDING"
            };
            console.log(await BookingAppointment.find(filteredQuery))
            const result = await BookingAppointment.updateMany(
                filteredQuery,
                { 
                    $set: { 
                        status: "REJECTED", 
                        rejected_reason: "Request is expired" 
                    } 
                }
            );

            return apiResponse(res, false, [], '', SUCCESS.OK, 1, result, req);
    }
    catch(error)
    {
        console.log(error);
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-en`], SERVER_ERROR.internalServerError, 0, [], req);

    }
};