<?php

declare(strict_types=1);

namespace apexl\Io\modules\user\services;

use apexl\Config\Singleton as Config;
use apexl\Io\modules\user\collections\permissionCollection;
use apexl\Io\modules\user\entities\userEntity;
use apexl\Vault\Vault;
use app\module\newtonsTrailers\Interface\PermissionInterface;

final readonly class userPermissionManagerService
{
    const TABLE__PERMISSIONS_USERS = 'permissions__users';
    private bool $isGodUser;

    public function __construct(private userEntity $user, private Vault $vault, Config $config)
    {
        $this->isGodUser = $this->isGodUser($config);
    }

    private function isGodUser(Config $config): bool
    {
        return ($config->app->permissions->enableGodUser ?? false) && $this->user->id == 1;
    }

    public function can(PermissionInterface|string $permission): bool
    {
        if ($this->isGodUser) {
            return true;
        }

        if ($this->userPermissions()->contains(
            $permission instanceof PermissionInterface ? $permission->asString() : $permission
        )) {
            return true;
        }

        if ($this->user->roles()->can($permission)) {
            return true;
        }

        return false;
    }

    private function userPermissions(): permissionCollection
    {
        return permissionCollection::createFromQueryResult(
            $this->vault->select(self::TABLE__PERMISSIONS_USERS)
                ->fields('permission')
                ->where('user', $this->user->id)
                ->execute()
                ->fetchAll()
        );
    }

    public function add(PermissionInterface $permission): void
    {
        $this->vault->insert(self::TABLE__PERMISSIONS_USERS)
            ->fields([
                'user' => $this->user->id,
                'permission' => $permission->asString(),
            ])->execute();
    }

    public function remove(PermissionInterface $permission): void
    {
        $this->vault->delete(self::TABLE__PERMISSIONS_USERS)
            ->where('user', $this->user->id)
            ->where('permission', $permission->asString())
            ->execute();
    }


}
