<?php

declare(strict_types=1);

namespace App\Framework\Config\ValueObjects;

use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Http\IpAddress;

/**
 * Value Object representing security context information
 * Used for auditing, logging, and security validation
 */
final readonly class SecurityContext
{
    public function __construct(
        public bool $isHttps,
        public IpAddress $clientIp,
        public string $maskedUserAgent,
        public string $serverName,
        public string $encryptionMethod,
        public Timestamp $timestamp
    ) {
    }

    /**
     * Create from server environment and encryption context
     */
    public static function create(
        bool $isHttps,
        IpAddress $clientIp,
        string $maskedUserAgent,
        string $serverName,
        string $encryptionMethod
    ): self {
        return new self(
            isHttps: $isHttps,
            clientIp: $clientIp,
            maskedUserAgent: $maskedUserAgent,
            serverName: $serverName,
            encryptionMethod: $encryptionMethod,
            timestamp: Timestamp::fromFloat(microtime(true))
        );
    }

    /**
     * Check if the context is considered secure
     */
    public function isSecure(): bool
    {
        return $this->isHttps;
    }

    /**
     * Get security risk level based on context
     */
    public function getRiskLevel(): SecurityRiskLevel
    {
        if (! $this->isHttps) {
            return SecurityRiskLevel::HIGH;
        }

        if ($this->clientIp->isPrivate()) {
            return SecurityRiskLevel::LOW;
        }

        return SecurityRiskLevel::MEDIUM;
    }

    /**
     * Get context summary for logging
     */
    public function getSummary(): string
    {
        $protocol = $this->isHttps ? 'HTTPS' : 'HTTP';

        return sprintf(
            '%s from %s via %s (%s)',
            $protocol,
            $this->clientIp->toString(),
            $this->serverName,
            $this->encryptionMethod
        );
    }

    /**
     * Convert to array for logging/serialization
     * @return array<string, mixed>
     */
    public function toArray(): array
    {
        return [
            'is_https' => $this->isHttps,
            'client_ip' => $this->clientIp->toString(),
            'user_agent' => $this->maskedUserAgent,
            'server_name' => $this->serverName,
            'encryption_method' => $this->encryptionMethod,
            'timestamp' => $this->timestamp->toDateTimeString(),
            'risk_level' => $this->getRiskLevel()->value,
            'summary' => $this->getSummary(),
        ];
    }

    /**
     * Check if context is suitable for handling secrets
     */
    public function isSecretHandlingSafe(): bool
    {
        return $this->isHttps && $this->getRiskLevel() !== SecurityRiskLevel::HIGH;
    }

    /**
     * String representation
     */
    public function __toString(): string
    {
        return $this->getSummary();
    }
}
