/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2025 Rainbownapkin and the TTN Community

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.*/

//Config
const config = require('../../../../config.json');

//NPM Imports
const {validationResult, matchedData} = require('express-validator');

//local imports
const {userModel} = require('../../../schemas/user/userSchema');
const userBanModel = require('../../../schemas/user/userBanSchema');
const altchaUtils = require('../../../utils/altchaUtils');
const {exceptionHandler, errorHandler} = require('../../../utils/loggerUtils');

module.exports.post = async function(req, res){
    try{
        //Check for validation errors
        const validResult = validationResult(req);

        //If there are none
        if(validResult.isEmpty()){
            //Get sanatized/validated data
            const user = matchedData(req);
            //Verify Altcha Payload
            const verified = await altchaUtils.verify(req.body.verification);

            //If altcha verification failed
            if(!verified){
                return errorHandler(res, 'Altcha verification failed, Please refresh the page!', 'unauthorized');
            }


            //If we're proxied use passthrough IP
            const ip = config.proxied ? req.headers['x-forwarded-for'] : req.ip;

            //Would prefer to stick this in userModel.statics.register() but we end up with circular dependencies >:(
            const nukedBans = await userBanModel.checkProcessedBans(user.user);

            //if we found any related nuked bans
            if(nukedBans != null){
                //Shit our pants!
                return errorHandler(res, 'Cannot re-create banned account!', 'unauthorized');
            }

            //Look for ban by IP
            const ipBanDB = await userBanModel.checkBanByIP(ip);

            //If this ip is randy bobandy
            if(ipBanDB != null){

                //Make the number a little prettier despite the lack of precision since we're not doing calculations here :P
                const expiration = ipBanDB.getDaysUntilExpiration() < 1 ? 0 : ipBanDB.getDaysUntilExpiration();
                let banMsg = [];

                //If the ban is permanent
                if(ipBanDB.permanent){
                    //tell it to fuck off
                    //Make the code and message look pretty (kinda) at the same time
                    banMsg = [
                        'The IP address you are trying to register an account from has been permanently banned.',
                        'Your cleartext IP has been saved to the database.',
                        `Any associated accounts will be nuked in ${expiration} day(s).`,
                        'If you beleive this to be an error feel free to reach out to your server administrator.',
                        'Otherwise, fuck off :)'
                    ];
                }else{
                    //tell it to fuck off
                    //Make the code and message look pretty (kinda) at the same time
                    banMsg = [
                        'The IP address you are trying to register an account from has been temporarily banned.',
                        `Your cleartext IP has been saved to the database until the ban expires in ${expiration} day(s).`,
                        'If you beleive this to be an error feel free to reach out to your server administrator.',
                        'Otherwise, fuck off :)'
                    ];
                }

                //tell it to fuck off
                return errorHandler(res, banMsg.join('<br>'), 'unauthorized');
            }

            //Register off of given IP
            await userModel.register(user, ip);

            return res.sendStatus(200);
        }else{
            res.status(400);
            return res.send({errors: validResult.array()});
        }
    }catch(err){
        return exceptionHandler(res, err);
    }
}