<?php

namespace apexl\Io\modules\user\entities;

use apexl\Io\includes\Entity;
use apexl\Io\includes\Utils;
use apexl\Io\modules\user\entities\operators\roleOperator;
use apexl\Io\modules\user\services\currentUser;
use apexl\Io\operators\entityDatabaseOperator;

/**
 * @property string $id
 * @property string $name
 * @property string $permissions
 * @property string $created
 * @property string $created_by
 * @property string $modified
 * @property string $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
{
    public function __construct()
    {
        parent::__construct('roles');
        $this->setOperator(new roleOperator('roles', 'id'));
    }

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

    public function access($permission): bool
    {
        $currentUser = currentUser::getCurrentUser();
        //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;
        }

        if (is_array($this->permissions)) {
            return in_array($permission, $this->permissions);
        }
        return false;
    }

    /**
     * override the magic load method, so we can intercept permissions and unserilize them.
     * @param $id
     * @return $this
     *@throws \Exception
     */
    public function load($id, bool $skipAccessControl = false): Entity
    {
        parent::__call('load', [$id, $skipAccessControl]);
        //gives us an array of role id's for easy use later.
        if (!empty($this->permissions) && is_string($this->permissions)) {
            $this->permissions = unserialize($this->permissions);
        }
        return $this;
    }

    /**
     * override the magic store method to make sure we serialise permission data before saving.
     * @throws \Exception
     */
    public function store(): Entity
    {
        //we need to revert the serialised data after storing, so its still available as if we loaded the data
        if ($this->permissions !== null && !empty($this->permissions) && is_array($this->permissions)) {
            $cleanVersion = $this->permissions;
            $this->permissions = serialize($this->permissions);
            parent::__call('store', [$this->data]);
            $this->permissions = $cleanVersion;
            return $this;
        }
        parent::__call('store', [$this->data]);
        return $this;
    }

    protected function fieldConfig()
    {
        return [
            "id" => [
                'name' => "ID"
            ],
            "name" => [
                'name' => "Name"
            ],
            "permissions" => [
                'name' => "Permissions",
                'display' => function ($permissions): string {
                    return wordwrap(implode(',', unserialize($permissions)), 60, '...');
                }
            ],
            "modified" => [
                'name' => "Modified",
                'display' => function ($date) {
                    return Utils::HIDE_FROM_DISPLAY;
                }
            ],
            "modified_by" => [
                'name' => "Modified By",
                'display' => function ($uid) {
                    return Utils::HIDE_FROM_DISPLAY;
                }
            ],
        ];
    }
}
