<?php

use Jaga\Models\BaseModel;
use Jaga\Traits\JagaTimestamp;
use Jaga\Traits\SoftDelete;

/**
 * Class PancekUserAccess
 * @property UmUser $umUser
 * @property Roles $role
 */
class PancekUserAccess extends BaseModel
{
    use JagaTimestamp, SoftDelete;

    public $id;
    public $user_id;
    public $role_id;
    public $start_date;
    public $end_date;
    public $created_at;
    public $updated_at;
    public $deleted_at;

    const ROLE_OBSERVER             = 'observer_pancek';
    const ROLE_VERIFIKATOR_BK       = 'verifikator_bk_pancek';
    const ROLE_VERIFIKATOR_BC       = 'verifikator_kppbc_pancek';

    const ACCESS_EXTEND     = 1;
    const ACCESS_INVALIDATE = 2;
    const ACCESS_RESET      = 3;

    public static $throwableModelName = 'PancekUserAccessException';

    public function initialize()
    {
        $this->setSchema("jaga");
        $this->setSource("pancek_user_access");
        $this->belongsTo(
            "user_id",
            \UmUser::class,
            "um_id",
            [
                'reusable' => true, // cache related data
                'alias'    => 'umUser',
            ]
        );
        $this->belongsTo(
            "role_id",
            \Roles::class,
            "id",
            [
                'reusable' => true, // cache related data
                'alias'    => 'role',
            ]
        );
    }

    /**
     * @throws CustomErrorException
     */
    public static function checkEligible($idUser, $idRole): bool
    {
        /** @var PancekUserAccess $pancekUserAccess */
        $pancekUserAccess = self::findFirst([
            'conditions' => 'user_id = :user_id: AND role_id = :role_id: AND deleted_at IS NULL',
            'bind' => ['user_id' => $idUser, 'role_id' => $idRole]
        ]);

        if ($pancekUserAccess) {
            $time = strtotime($pancekUserAccess->end_date);
            $endDate = date('Y-m-d', $time);
            if ($endDate < date('Y-m-d')) {
                throw new CustomErrorException(BaseResponse::INVALID_ACTION, "Masa aktif akun Anda telah habis. Mohon hubungi admin untuk mengaktifkan akun anda.");
            }
        }

        return true;
    }

    /**
     * @throws CustomErrorException
     */
    public static function checkEligibleForRoleObserver(BaseController $context)
    {
        if ($context->pHasRole(self::ROLE_OBSERVER)) {
            $idUser = $context->shared->user->um_id;
            $idRoleObserver = 0;
            try {
                $idRoleObserver = Roles::getIdByRole(self::ROLE_OBSERVER);
            } catch (\Exception $e) {}

            if ($idRoleObserver > 0) {
                return self::checkEligible($idUser, $idRoleObserver);
            }
        }

        return true;
    }

    public static function insertForRoleObserver($userId, $roles)
    {
        foreach ($roles as $role) {
            /** @var Roles $role */
            if ($role->name == self::ROLE_OBSERVER) {
                $exist = PancekUserAccess::findFirst([
                    'conditions' => 'user_id = :user_id: AND role_id = :role_id: AND deleted_at IS NULL',
                    'bind' => [
                        'user_id' => $userId,
                        'role_id' => $role->id,
                    ]
                ]);
                if (!$exist) {
                    $exist = new PancekUserAccess();
                    $exist->user_id = $userId;
                    $exist->role_id = $role->id;
                    $exist->start_date = date('Y-m-d');
                    $exist->created_at = date('Y-m-d H:i:s');
                }
                $exist->end_date = date('Y-m-d', strtotime("+3 months"));
                $exist->updated_at = date('Y-m-d H:i:s');
                if (!$exist->save()) {
                    $error_messages = $exist->getErrorMessages();
                    throw new CustomErrorException(BaseResponse::SQL_ERROR, $error_messages);
                }
            }
        }
    }

    public function getErrorMessages()
    {
        $errors = $this->getMessages();
        $error_messages = [];

        foreach ($errors as $key => $error) {
            $error_messages[] = ["field" => $error->getField(), "message" => $error->getMessage()];
        }

        return $error_messages;
    }
}