<?php
namespace Incoviba\Service;

use Exception;
use Psr\Http\Client\ClientExceptionInterface;
use Psr\Http\Client\ClientInterface;
use Psr\Log\LoggerInterface;

class Login
{
    public function __construct(protected ClientInterface $client, protected LoggerInterface $logger,
                                protected string $tokenFilename,
                                protected string $username, protected string $password) {}

    public function login(): string
    {
        $url = '/api/login';
        try {
            $response = $this->client->request('POST', $url, [
                'body' => http_build_query([
                    'username' => $this->username,
                    'password' => $this->password
                ]),
                'headers' => ['Content-Type' => 'application/x-www-form-urlencoded']
            ]);
        } catch (ClientExceptionInterface $exception) {
            $this->logger->error($exception);
            return '';
        }

        if ($response->getStatusCode() !== 200) {
            return '';
        }
        $body = $response->getBody()->getContents();
        $data = json_decode($body, true);
        if (!key_exists('token', $data)) {
            $this->logger->error('Token not found');
            return '';
        }
        file_put_contents($this->tokenFilename, $data['token']);
        return $data['token'];
    }
    public function retrieveToken(): string
    {
        if (!file_exists($this->tokenFilename)) {
            throw new Exception('Token file not found');
        }
        return file_get_contents($this->tokenFilename);
    }
    public function tryToken(string $token): bool
    {
        $url = '/api/tokens/try';
        try {
            $response = $this->client->request('GET', $url, [
                'headers' => ['Authorization' => "Bearer {$token}"]
            ]);
        } catch (ClientExceptionInterface $exception) {
            $this->logger->error($exception);
            return false;
        }
        return $response->getStatusCode() === 200;
    }
    public function getKey(string $apiKey, string $separator = 'g'): string
    {
        try {
            $token = $this->retrieveToken();
            if (!$this->tryToken(implode('', [md5($apiKey), $separator, $token]))) {
                throw new Exception('Token not valid');
            }
        } catch (Exception $exception) {
            $this->logger->error($exception);
            $token = $this->login();
        }
        return implode('', [md5($apiKey), $separator, $token]);
    }
}
