<?php

namespace apexl\Io\modules\user\entities;

use apexl\entityCore\traits\hasCasts;
use apexl\Io\includes\Entity;
use apexl\Io\includes\System;
use apexl\Io\modules\user\collections\permissionCollection;
use apexl\Io\modules\user\entities\operators\roleOperator;
use apexl\Io\modules\user\interfaces\PermissionInterface;
use apexl\Io\modules\user\services\RolePermissionManagerService;
use DateTimeImmutable;

/**
 * @property int $id
 * @property string $name
 * @property DateTimeImmutable $created
 * @property userEntity $created_by
 * @property DateTimeImmutable $modified
 * @property userEntity $modified_by
 * @property roleOperator $operator
 * @method roleEntity[] loadMultiple(array $conditions = [], array $orderBy = [], bool|int $limit = false, bool|int $offset = false)
 * @mixin roleOperator
 */
class roleEntity extends Entity
{
    use hasCasts;

    private RolePermissionManagerService $permissionManager;

    public function __construct()
    {
        parent::__construct('roles');
        $this->setOperator(new roleOperator('roles', 'id'));
        $this->permissionManager = System::makeRegisteredService(RolePermissionManagerService::class, [
            'role' => $this,
        ]);

    }

    public function getEntityType(): string
    {
        return __CLASS__;
    }

    public function access($permission): bool
    {
        $currentUser = $this->currentUserFactory->get();
        //are we logged in? if so, check if the permission is 'IsLoggedIn' and pass it if it is.
        if ($currentUser->id != 0 && $permission == 'IsLoggedIn') {
            return true;
        }

        return $this->can($permission);
    }

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

    public function addPermission(PermissionInterface $permission): void
    {
        if (!$this->hasPermission($permission)) {
            $this->permissionManager->add($permission);
        }
    }

    public function hasPermission(PermissionInterface $permission)
    {
        if (!isset($existingPermissions)) {
            static $existingPermissions;
            $existingPermissions = $this->permissions();
        }

        foreach ($existingPermissions as $existingPermission) {
            if ($existingPermission === $permission) return true;
        }

        return false;
    }

    public function permissions(): permissionCollection
    {
        return $this->permissionManager->permissions();
    }

    public function removePermission(PermissionInterface $permission): void
    {
        if ($this->hasPermission($permission)) {
            $this->permissionManager->remove($permission);
        }
    }
}
