let bcrypt = require('bcryptjs')
let multer = require('multer')
let express = require('express')
let router = express.Router()
const auth = require('../lib/auth')
var Recaptcha = require('express-recaptcha').RecaptchaV3;
var recaptcha = new Recaptcha('6LdlbrwZAAAAAKvtcVQhVl_QaNOqmQ4PgyW3SKHy', '6LdlbrwZAAAAAMAWPVDrL8eNPxrws6AMDtLf1bgd');
var reCAPTCHASecret = "6LdlbrwZAAAAAKvtcVQhVl_QaNOqmQ4PgyW3SKHy";
const Errors = require('../lib/errors.js')
var format = require('date-format');
let {
    User, AuditLog, Team, Item, Post, ProfilePicture, StaffApplications, AdminToken, PassKey, Thread, Category, Sequelize, Ip, Ban, sequelize
} = require('../models')
let pagination = require('../lib/pagination.js')

router.all('*', auth, async(req, res, next) => {
    let user = await User.findOne({ where: {
            username: req.userData.username
        }})
    if(!user) throw Errors.requestNotAuthorized
    if(req.userData.admin && user.admin) {
        next()
    } else {
        res.status(401)
        res.json({
            errors: [Errors.sessionAdminProtection]
        })
    }
})

router.put('/user/scrub', auth, async(req, res, next) => {
    try {
        if(!req.userData.admin) {
            throw Errors.requestNotAuthorized
        }
        await Ban.ReadOnlyMode(req.userData.UserId)

        if(req.autosan.body.description === "descscram") {
            let user = await User.findOne({ where: {
                    username: req.autosan.body.user
                }})
            if(user.admin) {
                AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' attempted to modify ' + req.autosan.body.user + ' but an error was thrown (Is admin, scrub description).'})
                throw Errors.modifyAdminUser
            }
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' modified user ' + req.autosan.body.user + ' and succeeded (scrub description).'})
            let userUpdate = await User.update({ description:  "Description was removed by an administrator"}, { where: {
                    username: req.autosan.body.user
                }})
            res.status(200)
            res.json({success: "true"})

        } else if(req.body.username === "usernamescram") {
            let user = await User.findOne({ where: {
                    username: req.autosan.body.user
                }})
            if(user.admin) {
                AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' attempted to modify ' + req.autosan.body.user + ' but an error was thrown (Is admin, scrub username).'})
                throw Errors.modifyAdminUser
            }
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' modified user ' + req.autosan.body.user + ' and succeeded (scrub username).'})
            let userUpdate = await User.update({username: Math.random().toString(36).substring(2)}, {
                where: {
                    username: req.autosan.body.user
                }
            })
            res.json({success: true})
        } else {
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' attempted to modify ' + req.autosan.body.user + ' but an error was thrown (unknown, scrub username).'})
            res.json({ success: false })
        }
    } catch (e) { next(e) }
})

router.put('/user/modify', auth, async(req, res, next) => {
    try {
        if(!req.userData.admin) {
            throw Errors.requestNotAuthorized
        }

        await Ban.ReadOnlyMode(req.userData.UserId)

        if(req.body.username) {
            let user = await User.findOne({ where: {
                    username: req.body.username
                }})
            let user1 = await User.findOne({ where: {
                    username: req.userData.username
                }})
            if(!user) throw Errors.accountDoesNotExist
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' modified ' + req.body.username + ' and succeeded (changed roles).'})
            if(user.admin && !user1.executive) {
                AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' attempted to modify ' + req.body.username + ' but an error was thrown (Is admin, changed roles).'})
                throw Errors.modifyAdminUser
            }
            if(user.executive) {
                AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' attempted to modify ' + req.body.username + ' but an error was thrown (Is executive, changed roles).'})
                throw Errors.modifyAdminUser
            }
            if(user1.executive) {
                AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' modified ' + req.body.username + ' and succeeded (changed roles, executive action).'})
                let userUpdate = await User.update({
                    booster: req.body.booster,
                    bot: req.body.bot,
                    system: req.body.system,
                    admin: req.body.admin,
                    hidden: req.body.hidden
                }, {
                    where: {
                        username: req.body.username
                    }
                })
                res.status(200)
                res.json({success: true})
            } else {
                AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' modified ' + req.body.username + ' and succeeded (changed roles, admin action).'})
                let userUpdate = await User.update({
                    booster: req.body.booster,
                    bot: req.body.bot,
                    system: req.body.system,
                    hidden: req.body.hidden
                }, {
                    where: {
                        username: req.body.username
                    }
                })
                res.status(200)
                res.json({success: true})
            }
        } else {
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' attempted to modify ' + req.body.username + ' but an error was thrown (account does not exist).'})
            res.status(400)
            throw Errors.accountDoesNotExist
        }

    } catch (e) { next(e) }
})

router.get('/privileges', auth, async(req, res, next) => {
    try {
        let queryObj = {
            attributes: {include: ['username', 'admin', 'executive'], exclude: ['hash', 'email', 'emailVerified', 'koins', 'currency2', 'emailToken', 'passwordResetExpiry', 'passwordResetToken', 'experimentMode', 'developerMode', 'cookieOptOut', 'deleteCode', 'jwtOffset', 'description', 'theme', 'contributor', 'passwordResetOptOut', 'picture', 'createdAt', 'updatedAt', 'id']},
            where: {username: req.userData.username}
        }
        let user = await User.findOne(queryObj)
        res.json(user)
    } catch (e) { next(e) }
})

router.get('/teams/pending', auth, async(req, res, next) => {
    try {
        await Ban.isIpBanned(req.ip)

        let team = await Team.findAll({where: {approved: false, banned: false}})
        if(!team) {
            res.status(200)
            res.json({success: false})
        }
        res.json(team)
    } catch (e) { next(e) }
})

router.put('/teams/approve', auth, async(req, res, next) => {
    try {
        await Ban.isIpBanned(req.ip)

        let team = await Team.findOne({where: {username: req.body.username}})
        if(!team) {
            throw Errors.accountDoesNotExist
        }
        if(req.body.approve) {
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' approved the ' + req.body.username + ' team and succeeded (approved team).'})
            await team.update({approved: true});
            res.status(200)
            res.json({success: true})
        } else if(!req.body.approve && req.body.reason) {
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' banned the ' + req.body.username + ' team and succeeded (banned team).'})
            await team.update({banned: true, banReason: req.body.reason})
            res.status(200)
            res.json({success: true})
        } else {
            throw Errors.requestNotAuthorized
        }
    } catch (e) { next(e) }
})

router.get('/marketplace/pending', auth, async(req, res, next) => {
    try {
        await Ban.isIpBanned(req.ip)

        let item = await Item.findAll({where: {approved: false, deleted: false}})
        if(!item) {
            res.status(200)
            res.json({success: false})
        }
        res.json(item)
    } catch (e) { next(e) }
})

router.put('/marketplace/approve', auth, async(req, res, next) => {
    try {
        await Ban.isIpBanned(req.ip)

        let item = await Item.findOne({where: {id: req.body.id}})
        if(!item) {
            throw Errors.accountDoesNotExist
        }
        if(req.body.approve && !req.body.delete) {
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' approved the Marketplace Item MID: ' + req.body.id + ' and succeeded (approved marketplace item).'})
            await item.update({approved: true});
            res.status(200)
            res.json({success: true})
        } else if(req.body.delete && !req.body.approve) {
            AuditLog.create({UserId: req.userData.UserId, action: req.userData.username + ' removed the Marketplace Item MID: ' + req.body.id + ' and succeeded (removed marketplace item).'})
            await item.update({deleted: true});
            res.status(200)
            res.json({success: true})
        } else {
            throw Errors.requestNotAuthorized
        }
    } catch (e) { next(e) }
})

router.get('/logs', auth, async(req, res, next) => {
    try {
        await Ban.isIpBanned(req.ip)

        let logs = await AuditLog.findAll()
        if(!logs) {
            res.status(200)
            res.json({success: false})
        }
        res.json(logs)
    } catch (e) { next(e) }
})
module.exports = router;
