import { log } from "util";

const _ = require('lodash');
const { Blog } = require('../../models/admin/blog');
const { FAQ } = require('../../models/admin/faq');
const { Magazine } = require('../../models/admin/magazine');
const { apiResponse } = require("../../core/response/response")
const { DepartmentCity } = require('../../models/department-city')
const { BookingAppointment } = require('../../models/booking')
const { MagazineCategory } = require('../../models/admin/magazine_category');
const { SUCCESS, REDIRECTION, CLIENT_ERROR, SERVER_ERROR } = require("../../core/response/statusCode")
const { ERROR_MSG, SUCCESS_MSG } = require("../../core/response/messages")
const { Role } = require('../../models/role');
const { User } = require('../../models/user');
const { Category } = require('../../models/admin/category');
const mongoose = require("mongoose");
const userObject = new User();
const { LanguageTranslate } = require('../../models/admin/language-translate');

const { sendEmail } = require('../../core/utilities/emailService');
const {contactUsTemplate} = require('../../core/email-templates/email-web')
const { CronEmail } = require('../../models/email')
const { Contact } = require("../../models/admin/contact")
const { ContactReply } = require("../../models/admin/contact-reply")

export { }


// listing blog
exports.blogListing = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { user_id, is_read } = req.body
        var filteredQuery = {}
        let page, limit: number;



        page = req.query.page ? parseInt(req.query.page) - 1 : 0;
        limit = req.query.limit ? parseInt(req.query.limit) : 10;
        filteredQuery = {
            is_deleted: false,
            is_active: true
        }
        const [data, count] = await Promise.all([
            Blog.find(filteredQuery, { _id: 1, title_en: 1, title_ar: 1, title_fr: 1, description_en: 1, description_ar: 1, description_fr: 1, blog_pic: 1, createdAt: 1 }).sort({ createdAt: -1 }).skip(page * limit).limit(limit),
            Blog.countDocuments(filteredQuery)
        ]);
        return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}
//faq listing
exports.faqListing = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { user_id, is_read, user_type } = req.body
        var filteredQuery = {}
        let page, limit: number;



        page = req.query.page ? parseInt(req.query.page) - 1 : 0;
        limit = req.query.limit ? parseInt(req.query.limit) : 10;
        filteredQuery = {
            is_deleted: false,
            is_active: true,
            user_type: user_type
        }
        const [data, count] = await Promise.all([
            FAQ.find(filteredQuery, { _id: 1, question_en: 1, answer_en: 1, question_ar: 1, answer_ar: 1, question_fr: 1, answer_fr: 1, is_active: 1, createdAt: 1, user_type: 1 }).sort({ createdAt: -1 }).skip(page * limit).limit(limit),
            FAQ.countDocuments(filteredQuery)
        ]);
        return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}


// magazine
exports.magazineListing = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
   
    try {
        let { title } = req.query;
        var filteredQuery = {}
        let page, limit: number;
        page = req.query.page ? parseInt(req.query.page) - 1 : 0;
        limit = req.query.limit ? parseInt(req.query.limit) : 10;
        let skip = parseInt(page) * limit;
        filteredQuery = {
            is_deleted: false,
            is_active: true
        }
        let title_regex = new RegExp(title, 'i');
        const filter_title = (title && title !== 'undefined')
            ? { [`title_${lang}`]: title_regex }
            : {};

            filteredQuery = { ...filteredQuery, ...filter_title };
        
        
        const [data, count] = await Promise.all([
            Magazine.aggregate([
                { $match: filteredQuery },
                {
                    $lookup: {
                        from: "magazine_categories",
                        as: "magazine_categories",
                        let: { magazine_category: "$magazine_category" },
                        pipeline: [
                            {
                                $match: {
                                    $expr: { $eq: ["$$magazine_category", "$_id"] },
                                }
                            },
                            {
                                $project: {
                                    _id: 1,
                                    title_en: 1,
                                    title_ar: 1,
                                    title_fr: 1,
                                    image: 1
                                }
                            }
                        ],
                    },

                },
                {
                    $unwind: {
                        path: '$magazine_categories',
                        preserveNullAndEmptyArrays: true,
                    },
                },
                {
                    $project: {
                        title_en: 1,
                        title_ar: 1,
                        title_fr: 1,
                        // description_en:1,
                        // description_ar:1,
                        // description_fr:1,
                        magazine_pic: 1,
                        magazine_pdf: 1,
                        magazine_video: 1,
                        createdAt: 1,
                        magazine_categories: "$magazine_categories"
                    }
                },
                { $sort: { createdAt: -1 } },
                { $skip: skip },
                { $limit: limit }
            ]),
            Magazine.countDocuments(filteredQuery)
        ]);
        return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}

// Magazine listing count per category
exports.magazineListingCount = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        let { title } = req.query;
        let filteredQuery: any = { is_deleted: false, is_active: true };
        if (title && title !== 'undefined') {
            const title_regex = new RegExp(title, 'i');
            // Match against any localized title field
            filteredQuery['$or'] = [
                { title_en: title_regex },
                { title_ar: title_regex },
                { title_fr: title_regex }
            ];
        }

        const pipeline = [
            { $match: filteredQuery },
            {
                $group: {
                    _id: "$magazine_category",
                    count: { $sum: 1 }
                }
            },
            {
                $lookup: {
                    from: "magazine_categories",
                    localField: "_id",
                    foreignField: "_id",
                    as: "category"
                }
            },
            { $unwind: { path: "$category", preserveNullAndEmptyArrays: true } },
            {
                $project: {
                    _id: 0,
                    magazine_category_id: "$_id",
                    count: 1,
                    category: {
                        _id: "$category._id",
                        title_en: "$category.title_en",
                        title_ar: "$category.title_ar",
                        title_fr: "$category.title_fr",
                        image: "$category.image"
                    }
                }
            },
            { $sort: { count: -1 } }
        ];

        const data = await Magazine.aggregate(pipeline);
        return apiResponse(res, false, [], '', SUCCESS.OK, data.length, data, req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}

// list by id
exports.blogListingById = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { blog_id, is_read } = req.body
        var filteredQuery = {}
        let page, limit: number;



        page = req.query.page ? parseInt(req.query.page) - 1 : 0;
        limit = req.query.limit ? parseInt(req.query.limit) : 10;
        filteredQuery = {
            is_deleted: false,
            is_active: true,
            _id: new mongoose.Types.ObjectId(blog_id)
        }
        // const [data, count] = await Promise.all([
        let data = await Blog.find(filteredQuery, { _id: 1, title_en: 1, title_ar: 1, title_fr: 1, description_en: 1, description_ar: 1, description_fr: 1, blog_pic: 1, createdAt: 1 }).sort({ createdAt: -1 }).skip(page * limit).limit(limit)
        let count = await Blog.countDocuments(filteredQuery)
        // ]);
        return apiResponse(res, false, [], '', SUCCESS.OK, count, data[0], req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}




// list by id
exports.magazineListingById = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { magazine_id, is_read } = req.body
        var filteredQuery = {}
        let page, limit: number;



        page = req.query.page ? parseInt(req.query.page) - 1 : 0;
        limit = req.query.limit ? parseInt(req.query.limit) : 10;
        filteredQuery = {
            is_deleted: false,
            is_active: true,
            _id: new mongoose.Types.ObjectId(magazine_id)
        }
        // const [data, count] = await Promise.all([
        let data = await Magazine.find(filteredQuery, { _id: 1, title_en: 1, title_ar: 1, title_fr: 1, description_en: 1, description_ar: 1, description_fr: 1, magazine_pic: 1, createdAt: 1 }).sort({ createdAt: -1 }).skip(page * limit).limit(limit)
        let count = await Magazine.countDocuments(filteredQuery)
        // ]);
        return apiResponse(res, false, [], '', SUCCESS.OK, count, data[0], req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}


exports.MagazineCategoryList = async (req, res) => {

    const { id } = req.body

    const lang = req.headers["accept-language"] || 'en'
    let record = await MagazineCategory.find({});
    let count = await MagazineCategory.countDocuments({})
    if (record) {

        return apiResponse(res, false, [], '', SUCCESS.OK, count, record, req)
    }

    return apiResponse(res, true, [], ERROR_MSG[`NO-RECORD-FOUND-${lang}`], CLIENT_ERROR.badRequest, 0, [], req);

}


// listing state city from country code
exports.departmentCityListing = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { country_code } = req.body;
        if(country_code)
        {
            let data = await DepartmentCity.find({ country_code: country_code })
            let count = await DepartmentCity.countDocuments({ country_code: country_code })
            return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
        }
        else
        {
             let data = await DepartmentCity.find({  })
            let count = await DepartmentCity.countDocuments({  })
            return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
        }
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}

// munciplte listing

exports.departmentWaliyaListing = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { wilaya_code } = req.body
        if(wilaya_code)
        {
            let data = await DepartmentCity.find({ wilaya_code: wilaya_code })
            let count = await DepartmentCity.countDocuments({ wilaya_code: wilaya_code })
            return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
        }
        else
        {
             let data = await DepartmentCity.find({  })
            let count = await DepartmentCity.countDocuments({  })
            return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
        }
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}

exports.allDoctorHospitalByNameListing = async (req, res) => {
    var title_lang = 'en';


    try {
        const { name_search, location , patient_id } = req.body;

        let conditionFetchRole = {
            $or: [
                {
                    title: "doctor"
                },
                {
                    title: "hospital"
                }
            ]
        }

        const fetchUserRole = await Role.find(conditionFetchRole);
        if (fetchUserRole && fetchUserRole.length > 0) {
            var filteredQuery = {}
            let ids_user_role = [];
            fetchUserRole.map(async (p) => {
                await ids_user_role.push(new mongoose.Types.ObjectId(p._id));
            })


            filteredQuery['user_role'] = {
                $in: ids_user_role
            };

            filteredQuery['user_account_status'] = "APPROVED";
            filteredQuery['is_account_active'] = true;
            filteredQuery['is_deleted'] = false;
            filteredQuery['is_completed'] = true;

            if (location && location.length > 0) {
                let KM = 50
                filteredQuery['location'] = { $geoWithin: { $centerSphere: [location, KM / 6378.1] } }
            }

            if (name_search && name_search.length > 0) {
                const nameRegex = new RegExp(name_search, 'i'); // 'i' for case-insensitive


                let findCategories = await Category.find({
                    $or: [
                        {
                            title_en: nameRegex
                        },
                        {
                            title_ar: nameRegex
                        },
                        {
                            title_fr: nameRegex
                        }
                    ]
                });

                let catIds = [];
                findCategories.map(s => {
                    catIds.push(s._id.toString());
                });


                filteredQuery['$or'] = [
                    { first_name: nameRegex },
                    { last_name: nameRegex },
                    { $expr: { $regexMatch: { input: { $concat: ["$first_name", " ", "$last_name"] }, regex: nameRegex } } },
                    {
                        primary_specialty: {
                            $in: catIds
                        }
                    }
                ];

            }

            const matchConditions = [];
            let lookupStage = {}
            matchConditions.push({ $eq: ["$hospital_doctor_id", "$$doctorId"] });
            matchConditions.push({ $eq: ["$is_blocked_user", true] });
            if (patient_id) {
                matchConditions.push({ $eq: ["$patient_id", new mongoose.Types.ObjectId(patient_id)] });
            }
            lookupStage = {
                    $lookup: {
                        from: "block-users",
                        let: { doctorId: "$_id" },
                        pipeline: [
                        {
                            $match: {
                            $expr: {
                                $and: matchConditions
                            }
                            }
                        }
                        ],
                        as: "blocked_info"
                    }
                };

            let blocedFilter = {} ;
            if(patient_id)
            {
                blocedFilter =  {
                        blocked_info: { $eq: [] }
                        }
            }
            
            const [data, count] = await Promise.all([
                User.aggregate([
                    { $match: filteredQuery },
                    { $sort: { createdAt: -1 } },
                    {
                        $lookup: {
                            from: "roles",
                            as: "role_of_user",
                            let: { user_role: "$user_role" },
                            pipeline: [
                                {
                                    $match: {

                                        $expr: { $eq: ["$$user_role", "$_id"] },
                                    }
                                },
                            ],
                        },
                    },
                    {
                        $unwind: {
                            path: '$role_of_user',
                            preserveNullAndEmptyArrays: true,
                        },
                    }, 
                    lookupStage,
                    {
                        $match:blocedFilter
                    },
                    {
                        $lookup: {
                            from: "categories",
                            as: "selected_speciality",
                            let: { primary_specialty: "$primary_specialty" },
                            pipeline: [
                                {
                                    $match: {
                                        //$expr: { $in: ["$_id", "$$primary_specialty"] }
                                        "$expr": {
                                            "$cond": {
                                                "if": { "$isArray": "$$primary_specialty" },
                                                "then": { "$in": ["$_id", "$$primary_specialty"] },
                                                "else": { "$eq": ["$primary_specialty", "$_id"] }
                                            }
                                        }
                                    }
                                },
                                {
                                    $project: {
                                        _id: 1,
                                        title_ar: 1,
                                        title_en: 1,
                                        title_fr: 1,
                                        image: 1
                                    }
                                }
                            ],
                        },

                    },

                    {
                        $lookup: {
                            from: "languages",
                            as: "selected_language",
                            let: { spoken_language: "$spoken_language" },
                            pipeline: [
                                {
                                    $match: {
                                        "$expr": {
                                            "$cond": {
                                                "if": { "$isArray": "$$spoken_language" },
                                                "then": { "$in": ["$_id", "$$spoken_language"] },
                                                "else": { "$eq": ["$spoken_language", "$_id"] }
                                            }
                                        }
                                    }
                                },
                                {
                                    $project: {
                                        _id: 1,
                                        title: 1
                                    }
                                }
                            ],
                        },

                    }
                ]),
                User.countDocuments(filteredQuery)
            ]);
            return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
        } else {
            return apiResponse(res, false, [], '', SUCCESS.OK, 0, [], req)
        }


    } catch (error) {
        console.log(error)
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${title_lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}

exports.getTranslateLanguage = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { is_active } = req.body;
        const [data, count] = await Promise.all([
            LanguageTranslate.find({ is_deleted: false, is_active: true }),
            LanguageTranslate.countDocuments({ is_deleted: false, is_active: true })
        ]);
        return apiResponse(res, false, [], '', SUCCESS.OK, count, data, req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}

//appointment  count for app

exports.appointmentCount = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { user_id } = req.body
        let user = await User.findOne({ _id: new mongoose.Types.ObjectId(user_id) }, { user_role: 1 })
        let role = await Role.findOne({ _id: new mongoose.Types.ObjectId(user.user_role) });

        let query = {};
        if (role.title === "patient") {
            query['patient_id'] = new mongoose.Types.ObjectId(user_id)
        } else {
            query['hospital_doctor_id'] = new mongoose.Types.ObjectId(user_id)
        }
        let startDate = new Date();
        let endDate = new Date(startDate.getFullYear(), startDate.getMonth() + 1, 0);
        //change filteredquery status acccording to count
        // console.log(query);

        let approvedFiltered = {}
        let approvedFilteredWithRescheduled = {}

        let approvedEndDate = new Date(new Date().setDate(new Date().getDate() + 30));
        approvedEndDate.setUTCHours(23, 59, 59);
        approvedFiltered['booking_date'] = { $gt: approvedEndDate }
        approvedFiltered['status'] = "APPROVED";

        approvedFilteredWithRescheduled['reschedule_date'] = { $gt: approvedEndDate }
        approvedFilteredWithRescheduled['status'] = "APPROVED";

        let approved_count = await BookingAppointment.countDocuments({
            $or: [
                approvedFiltered,
                approvedFilteredWithRescheduled
            ],
            ...query
        })


        //change filteredquery status acccording to count

        let pending_count = await BookingAppointment.countDocuments({ ...query, status: 'PENDING' })


        //change filteredquery status acccording to count

        let rejected_count = await BookingAppointment.countDocuments({ ...query, status: 'REJECTED' })



        //change filteredquery status acccording to count

        let completed_count = await BookingAppointment.countDocuments({ ...query, status: 'COMPLETED' })



        //upcoming count case

        let upcomingFiltered = {}
        let upcomingFilteredWithRescheduled = {}

        let upcEndDate = new Date(new Date().setDate(new Date().getDate() + 30));
        let upcStrtDate =new Date(new Date().setDate(new Date().getDate() + 1));
        upcStrtDate.setUTCHours(0, 0,0,0);
        upcEndDate.setUTCHours(23, 59, 59);
        upcomingFiltered['$and'] = [
            { booking_date : { $gte: upcStrtDate, $lte: upcEndDate }},
            { reschedule_date: null }
        ];
        upcomingFiltered['status'] = "APPROVED";

        upcomingFilteredWithRescheduled['reschedule_date'] = { $gte: startDate, $lte: upcEndDate }
        upcomingFilteredWithRescheduled['status'] = "APPROVED";


        let upcomingCountCondition = {
            $or: [
                upcomingFiltered,
                upcomingFilteredWithRescheduled
            ],
            ...query
        }

        let upcoming_count = await BookingAppointment.countDocuments(upcomingCountCondition)



        // //case of today count
        let filteredQuery = {}
        let filteredQueryWithRescheduled = {}
        let today = new Date(); // This gets the current date and time
        today.setUTCHours(0, 0, 0, 0); // Set time to the beginning of the day in UTC
        let tomorrow = new Date(today); // Clone the today date object
        tomorrow.setUTCDate(today.getUTCDate() + 1);
        // console.log(today, tomorrow);

        filteredQuery['$and'] = [
            { booking_date: { $gte: today, $lt: tomorrow } },
            { reschedule_date: null }
        ];
        filteredQuery['status'] = "APPROVED";

        filteredQueryWithRescheduled['reschedule_date'] = { $gte: today, $lt: tomorrow }
        filteredQueryWithRescheduled['status'] = "APPROVED";
        console.log(filteredQuery, filteredQueryWithRescheduled);


        let todayCountCondition = {
            $or: [
                filteredQuery,
                filteredQueryWithRescheduled
            ],
            ...query
        }


        let today_count = await BookingAppointment.countDocuments(todayCountCondition)

        let data = [
            {
                "status": "Pending",
                "count": pending_count,
            },
            {
                "status": "Approved",
                "count": approved_count,
            },
            {
                "status": "Rejected",
                "count": rejected_count,
            },
            {
                "status": "Completed",
                "count": completed_count,
            },
            {
                "status": "Today",
                "count": today_count,
            },
            {
                "status": "Upcoming",
                "count": upcoming_count,
            },
        ]
        return apiResponse(res, false, [], '', SUCCESS.OK, 0, data, req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}


exports.createHopitalDoctorEmployee = async (req, res) => {
    let lang = req.headers["accept-language"] || 'en';
    const { email, user_role, phone_number, device_token, device_type } = req.body;
    try {
        let existingPhoneUser
        if (phone_number && phone_number != null) {
            existingPhoneUser = await User.findOne(
                { "phone_number.nationalNumber": phone_number.nationalNumber  , hospital_id : req.body.hospital_id},
                { _id: 1, is_completed: 1, email: 1, phone_number: 1, is_signup: 1, is_signup_otp_varify: 1, is_verified: 1 }
            );
        }
        let existingEmailUser = await User.findOne(
            { "email": email , hospital_id : req.body.hospital_id },
            { _id: 1, is_completed: 1, email: 1, phone_number: 1, is_signup: 1, is_signup_otp_varify: 1, is_verified: 1 }
        );
        let existingUser = (existingPhoneUser && existingPhoneUser != null) ? existingPhoneUser : existingEmailUser
        //fetch Role
        let role = await Role.findOne(
            { title: 'doctor' },
            { _id: 1 }
        );
        if (existingUser && existingUser.is_signup == true && existingUser.is_signup_otp_varify == true) {
            if (existingPhoneUser && existingPhoneUser.phone_number != null) {
                return apiResponse(res, true, [], ERROR_MSG[`PHONE-ALREADY-EXIST-${lang}`], CLIENT_ERROR.badRequest, 0, [], req);
            }
            else {
                return apiResponse(res, true, [], ERROR_MSG[`EMAIL-ALREADY-EXIST-${lang}`], CLIENT_ERROR.badRequest, 0, [], req);
            }
        }
        
        if (!existingUser) {
            req.body['is_signup_otp_varify'] = true;
            var newUser = new User(_.pick(req.body, ['title', 'first_name', 'middle_name', 'last_name', 'dob', 'phone_number', 'user_role', 'email', 'gender', 'device_data', 'password', 'social_security_number', 'branch_of_medicines', 'primary_specialty', 'additional_specialty', 'qualification', 'year_of_practice', 'additional_qualification', 'spoken_language', 'certificate', 'clinic_name', 'clinic_contact', 'clinic_open_time', 'clinic_close_time', 'street_address', 'location', 'primary_specialty_name', 'show_email', 'doctor_present', 'clinic_timing', 'is_fulltime', 'clinic_municipality', 'clinic_department', 'is_completed', 'hospital_name', 'hospital_id' , 'spoken_language_name']));
            newUser['email'] = req.body.email.toLowerCase();
            newUser['is_completed'] = true;
            newUser['is_fulltime'] = true;
            function maskEmail(email) {
                // Split the email address into local part and domain part
                var parts = email.split('@');

                // Replace characters in the local part except for the first two characters
                var maskedLocalPart = parts[0].substring(0, 2) + parts[0].substring(2).replace(/./g, '*');

                // Return the masked email address
                return maskedLocalPart + '@' + parts[1];
            }
            var maskedEmail = maskEmail(req.body.email.toLowerCase());
            newUser['show_email'] = maskedEmail
            if (user_role) {
                newUser['user_role'] = role['_id']
            }
            newUser['user_account_status'] = 'APPROVED'
            
            newUser['last_digit_phone'] = phone_number.e164Number.slice(-4)
            newUser['is_signup'] = true
            await newUser.save()
                .then(async function (user) {
                    const token = await userObject.generateToken(user.salt_key);//generate token
                    
                    let updatedData = {
                        $set: { account_verify_token: token },
                        $push: { auth_token: token },

                    }
                    let userData = await User.findOneAndUpdate({ _id: user._id }, updatedData, { new: true },)

                    return apiResponse(res, false, [], SUCCESS_MSG[`OTP-SEND-${lang}`], SUCCESS.OK, 0, userData, req)
                })
        }
    } catch (error) {
        console.log(error);
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}

exports.contactUs = async (req, res) => {
    let lang = req.headers["accept-language"] || 'en';

    let userInfoData = await User.findOne({ _id: req.body.user_id });
    if (!userInfoData) return apiResponse(res, true, [], ERROR_MSG[`ACCOUNT-NOT-EXIST-${lang}`], CLIENT_ERROR.badRequest, 0, [], req);

    console.log(req.body);

    // Ensure attachments is always an array
    let attachments = [];
    if (Array.isArray(req.body.attachments)) {
        attachments = req.body.attachments;
    } else if (req.body.attachments) {
        attachments = [req.body.attachments];
    }

    // Generate random 6-digit ticket id as string with retry on collision
    async function generateUniqueTicketId() {
        const maxAttempts = 5;
        for (let i = 0; i < maxAttempts; i++) {
            const id = Math.floor(100000 + Math.random() * 900000).toString();
            const existing = await Contact.findOne({ ticket_id: id }).lean();
            if (!existing) return id;
        }
        // As a last resort, append a random letter to reduce collision
        const fallback = Math.floor(100000 + Math.random() * 900000).toString() + String.fromCharCode(65 + Math.floor(Math.random() * 26));
        return fallback;
    }
    const ticketId = await generateUniqueTicketId();

    var newContact = new Contact({
        subject: req.body.subject,
        description: req.body.description,
        attachments: attachments,
        user_id: req.body.user_id,
        ticket_id: ticketId,
    });

    newContact.save()
        .then(async function (contact) {
            let link = `${process.env.WEB_ENDPOINT}`;
            let subject = contact.subject;
            let templateData = contactUsTemplate({ subject, link });
            const mailOptions = {
                to: contact.email,
                subject: templateData.subject,
                html: templateData.html
            };
            let isEmailSent = await sendEmail(mailOptions, res);
            let sentStatus = 'PENDING';
            if (isEmailSent) {
                sentStatus = 'SUCCESS';
            }
            let cronPostParams = {
                "user_id": contact._id,
                "email_to": contact.email,
                "email_subject": templateData.subject,
                "email_content": templateData.html,
                "cron_email_type": "CONTACT_US",
                "cron_email_status": sentStatus
            };
            let saveEmail = new CronEmail(cronPostParams);
            saveEmail.save();

            let userData = _.pick(contact, ['_id', 'ticket_id']);

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



exports.contactListing = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {

        console.log("req.body", req.body);
        console.log("req.query", req.query);

        const { patient_id, list_type } = req.body;

        let filteredQuery: any = { is_deleted: false };

        let page = req.query.page ? parseInt(req.query.page) - 1 : 0;
        let limit = 10;

        if (patient_id) {
            filteredQuery['user_id'] = patient_id;
        }

        // ✅ Add status condition (only if not "All")
        if (list_type && list_type !== "All") {
            filteredQuery['status'] = list_type;
        }

        const [data, count] = await Promise.all([
            Contact.find(filteredQuery)
                .sort({ createdAt: -1 })
                .skip(page * limit)
                .limit(limit)
                .populate("user_id", "first_name last_name"),
            Contact.countDocuments(filteredQuery)
        ]);

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

exports.contactDetails = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { ticketId } = req.params;
        const contact = await Contact.findById(ticketId).populate("user_id", "first_name last_name");
        if (!contact) {
            return apiResponse(res, true, [], ERROR_MSG[`CONTACT-NOT-FOUND-${lang}`], SERVER_ERROR.notFound, 0, [], req)
        }

        const replies = await ContactReply.find({
            contact_id: ticketId,
            is_deleted: false
        }).populate("assigned_by_admin_id assigned_to_admin_id", "first_name last_name email");

        const merged = {
            ...contact.toObject(),
            contactReply: replies
        };
        return apiResponse(res, false, [], '', SUCCESS.OK, 1, merged, req)
    } catch (error) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
    }
}

// Return counts for Contact tickets: All and by status
exports.contactListingCount = async (req, res) => {
    const lang = req.headers["accept-language"] || 'en'
    try {
        const { patient_id } = req.body;
        const baseFilter: any = { is_deleted: false };
        if (patient_id) {
            baseFilter['user_id'] = patient_id;
        }

        const [
            all_count,
            open_count,
            in_progress_count,
            resolved_count,
            closed_count
        ] = await Promise.all([
            Contact.countDocuments(baseFilter),
            Contact.countDocuments({ ...baseFilter, status: 'open' }),
            Contact.countDocuments({ ...baseFilter, status: 'in_progress' }),
            Contact.countDocuments({ ...baseFilter, status: 'resolved' }),
            Contact.countDocuments({ ...baseFilter, status: 'closed' })
        ]);

        const data = [
            { status: 'All', count: all_count },
            { status: 'open', count: open_count },
            { status: 'in_progress', count: in_progress_count },
            { status: 'resolved', count: resolved_count },
            { status: 'closed', count: closed_count }
        ];

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