/*
@swagger
components:
schemas:
	Book:
		type: object
required:
	- title
	- author
	- finished
properties:
	id:
		type: integer
description: The auto-generated id of the book.
	title:
type: string
description: The title of your book.
	author:
type: string
description: Who wrote the book?
	finished:
	type: boolean
description: Have you finished reading it?
	createdAt:
	type: string
format: date
description: The date of the record creation.
	example:
title: The Pragmatic Programmer
author: Andy Hunt / Dave Thomas
finished: true
*/
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, Post, teamPicture, TeamInvite, userWall, StaffApplications, AdminToken, PassKey, Thread, Category, Sequelize, Ip, Ban, sequelize, Team, TeamMembers, TeamRoles
} = require('../models')
let pagination = require('../lib/pagination.js')
const sgMail = require('@sendgrid/mail');
const MailGen = require('mailgen')
const crypto = require("crypto")
const cryptoRandomString = require("crypto-random-string")
let Promise = require('bluebird');
const rateLimit = require("express-rate-limit");
let upload = multer({
    storage: multer.memoryStorage(),
    limits:{
        fileSize: 1024 * 1024
    }
})

const emailLimiter = rateLimit({
    windowMs: 60000,
    max: 1, // limit each IP to 100 requests per windowMs
    message: "{\"errors\":[{\"name\":\"rateLimit\",\"message\":\"You may only make 1 request to this endpoint per minute.\",\"status\":429}]}"
});

router.post('/:username/picture', auth, upload.single('picture'), async (req, res, next) => {
    try {
        let user = await Team.findOne({
            where: {
                username: req.params.username
            }
        })
        let picture = await teamPicture.findOne({
                where: { TeamId: user.id }
            })

            let pictureObj = {
                file: req.file.buffer,
                mimetype: req.file.mimetype,
                TeamId: user.id
            }

            //No picture set yet
            if(!picture) {
                await teamPicture.create(pictureObj)
            } else {
                await picture.update(pictureObj)
            }

            //Add random query to end to force browser to reload background images
            await user.update({
                picture: '/api/v1/teams/view/' + req.params.username + '/picture?rand=' + Date.now()
            })

            res.json(user.toJSON())
    } catch (e) { next(e) }
})

router.put('/modify/:username', auth, async(req, res, next) => {
    try {
        if(!req.userData.username) {
            throw Errors.requestNotAuthorized
        }
        await Ban.ReadOnlyMode(req.userData.UserId)
        let user1 = await Team.findOne({ where: {
                username: req.params.username
            }})
        let user2 = await User.findOne({ where: {
                username: req.userData.username
            }})
        console.log(user1.OwnerId, user2.id)
        if(user1 && user2.id === user1.OwnerId) {
        if(req.autosan.body.description !== undefined, req.autosan.body.name !== undefined) {

            let user = await Team.update({description: req.autosan.body.description, name: req.autosan.body.name}, {
                where: {
                    username: req.params.username
                }
            })
            res.status(200)
            res.json({success: true})
        } else {
            throw Errors.requestNotAuthorized
        }
        } else {
            throw Errors.requestNotAuthorized
        }
    } catch (e) { next(e) }
})

router.post('/roles/create/:username', auth, async(req, res, next) => {
    try {
        let team = await Team.findOne({
            where: {username: req.params.username}
        });
        if(team) {
            let queryObj3 = {
                where: {userId: req.userData.UserId, teamId: team.id},
            }
            if(team.banned) {
                res.status(200)
                res.json({success: false})
            }
            let teamJoinTest = await TeamMembers.findOne(queryObj3)
            if (teamJoinTest) {
                let makeRole = {
                    name: req.body.name,
                    administrator: req.body.administrator,
                    inviteUsers: req.body.inviteUsers,
                    changeTeamMeta: req.body.changeTeamMeta,
                    forumAdministrator: req.body.forumAdministrator,
                    moderateForumThreads: req.body.moderateForumThreads,
                    changeTeamPrivacy: req.body.changeTeamPrivacy,
                    submitTeamItems: req.body.submitTeamItems,
                    priority: req.body.priority,
                    teamId: team.id
                }
                let teamCreate = await TeamRoles.create(makeRole)
                res.status(200)
                res.json(teamCreate.toJSON())
            } else if (!teamJoinTest) {
                res.status(400)
                res.json({success: false})
            }
        } else {
            throw Errors.teamDoesNotExist
        }
    } catch (e) { next(e) }
})

router.put('/roles/modify/:username/:id', auth, async(req, res, next) => {
    try {
        let team = await Team.findOne({
            where: {username: req.params.username}
        });
        if(team) {
            let queryObj3 = {
                where: {userId: req.userData.UserId, teamId: team.id},
            }
            if(team.banned) {
                res.status(200)
                res.json({success: false})
            }
            let teamJoinTest = await TeamMembers.findOne(queryObj3)
            if (teamJoinTest) {
                if(req.body.name) {
                    let find = await TeamRoles.findOne({
                        where: {
                            id: req.params.id,
                            teamId: team.id
                        }
                    })
                    if(find) {
                        let update = await TeamRoles.update({
                            priority: req.body.priority,
                            name: req.body.name,
                            administrator: req.body.administrator,
                            inviteUsers: req.body.inviteUsers,
                            changeTeamMeta: req.body.changeTeamMeta,
                            forumAdministrator: req.body.forumAdministrator,
                            moderateForumThreads: req.body.moderateForumThreads,
                            changeTeamPrivacy: req.body.changeTeamPrivacy,
                            submitTeamItems: req.body.submitTeamItems,
                        }, {
                            where: {
                                id: req.params.id,
                                teamId: team.id
                            }
                        })
                        res.status(200)
                        res.json({success: true})
                    } else {
                        res.status(400)
                        res.json({success: false})
                    }
                } else if(req.body.priority && !req.body.name) {
                    let find = await TeamRoles.findOne({
                        where: {
                            id: req.params.id,
                            teamId: team.id
                        }
                    })
                    if(find) {
                        await TeamRoles.update({priority: req.body.priority}, {
                            where: {
                                id: req.params.id,
                                teamId: team.id
                            }
                        })
                        res.status(200)
                        res.json({success:true})
                    } else {
                        res.status(400)
                        res.json({success: false})
                    }
                } else {
                    res.status(400)
                    res.json({success: false})
                }
            } else if (!teamJoinTest) {
                res.status(400)
                res.json({success: false})
            }
        } else {
            throw Errors.teamDoesNotExist
        }
    } catch (e) { next(e) }
})

router.put('/:username/invites/create', auth, async(req, res, next) => {
try {
    let team = await Team.findOne({
        where: {username: req.params.username}
    });
    if(team) {
        let create = await TeamInvite.create({
            maxUses: req.body.maxUses,
            RoleId: req.body.RoleId,
            TeamId: team.id,
            UserId: req.userData.UserId,
            code: crypto.randomBytes(20).toString('hex')
        })
        let createJSON = create.toJSON()
        res.status(200)
        res.json(createJSON)
    } else {
        throw Errors.teamDoesNotExist
    }
} catch (e) { next(e) }
})

router.get('/:username/invites/list', auth, async(req, res, next) => {
    try {
        let team = await Team.findOne({
            where: {username: req.params.username}
        });
        if(team) {
            let roles = await TeamInvite.findAll({
                where: {
                    TeamId: team.id
                },
                include: { model: User, attributes: ['username', 'createdAt', 'id', 'color', 'picture', 'locked', 'admin', 'booster', 'executive', 'bot'] },
            })
            res.status(200)
            res.json(roles)
        } else {
            throw Errors.teamDoesNotExist
        }
    } catch (e) { next(e) }
})

router.delete('/:username/invites/delete/:code', auth, async(req, res, next) => {
    try {
        let team = await Team.findOne({
            where: {username: req.params.username}
        });
        if(team) {
            let code = await TeamInvite.findOne({
                where: {code: req.params.code, TeamId: team.id}
            });
            if(code) {
                await code.killInvite(req.params.code)
                res.status(200)
                res.json({success: true})
            } else {
                throw Errors.inviteInvalid
            }
        } else {
            throw Errors.teamDoesNotExist
        }
    } catch (e) { next(e) }
})

module.exports = router;
