<?php
namespace Misuzu;

use RuntimeException;
use Misuzu\Users\User;

$urls = $msz->getURLs();
$authInfo = $msz->getAuthInfo();
if($authInfo->isLoggedIn()) {
    Tools::redirect($urls->format('index'));
    return;
}

$authCtx = $msz->getAuthContext();
$usersCtx = $msz->getUsersContext();
$users = $usersCtx->getUsers();
$roles = $usersCtx->getRoles();
$config = $msz->getConfig();

$register = !empty($_POST['register']) && is_array($_POST['register']) ? $_POST['register'] : [];
$notices = [];
$ipAddress = $_SERVER['REMOTE_ADDR'];
$countryCode = $_SERVER['COUNTRY_CODE'] ?? 'XX';

// there is currently no ip banning system.
// because people can have a wide variety of ip address
//  it doesn't make sense to include a single row for it
//  in the user bans table
// add better ip tracking and reintroduce the blacklist
// was thinking of having both a storage table and an expanded table
//  with the storage table contains range syntaxes and whatnot
//  and the expanded table just having seas of raw ips in it with a primary key
//  for fast matching
$restricted = '';

$loginAttempts = $authCtx->getLoginAttempts();
$remainingAttempts = $loginAttempts->countRemainingAttempts($ipAddress);

while(!$restricted && !empty($register)) {
    if(!CSRF::validateRequest()) {
        $notices[] = 'Was unable to verify the request, please try again!';
        break;
    }

    if($remainingAttempts < 1) {
        $notices[] = "There are too many failed login attempts from your IP address, you may not create an account right now.";
        break;
    }

    if(empty($register['username']) || empty($register['password']) || empty($register['email']) || empty($register['question'])
        || !is_string($register['username']) || !is_string($register['password']) || !is_string($register['email']) || !is_string($register['question'])) {
        $notices[] = "You haven't filled in all fields.";
        break;
    }

    $checkSpamBot = mb_strtolower($register['question']);
    $spamBotValid = [
        '21', 'twentyone', 'twenty-one', 'twenty one',
    ];
    $spamBotHint = [
        '19', 'nineteen', 'nine-teen', 'nine teen',
    ];

    if(!in_array($checkSpamBot, $spamBotValid)) {
        if(in_array($checkSpamBot, $spamBotHint))
            $notices[] = '_play_hint';

        $notices[] = 'Human only cool club, robots begone.';
        break;
    }

    $usernameValidation = $users->validateName($register['username']);
    if($usernameValidation !== '')
        $notices[] = $users->validateNameText($usernameValidation);

    $emailValidation = $users->validateEMailAddress($register['email']);
    if($emailValidation !== '')
        $notices[] = $users->validateEMailAddressText($emailValidation);

    if($register['password_confirm'] !== $register['password'])
        $notices[] = 'The given passwords don\'t match.';

    $passwordValidation = $users->validatePassword($register['password']);
    if($passwordValidation !== '')
        $notices[] = $users->validatePasswordText($passwordValidation);

    if(!empty($notices))
        break;

    $defaultRoleInfo = $roles->getDefaultRole();

    try {
        $userInfo = $users->createUser(
            $register['username'],
            $register['password'],
            $register['email'],
            $ipAddress,
            $countryCode,
            $defaultRoleInfo
        );
    } catch(RuntimeException $ex) {
        $notices[] = 'Something went wrong while creating your account, please alert an administrator or a developer about this!';
        break;
    }

    $users->addRoles($userInfo, $defaultRoleInfo);
    $config->setString('users.newest', $userInfo->getId());
    $msz->getPerms()->precalculatePermissions(
        $msz->getForumContext()->getCategories(),
        [$userInfo->getId()]
    );

    Tools::redirect($urls->format('auth-login-welcome', ['username' => $userInfo->getName()]));
    return;
}

Template::render('auth.register', [
    'register_notices' => $notices,
    'register_username' => !empty($register['username']) && is_string($register['username']) ? $register['username'] : '',
    'register_email' => !empty($register['email']) && is_string($register['email']) ? $register['email'] : '',
    'register_restricted' => $restricted,
]);
