<?php

declare(strict_types=1);

/**
 * Created by Aurélien RICHAUD (30/08/2018 16:51).
 */
class Cookie extends CookieCore
{
    /**
     * @var OAuthAccessToken|null
     */
    protected $accessToken;

    /**
     * @var OAuthAccessTokenCookie|null
     */
    protected $accessTokenCookie;

    /**
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    protected function loadAccessToken(): void
    {
        require_once _PS_MODULE_DIR_ . 'myvetshopclinique/classes/OAuthAccessToken.php';
        require_once _PS_MODULE_DIR_ . 'myvetshopclinique/classes/OAuthAccessTokenCookie.php';

        // Extraction du token de la requête
        $token = OAuthAccessToken::getTokenFromRequest();
        if (!$token) {
            return;
        }

        // Vérification de la validité du token
        $accessToken = OAuthAccessToken::getByToken($token);
        if (!$accessToken || $accessToken->expires < \time()) {
            return;
        }

        // Token valide
        $this->accessToken = $accessToken;
    }

    /**
     * @param string $path
     * @param int|null $expire
     * @param string[]|null $shared_urls
     * @param bool $standalone
     * @param bool $secure
     *
     * {@inheritDoc}
     */
    public function __construct(string $name, $path = '', $expire = null, $shared_urls = null, $standalone = false, $secure = false)
    {
        $this->loadAccessToken();

        parent::__construct($name, $path, $expire, $shared_urls, $standalone, $secure);
    }

    public function logout(): void
    {
        $stock = [];
        if (isset($this->_content['response_type'], $this->_content['client_id'], $this->_content['redirect_uri'], $this->_content['scope'])
        ) {
            $stock['response_type'] = $this->_content['response_type'];
            $stock['client_id'] = $this->_content['client_id'];
            $stock['redirect_uri'] = $this->_content['redirect_uri'];
            $stock['scope'] = $this->_content['scope'];
        }

        parent::logout();

        if (\count($stock)) {
            $this->response_type = $stock['response_type'];
            $this->client_id = $stock['client_id'];
            $this->redirect_uri = $stock['redirect_uri'];
            $this->scope = $stock['scope'];
        }
    }

    /**
     * @param bool $nullValues
     *
     * @throws PrestaShopDatabaseException
     * @throws PrestaShopException
     */
    public function update($nullValues = false): void
    {
        \assert($this->cipherTool instanceof PhpEncryption);
        \assert(\is_string($this->_name));

        if ($this->accessToken) {
            $this->accessTokenCookie = OAuthAccessTokenCookie::getByTokenAndName(
                $this->accessToken->token,
                $this->_name
            );

            // Si le cookie existe, n'est pas expiré et contient une donnée,
            // on remplace les valeurs par celles en base !
            if (
                $this->accessTokenCookie
                && $this->accessTokenCookie->expires > time()
                && $this->accessTokenCookie->value
            ) {
                $_COOKIE[$this->_name] = $this->cipherTool->encrypt($this->accessTokenCookie->value);

                // Force le cookie
                // parent::encryptAndSetCookie($this->accessTokenCookie->value);
            }
        }

        parent::update($nullValues);
    }

    /**
     * @param string|null $cookie
     *
     * @throws PrestaShopException
     */
    protected function encryptAndSetCookie($cookie = null): bool
    {
        \assert(\is_string($this->_name));
        \assert(\is_int($this->_expire));

        $ret = parent::encryptAndSetCookie($cookie);

        // Sauvegarde en base au besoin
        if ($this->accessToken && $this->accessTokenCookie) {
            $this->accessTokenCookie->expires = $this->_expire;
            $this->accessTokenCookie->value = $cookie;

            \Db::getInstance()->connect();
            $this->accessTokenCookie->save();
        }

        return $ret;
    }
}
