<?php
namespace Misuzu;

use RuntimeException;
use Index\Colour\Colour;
use Index\Colour\ColourRGB;

if(!$msz->isLoggedIn() || !perms_check_user(MSZ_PERMS_USER, $msz->getActiveUser()->getId(), MSZ_PERM_USER_MANAGE_ROLES)) {
    echo render_error(403);
    return;
}

$users = $msz->getUsers();
$roles = $msz->getRoles();

if(filter_has_var(INPUT_GET, 'r')) {
    $roleId = (string)filter_input(INPUT_GET, 'r', FILTER_SANITIZE_NUMBER_INT);

    try {
        $isNew = false;
        $roleInfo = $roles->getRole($roleId);
    } catch(RuntimeException $ex) {
        echo render_error(404);
        return;
    }
} else $isNew = true;

$currentUser = $msz->getActiveUser();
$canEditPerms = perms_check_user(MSZ_PERMS_USER, $currentUser->getId(), MSZ_PERM_USER_MANAGE_PERMS);

if($canEditPerms)
    $permissions = manage_perms_list(perms_get_role_raw($roleId ?? 0));

while($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) {
    $userRank = $users->getUserRank($currentUser);

    if(!$isNew && !$currentUser->isSuperUser() && $roleInfo->getRank() >= $userRank) {
        echo 'You aren\'t allowed to edit this role.';
        break;
    }

    $roleName = (string)filter_input(INPUT_POST, 'ur_name');
    $roleHide = !empty($_POST['ur_hidden']);
    $roleLeavable = !empty($_POST['ur_leavable']);
    $roleRank = (int)filter_input(INPUT_POST, 'ur_rank', FILTER_SANITIZE_NUMBER_INT);
    $roleTitle = (string)filter_input(INPUT_POST, 'ur_title');
    $roleDesc = (string)filter_input(INPUT_POST, 'ur_desc');
    $colourInherit = !empty($_POST['ur_col_inherit']);
    $colourRed = (int)filter_input(INPUT_POST, 'ur_col_red', FILTER_SANITIZE_NUMBER_INT);
    $colourGreen = (int)filter_input(INPUT_POST, 'ur_col_green', FILTER_SANITIZE_NUMBER_INT);
    $colourBlue = (int)filter_input(INPUT_POST, 'ur_col_blue', FILTER_SANITIZE_NUMBER_INT);

    Template::set([
        'role_ur_name' => $roleName,
        'role_ur_hidden' => $roleHide,
        'role_ur_leavable' => $roleLeavable,
        'role_ur_rank' => $roleRank,
        'role_ur_title' => $roleTitle,
        'role_ur_desc' => $roleDesc,
        'role_ur_col_inherit' => $colourInherit,
        'role_ur_col_red' => $colourRed,
        'role_ur_col_green' => $colourGreen,
        'role_ur_col_blue' => $colourBlue,
    ]);

    if(!$currentUser->isSuperUser() && $roleRank >= $userRank) {
        echo 'You aren\'t allowed to make a role with equal rank to your own.';
        break;
    }

    $roleNameLength = mb_strlen($roleName);
    if($roleNameLength < 1 || $roleNameLength > 100) {
        echo 'Provided role name is either too long or too short.';
        break;
    }

    if($roleRank < 1 || $roleRank > 100) {
        echo 'Role rank may not be less than 1 or more than 100.';
        break;
    }

    $roleColour = $colourInherit
        ? Colour::none()
        : new ColourRGB($colourRed, $colourGreen, $colourBlue);

    if(mb_strlen($roleDesc) > 1000) {
        echo 'Description may not be longer than 1000 characters.';
        break;
    }

    if(mb_strlen($roleTitle) > 64) {
        echo 'Role title may not be longer than 64 characters.';
        break;
    }

    if($isNew) {
        $roleInfo = $roles->createRole($roleName, $roleRank, $roleColour, $roleTitle, $roleDesc, $roleHide, $roleLeavable);
    } else {
        if($roleName === $roleInfo->getName())
            $roleName = null;
        if($roleHide === $roleInfo->isHidden())
            $roleHide = null;
        if($roleLeavable === $roleInfo->isLeavable())
            $roleLeavable = null;
        if($roleRank === $roleInfo->getRank())
            $roleRank = null;
        if($roleTitle === $roleInfo->getTitle())
            $roleTitle = null;
        if($roleDesc === $roleInfo->getDescription())
            $roleDesc = null;
        // local genius did not implement colour comparison
        if((string)$roleColour === (string)$roleInfo->getColour())
            $roleColour = null;

        $roles->updateRole($roleInfo, $roleName, $roleRank, $roleColour, $roleTitle, $roleDesc, $roleHide, $roleLeavable);
    }

    $msz->createAuditLog(
        $isNew ? 'ROLE_CREATE' : 'ROLE_UPDATE',
        [$roleInfo->getId()]
    );

    if(!empty($permissions) && !empty($_POST['perms']) && is_array($_POST['perms'])) {
        $perms = manage_perms_apply($permissions, $_POST['perms']);

        if($perms !== null) {
            $permKeys = array_keys($perms);
            $setPermissions = DB::prepare('
                REPLACE INTO `msz_permissions` (`role_id`, `user_id`, `' . implode('`, `', $permKeys) . '`)
                VALUES (:role_id, NULL, :' . implode(', :', $permKeys) . ')
            ');
            $setPermissions->bind('role_id', $roleInfo->getId());

            foreach($perms as $key => $value) {
                $setPermissions->bind($key, $value);
            }

            $setPermissions->execute();
        } else {
            $deletePermissions = DB::prepare('DELETE FROM `msz_permissions` WHERE `role_id` = :role_id AND `user_id` IS NULL');
            $deletePermissions->bind('role_id', $roleInfo->getId());
            $deletePermissions->execute();
        }
    }

    url_redirect('manage-role', ['role' => $roleInfo->getId()]);
    return;
}

Template::render('manage.users.role', [
    'role_new' => $isNew,
    'role_info' => $roleInfo ?? null,
    'can_manage_perms' => $canEditPerms,
    'permissions' => $permissions ?? [],
]);
