<?php

namespace BitApps\SocialPro\HTTP\Services\Social\BlueskyService;

use BitApps\Social\Deps\BitApps\WPKit\Http\Client\HttpClient;
use BitApps\Social\HTTP\Services\Traits\LoggerTrait;
use BitApps\Social\Model\Account;
use BitApps\Social\Utils\Common;
use BitApps\Social\Utils\Hash;

class BlueskyRefreshTokenService
{
    use Common, LoggerTrait;

    public const REFRESH_SESSION_URL = 'https://bsky.social/xrpc/com.atproto.server.refreshSession';

    private $HttpClient;

    private $accountDetails;

    private $accountId;

    private $accessToken;

    private $refreshToken;

    private $generateOn;

    public function __construct($accountDetails)
    {
        $this->HttpClient = new HttpClient();

        $this->accountDetails = $accountDetails;
        $this->accountId = $accountDetails->account_id;
        $this->accessToken = Hash::decrypt($accountDetails->access_token);
        $this->refreshToken = Hash::decrypt($accountDetails->refresh_token);
        $this->generateOn = $accountDetails->generateOn;
    }

    public function tokenExpiryCheck()
    {
        $TIMEOUT = 2 * 60 * 60; // 2 hour
        if (!$this->accessToken && !$this->refreshToken) {
            return false;
        }

        if ((\intval($this->generateOn)) + $TIMEOUT < time()) {
            return $this->refreshAccessToken();
        }

        return $this->accessToken;
    }

    public function accessToken()
    {
        return $this->tokenExpiryCheck();
    }

    public function refreshAccessToken()
    {
        $headers = [
            'Authorization' => 'Bearer ' . $this->refreshToken,
            'Content-Type'  => 'application/json'
        ];

        $result = $this->HttpClient->request(static::REFRESH_SESSION_URL, 'POST', [], $headers);

        if (isset($result->accessJwt)) {
            $this->accessToken = $result->accessJwt;
            $this->refreshToken = $result->refreshJwt;
            $this->saveAccessToken();
        }

        return $this->accessToken;
    }

    public function saveAccessToken()
    {
        if (empty($this->accountId)) {
            return;
        }
        $account = Account::findOne(['account_id' => $this->accountId]);

        $accountDetails = $this->accountDetails;
        $accountDetails->access_token = Hash::encrypt($this->accessToken);
        $accountDetails->refresh_token = Hash::encrypt($this->refreshToken);
        $accountDetails->generateOn = time();
        $account->update(['details' => $accountDetails])->save();
    }
}
