<?php

namespace Mnv\Models\Users;

use Mnv\Core\Model;
use Mnv\Core\Test\Logger;
use Mnv\Http\Request;

/**
 * Class UserGroups
 * @package Mnv\Models\Users
 */
class UserGroups extends Model
{

    /** @var string */
    protected string $table = 'user_group';
    /** @var string  */
    protected string $primaryKey = 'groupId';

    protected string $orderBy = 'groupId ASC';

    protected string $columns = 'groupId, groupName, status, addedOn, modifiedOn';

    /** @var array|mixed  */
    public $privileges = array();

    public $groups = array(
       UserTypes::DEVELOPER => 'Разработчики',
       UserTypes::ADMIN => 'Администраторы',
       UserTypes::MANAGER => 'Менеджеры',
       UserTypes::CUSTOMER => 'Пользователи',
    );

    public function __construct(Request $request)
    {
        $this->id           = $request->get('id');                      // getRequestVar('id','')
        $this->data         = $request->get('group', '');        // getRequestVar('group','', true),
        $this->privileges   = $request->get('privileges', '');   // getRequestVar('privileges','')
    }

    public static function selectGroup($userType)
    {
        $group = array('0' => "Выберите группу...");
        if ($userType == UserTypes::ADMIN) connect()->notWhere('groupId', 1);
        $group += connect()->table('user_group')->select('groupId, groupName')->where('status', 'V')->indexKey('groupId')->valueKey('groupName')->getAllIndexes();

        return $group;
    }

    public static function arrayGroup()
    {
        return connect('user_group')->select('groupId')->where('status', 'V')->indexKey('groupId')->valueKey('groupId')->getAllIndexes('array');
    }


    public function getCountGroupUsers(int $groupId)
    {
        return connect('users')->count('*', 'count')->where('accessLevel', $groupId)->getValue();
    }
    /**
     * @param $groupId
     * @return string|null
     */
    public static function accessLevelName($groupId): ?string
    {
        return connect('user_group')->select('groupName')->where('groupId', $groupId)->getValue();
    }

    public function all($limit, $page, $userTypes = null)
    {
        if ($userTypes != UserTypes::DEVELOPER) connect()->notWhere($this->primaryKey, 1);

        return parent::all($limit, $page);
    }

    public function total($UserType = null): void
    {
        if ($UserType != UserTypes::DEVELOPER) connect()->notWhere($this->primaryKey, 1);

        parent::total();
    }

    /**
     * Получить пользователя
     */
    public function edit(): UserGroups
    {
        if (!empty($this->id) && $this->data = connect()->table($this->table)->where($this->primaryKey, $this->id)->get('array')) {
            $this->data['countUsers'] = $this->getCountGroupUsers($this->id);
            $this->data['privilege'] = $this->getUserPrivileges();

        }

        return $this;
    }

    /**
     * @param string|null $fileName
     * @return mixed|string|null
     */
    public function checkFileName(?string $fileName): ?string
    {
        if (!empty($this->id)) connect()->where($this->primaryKey,'<>', $this->id);
        if ($fileName = connect()->table($this->table)->select('groupName')->where('LOWER(fileName)', $fileName)->getValue()) return $fileName;

        return null;
    }


    public function prepare(array $data, int $managerId): bool
    {
        $data['modifiedBy']   = $managerId;
        $data['modifiedOn']   = gmdate('Y-m-d H:i:s');

        if (empty($this->id)) {

            $data['addedBy'] = $managerId;
            $data['addedOn'] = gmdate('Y-m-d H:i:s');
            if ($this->id = $this->insert($data)) {
                $this->privileges();

                Logger::init()->info("Создана новая группа «" . $data['groupName'] . "»", $managerId)->save();

                return true;
            }
        } else {
            if ($this->update($data)) {
                $this->privileges();

                Logger::init()->info("Группа  «" . $data['groupName'] . "» была отредактирована", $managerId)->save();

                return true;
            }
        }

        return false;
    }


    public function remove(): bool
    {
        if (parent::remove()) {
            connect()->table('user_group_privileges')->where($this->primaryKey, $this->id)->delete();
            connect()->table('users')->where('accessLevel', $this->id)->delete();
            return true;
        }
        return false;
    }

    private function privileges(): void
    {
        connect()->table('user_group_privileges')->where($this->primaryKey, $this->id)->delete();

        foreach ($this->privileges as $privilege) {
            connect()->table('user_group_privileges')->insert([
                'groupId'   => $this->id,
                'privilege' => $privilege
            ]);
        }
    }

    private function getUserPrivileges(): ?array
    {
        return connect()->table('user_group_privileges')->select('privilege')->where($this->primaryKey, $this->id)->valueKey('privilege')->getAllIndexes();
    }
}