<?php

declare(strict_types=1);

namespace App\Framework\Http;

use App\Framework\Attributes\Singleton;
use App\Framework\Config\Environment;

/**
 * Service zur Verwaltung der Request-ID für den aktuellen Request.
 * Nutzt HMAC-Signierung, um die Integrität der IDs zu gewährleisten.
 */
#[Singleton]
final class RequestIdGenerator
{
    private const string REQUEST_ID_HEADER = 'X-Request-ID';

    private ?RequestId $requestId = null;

    private readonly string $secret;

    /**
     * Initialisiert den RequestIdGenerator mit Environment für Secret-Auflösung
     */
    public function __construct(?Environment $env = null, string $secret = '')
    {
        // Fallback für BC: Wenn kein Environment übergeben wird und Secret angegeben ist
        if ($secret !== '') {
            $this->secret = $secret;
        } elseif ($env !== null) {
            $this->secret = $env->getString('APP_SECRET', 'default-secret-change-me');
        } else {
            // Final fallback für alte Verwendung ohne Environment
            $this->secret = 'default-secret-change-me';
        }
    }

    /**
     * Generiert eine neue Request-ID oder validiert und verwendet eine bestehende
     */
    public function generate(?Headers $headers = null): RequestId
    {
        if ($this->requestId === null) {
            // Prüfen, ob eine Request-ID im Header vorhanden ist
            $headerRequestId = $headers?->getFirst(self::REQUEST_ID_HEADER);

            // Neue RequestId erstellen (validiert automatisch die Header-ID, falls vorhanden)
            $this->requestId = new RequestId($this->secret, $headerRequestId);
        }

        return $this->requestId;
    }

    /**
     * Gibt die aktuelle Request-ID zurück oder null, wenn noch keine generiert wurde
     */
    public function getCurrentId(): ?RequestId
    {
        return $this->requestId;
    }

    /**
     * Gibt den Header-Namen für die Request-ID zurück
     */
    public static function getHeaderName(): string
    {
        return self::REQUEST_ID_HEADER;
    }
}
