
const _ = require('lodash');
require('dotenv').config()
const mongoose = require("mongoose");
const { Admin } = require('../../models/admin/admin');
const { Role } = require('../../models/role');
const { apiResponse } = require("../../core/response/response")
const { CronEmail } = require('../../models/email')
const { dateFormat } = require('../../core/utilities/commonService');
const { SUCCESS, REDIRECTION, CLIENT_ERROR, SERVER_ERROR } = require("../../core/response/statusCode")
const { ERROR_MSG, SUCCESS_MSG } = require("../../core/response/messages")
const { sendEmail } = require('../../core/utilities/emailService');
const { addAdminTemplate, spaceAccountTemplate } = require('../../core/email-templates/email-admin');

export { };

exports.adminAdd = async (req, res) => {
    let lang1 = 'en'
    // If no validation errors, get the req.body objects that were validated and are needed
    const { id, first_name, last_name, email, password } = req.body;
    if (_.has(req.body, ['id']) && (req.body.id) != null) {

        let condition = {}
        condition['_id'] = new mongoose.Types.ObjectId(id);

        //checking record exist
        let record = await Admin.findOne(condition, { _id: 1 });
        if (!record) return apiResponse(res, true, [], ERROR_MSG[`NO-RECORD-FOUND-${lang1}`], CLIENT_ERROR.badRequest, 0, [], req);
        //update Admin
        try {
            let setting = await Admin.findOneAndUpdate({ _id:new mongoose.Types.ObjectId(req.body.id) }, { $set: req.body }, { new: true },)
            return apiResponse(res, false, [], '', SUCCESS.OK, 0, [setting], req);
        } catch (err) {
            return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang1}`], SERVER_ERROR.internalServerError, 0, []);
        }

    } else {
        //checking unique email
        let existingUser = await Admin.findOne(
            { 
                email: email,
                is_deleted: false
            }
        );

        if (existingUser) return apiResponse(res, true, [], ERROR_MSG[`EMAIL-ALREADY-EXIST-${lang1}`], CLIENT_ERROR.badRequest, 0, [], req);

        //save user 
        let newAdmin = new Admin(_.pick(req.body, ['first_name', 'last_name', 'email', 'password', 'phone_number', 'profile_pic', 'is_active', 'salt_key', 'device_data']));



        newAdmin.save().then(async function (user) {
            {



                let link = `${process.env.WEB_ENDPOINT_ADMIN}`;
                let fullName = `${first_name} ${last_name}`
                let templateData = addAdminTemplate({ link, fullName, email, password })
                const mailOptions = {
                    to: user.email,
                    subject: templateData.subject,
                    html: templateData.html
                };
                let isEmailSent = await sendEmail(mailOptions, res)
                let sentStatus = 'PENDING'
                if (isEmailSent) {
                    sentStatus = 'SUCCESS'
                }
                let cronPostParams = {
                    "user_id": user._id,
                    "email_to": user.email,
                    "email_subject": templateData.subject,
                    "email_content": templateData.html,
                    "cron_email_type": "NEW_ADMIN",
                    "cron_email_status": sentStatus
                }
                let saveEmail = new CronEmail(cronPostParams)
                saveEmail.save()

                // await User.findOneAndUpdate({ _id: user._id }, { $set: { auth_token: token } }, { new: true })

                let userData = _.pick(user, ['_id', 'first_name', 'last_name', 'email'])
                return apiResponse(res, false, [], '', SUCCESS.OK, 0, userData, req)

            };

        })
            .catch(function (err) {
                return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang1}`], SERVER_ERROR.internalServerError, 0, [], req)
            });



    }

}

exports.adminListing = async (req, res) => {
    let lang = 'en'
    try {
        const { first_name, last_name, email, createdAt, updatedAt, is_active } = req.body
        var filteredQuery = {}
        let page, limit: number;
        let fname_regex = new RegExp(first_name, 'i');
        let lname_regex = new RegExp(last_name, 'i');
        let email_regex = new RegExp(email, 'i');
        if (req.query.search) {
            var createdDate = new Date(dateFormat(createdAt, 'yyyy-MM-dd'));
            var updatedDate = new Date(dateFormat(updatedAt, 'yyyy-MM-dd'));
            createdDate.setDate(createdDate.getDate() + 1)
            updatedDate.setDate(updatedDate.getDate() + 1)
            page = req.query.page ? parseInt(req.query.page) - 1 : 0;
            limit = 10;
            const filter_fname = (first_name && first_name != 'undefined') ? { first_name: fname_regex } : {};
            const filter_lname = (last_name && last_name != 'undefined') ? { last_name: lname_regex } : {};
            const filter_email = (email && email != 'undefined') ? { email: email_regex } : {};
            const filter_createdAt = (createdAt && createdAt != 'undefined') ? { createdAt: { $gte: new Date(dateFormat(createdAt, 'yyyy-MM-dd')), $lt: new Date(dateFormat(createdDate, 'yyyy-MM-dd')) } } : {};
            const filter_updatedAt = (updatedAt && updatedAt != 'undefined') ? { updatedAt: { $gte: new Date(dateFormat(updatedAt, 'yyyy-MM-dd')), $lt: new Date(dateFormat(updatedDate, 'yyyy-MM-dd')) } } : {};
            filteredQuery = { ...filter_fname, ...filter_lname, ...filter_email, ...filter_createdAt, ...filter_updatedAt, is_deleted: false, is_super_admin: false }
        } else {
            page = req.query.page ? parseInt(req.query.page) - 1 : 0;
            limit = 10;
            filteredQuery = {
                is_deleted: false, is_super_admin: false
            }
        }
        if (is_active) {
            filteredQuery['is_active'] = is_active
        }
        if (is_active == false) {
            filteredQuery['is_active'] = is_active
        }
        const [data, count] = await Promise.all([
            Admin.find(filteredQuery).sort({ createdAt: -1 }).skip(page * limit).limit(limit),
            Admin.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.changeAdminStatus = async (req, res) => {
    let lang = 'en'
    const { id, status } = req.body
    let condition = {}
    condition['_id'] = new mongoose.Types.ObjectId(id);

    let record = await Admin.findOne(condition, { _id: 1 });

    if (record) {
        await Admin.findOneAndUpdate(condition, { $set: { is_active: status } }, { new: true })

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

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

}

// delete admin
exports.deleteAdmin = async (req, res) => {
    let lang = 'en'
    try {
        const id = req.body.id;
        let cres = await Admin.findOneAndUpdate({ _id: new mongoose.Types.ObjectId(id) }, { $set: { is_deleted: true } }, { new: true })
        if (cres) {
            return apiResponse(res, false, [], '', SUCCESS.OK, 0, [cres], req);
        } else {
            return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [], req)
        }

    } catch (err) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [])
    }
}

// delete selected category
exports.deleteSelectedAdmin = async (req, res) => {
    let lang = 'en';
    let ids = req.body.id;
    try {
        let cres = await Admin.updateMany({ _id: { $in: ids } }, { $set: { is_deleted: true, updatedAt: new Date() } }, { multi: true, upsert: true, new: true })
        if (cres) {
            return apiResponse(res, false, [], '', SUCCESS.OK, 0, [], req);
        } else {
            return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [])
        }

    } catch (err) {
        return apiResponse(res, true, [], ERROR_MSG[`SYSTEM-ERROR-${lang}`], SERVER_ERROR.internalServerError, 0, [])
    }
}

// get user roles
exports.fetchRoles = async (req, res) => {
    let roles = await Role.find();
    return apiResponse(res, false, [], '', SUCCESS.OK, 0, roles, req);
}

// get admin permissions
exports.getAdminPermissions = async (req, res) => {
    let lang = 'en';
    try {
        const { id } = req.body;
        if (!id) {
            return apiResponse(res, true, [], ERROR_MSG[`INVALID-ID-${lang}`], CLIENT_ERROR.badRequest, 0, [], req);
        }

        let admin = await Admin.findOne(
            { _id: new mongoose.Types.ObjectId(id), is_deleted: false },
            { permissions: 1, first_name: 1, last_name: 1, email: 1 }
        );

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

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

// update admin permissions
exports.updateAdminPermissions = async (req, res) => {
    let lang = 'en';
    try {
        const { id, permissions } = req.body;
        if (!id) {
            return apiResponse(res, true, [], ERROR_MSG[`INVALID-ID-${lang}`], CLIENT_ERROR.badRequest, 0, [], req);
        }

        let admin = await Admin.findOne(
            { _id: new mongoose.Types.ObjectId(id), is_deleted: false },
            { _id: 1 }
        );

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

        let updatedAdmin = await Admin.findOneAndUpdate(
            { _id: new mongoose.Types.ObjectId(id) },
            { $set: { permissions: permissions } },
            { new: true }
        );

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

exports.allAdminListing = async (req, res) => {
    let lang = 'en'
    try {
        var filteredQuery = {}

        filteredQuery = {
            is_deleted: false
        }
        const [data, count] = await Promise.all([
            Admin.find(filteredQuery).sort({ createdAt: -1 }),
            Admin.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)
    }
}
