<?php

namespace routes;

use classes\authentication;
use objects\groups_o;
use objects\logs_o;
use traits\route_t;

class rolesRoute
{
    use route_t;

    public function run(): void
    {
        self::get('/roles', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('list_roles');
            $user = (new authentication())->get_user();
            if ($user) {
                (new logs_o())->add('roles', 'global', 1, 0, 'ROLES', 'User accessed the roles list');
                $groups = new groups_o();
                // Check if the id parameter is set
                if (self::isParametersSet(['id'])) {
                    self::requireType((int)self::getParameter('id'), self::type_int());
                    $groups->select((int)self::getParameter('id'));
                    $groups->requireSelected();
                    $response->success($groups->asArray());
                }
                // Return the list of roles
                $response->success($groups->listObjectsWithPaginationIfSet(
                    function ($group) {
                        return [
                            'id' => (int)$group['id'],
                            'name' => (string)$group['name'],
                            'description' => (string)$group['description'],
                            'created_at' => (string)$group['created_at'],
                            'permissions' => (new groups_o())->select((int)$group['id'])->getPermissions()
                        ];
                    }
                ));
            } else {
                (new logs_o())->add('roles', 'global', 0, 0, 'ROLES', 'User tried to access the roles list without a valid session');
                $response->error('Invalid session', 400);
            }
        },
            [
                'list_roles' => 'List all roles'
            ]
        );

        self::post('/roles', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('add_role');
            $user = (new authentication())->get_user();
            if ($user) {
                (new logs_o())->add('roles', 'global', 1, 0, 'ROLES', 'User added a role');
                self::requireParameters(['name', 'description']);
                self::requireType((string)self::getParameter('name'), 'string');
                self::requireType((string)self::getParameter('description'), 'string');
                $group = new groups_o();
                $group->add(
                    (string)self::getParameter('name'),
                    (string)self::getParameter('description')
                );
                $response->success($group->asArray());
            } else {
                (new logs_o())->add('roles', 'global', 0, 0, 'ROLES', 'User tried to add a role without a valid session');
                $response->error('Invalid session', 400);
            }
        },
            [
                'add_role' => 'Add a role'
            ]
        );

        self::put('/roles', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('edit_role');
            $user = (new authentication())->get_user();
            if ($user) {
                self::requireParameters(['id']);
                self::requireType((int)self::getParameter('id'), self::type_int());
                $group = new groups_o();
                $group->select((int)self::getParameter('id'));
                $group->requireSelected();
                // Check which parameters are set and update them
                if (self::isParametersSet(['name'])) {
                    $group->name->set((string)self::getParameter('name'));
                }
                if (self::isParametersSet(['description'])) {
                    $group->description->set((string)self::getParameter('description'));
                }
                (new logs_o())->add('roles', 'global', 1, $user->id, 'ROLES', 'User edited a role');
                $response->success($group->asArray());
            } else {
                (new logs_o())->add('roles', 'global', 0, 0, 'ROLES', 'User tried to edit a role without a valid session');
                $response->error('Invalid session', 400);
            }
        },
            [
                'edit_role' => 'Edit a role'
            ]
        );

        self::post('/roles/permissions', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('add_role_permission');
            $user = (new authentication())->get_user();
            if ($user) {
                self::requireParameters(['group_id', 'permission_id']);
                self::requireType((int)self::getParameter('group_id'), self::type_int());
                self::requireType((string)self::getParameter('permission_id'), 'string');
                $group = new groups_o();
                $group->select((int)self::getParameter('group_id'));
                $group->requireSelected();
                $group->addPermission((string)self::getParameter('permission_id'));
                (new logs_o())->add('roles', 'global', 1, $user->id, 'ROLES', 'User added a permission to a role');
                $response->success($group->asArray());
            } else {
                (new logs_o())->add('roles', 'global', 0, 0, 'ROLES', 'User tried to add a permission to a role without a valid session');
                $response->error('Invalid session', 400);
            }
        },
            [
                'add_role_permission' => 'Add a permission to a role'
            ]
        );

        self::delete('/roles/permissions', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('delete_role_permission');
            $user = (new authentication())->get_user();
            if ($user) {
                self::requireParameters(['group_id', 'permission_id']);
                self::requireType((int)self::getParameter('group_id'), self::type_int());
                self::requireMinLength('group_id', 1);
                self::requireType((string)self::getParameter('permission_id'), 'string');
                self::requireMinLength('permission_id', 1);
                $group = new groups_o();
                $group->select((int)self::getParameter('group_id'));
                $group->requireSelected();
                $group->removePermission((string)self::getParameter('permission_id'));
                (new logs_o())->add('roles', 'global', 1, $user->id, 'ROLES', 'User deleted a permission from a role');
                $response->success($group->asArray());
            } else {
                (new logs_o())->add('roles', 'global', 0, 0, 'ROLES', 'User tried to delete a permission from a role without a valid session');
                $response->error('Invalid session', 400);
            }
        },
            [
                'delete_role_permission' => 'Remove a permission from a role'
            ]
        );

        self::post('/roles/clone', function () {
            // Require the user to be logged in
            global $response;
            self::requirePermission('clone_role');
            $user = (new authentication())->get_user();
            if ($user) {
                self::requireParameters(['id']);
                self::requireType((int)self::getParameter('id'), self::type_int());
                $group = new groups_o();
                $group->select((int)self::getParameter('id'));
                $group->requireSelected();
                $group->clone($group->name->value() . ' - Klon', (string)$group->description->value());
                (new logs_o())->add('roles', 'global', 1, $user->id, 'ROLES', 'User cloned a role');
                $response->success($group->asArray());
            } else {
                (new logs_o())->add('roles', 'global', 0, 0, 'ROLES', 'User tried to clone a role without a valid session');
                $response->error('Invalid session', 400);
            }
        },
            [
                'clone_role' => 'Clone a role'
            ]
        );
    }
}