<?php
namespace Misuzu\Twitter;

use Stringable;
use Misuzu\Config\IConfig;

class TwitterAccessToken implements Stringable {
    public function __construct(
        private string $type,
        private string $accessToken,
        private int $expires,
        private array $scope,
        private string $refreshToken
    ) {}

    public function getType(): string {
        return $this->type;
    }

    public function getAccessToken(): string {
        return $this->accessToken;
    }

    public function hasAccessToken(): bool {
        return $this->type !== '' && $this->accessToken !== '';
    }

    public function getExpiresTime(): int {
        return $this->expires;
    }

    public function hasExpires(): bool {
        return time() > $this->expires;
    }

    public function getScope(): array {
        return $this->scope;
    }

    public function getRefreshToken(): string {
        return $this->refreshToken;
    }

    public function hasRefreshToken(): bool {
        return $this->refreshToken !== '';
    }

    public function __toString(): string {
        return 'Bearer ' . $this->accessToken;
    }

    public static function empty(): self {
        return new static('', '', 0, [], '');
    }

    public static function fromTwitterResponse(object $obj): self {
        return new static(
            $obj->token_type ?? '',
            $obj->access_token ?? '',
            time() + ($obj->expires_in ?? 0),
            explode(' ', ($obj->scope ?? '')),
            $obj->refresh_token ?? ''
        );
    }

    public static function load(IConfig $config): self {
        return new static(
            $config->getValue('type', IConfig::T_STR),
            $config->getValue('token', IConfig::T_STR),
            $config->getValue('expires', IConfig::T_INT),
            $config->getValue('token', IConfig::T_ARR),
            $config->getValue('refresh', IConfig::T_STR)
        );
    }

    public static function save(IConfig $config, self $tokenInfo): void {
        $config->setValue('type', $tokenInfo->getType());
        $config->setValue('token', $tokenInfo->getAccessToken());
        $config->setValue('expires', $tokenInfo->getExpiresTime());
        $config->setValue('scope', $tokenInfo->getScope());
        $config->setValue('refresh', $tokenInfo->getRefreshToken());
    }

    public static function nuke(IConfig $config): void {
        $config->removeValue('type');
        $config->removeValue('token');
        $config->removeValue('expires');
        $config->removeValue('scope');
        $config->removeValue('refresh');
    }
}
