<?php
namespace ElixForms\Auth;

use ElixForms\Exceptions\ElixFormsException;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

class ElixFormsAuthenticationClient {
    private $baseUrl;
    private $httpClient;

    public function __construct(string $baseUrl, ?Client $httpClient = null) {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->httpClient = $httpClient ?? new Client(['timeout' => 10.0, 'http_errors' => false]);
    }

    /**
     * Esegue il login verso l'API di elixForms.
     *
     * @param string $username
     * @param string $password
     * @return string Il token di autenticazione (authToken)
     * @throws ElixFormsException Se le credenziali sono errate o c'è un errore server
     */
    public function login(string $username, string $password): string {
        $this->baseUrl = rtrim($this->baseUrl,'/');
        $url = "{$this->baseUrl}/services/api/authentication/login/v1";

        try {
            $response = $this->httpClient->post($url, [
                'form_params' => [
                    'username' => $username,
                    'password' => $password
                ]
            ]);

            $status = $response->getStatusCode();
            if ($status !== 200) {
                throw new ElixFormsException("Errore durante il login elixForms. HTTP Status: " . $status);
            }

            $body = $response->getBody()->getContents();
            $json = json_decode($body, true);

            if (json_last_error() !== JSON_ERROR_NONE || empty($json)) {
                throw new ElixFormsException("Risposta non valida dal server elixForms: atteso JSON.");
            }

            if (isset($json['value']['authToken'])) {
                return $json['value']['authToken'];
            }

            throw new ElixFormsException("authToken non trovato nella risposta del login elixForms.");
        } catch (GuzzleException $e) {
            throw new ElixFormsException("Errore di connessione al server elixForms: " . $e->getMessage(), 0, $e);
        }
    }

    /**
     * Effettua il logout invalidando il token sul server elixForms.
     *
     * @param string $username
     * @param string $token
     * @return bool True se il logout ha successo
     * @throws ElixFormsException Se c'è un errore durante il logout
     */
    public function logout(string $username, string $token): bool {
        $url = "{$this->baseUrl}/services/api/authentication/" . urlencode($username) . '/logout/v1';

        try {
            $response = $this->httpClient->post($url, [
                'headers' => [
                    'Authorization' => 'Bearer ' . $token,
                    'Content-Type' => 'application/x-www-form-urlencoded'
                ]
            ]);

            $status = $response->getStatusCode();
            if ($status !== 200) {
                throw new ElixFormsException("Errore durante il logout elixForms. HTTP Status: " . $status);
            }

            return true;
        } catch (GuzzleException $e) {
            throw new ElixFormsException("Errore di connessione al server elixForms: " . $e->getMessage(), 0, $e);
        }
    }
}
