<?php

declare(strict_types=1);

namespace App\Framework\Process\ValueObjects\Http;

use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Http\Headers;
use App\Framework\Http\Status;
use App\Framework\Http\Url\Url;

/**
 * URL Health Check Result.
 */
final readonly class UrlHealthCheck
{
    public function __construct(
        public Url $url,
        public bool $isAccessible,
        public Status $status,
        public Duration $responseTime,
        public ?string $error = null,
        public ?Url $redirectUrl = null,
        public ?Headers $headers = null
    ) {
    }

    /**
     * Erstellt ein erfolgreiches Health-Check-Ergebnis.
     */
    public static function success(
        Url $url,
        Status $status,
        Duration $responseTime,
        ?Headers $headers = null
    ): self {
        return new self(
            url: $url,
            isAccessible: true,
            status: $status,
            responseTime: $responseTime,
            headers: $headers
        );
    }

    /**
     * Erstellt ein fehlgeschlagenes Health-Check-Ergebnis.
     */
    public static function failed(Url $url, string $error): self
    {
        return new self(
            url: $url,
            isAccessible: false,
            status: Status::INTERNAL_SERVER_ERROR,
            responseTime: Duration::fromMilliseconds(0),
            error: $error
        );
    }

    /**
     * Fügt Redirect-Informationen hinzu.
     */
    public function withRedirect(Url $redirectUrl): self
    {
        return new self(
            url: $this->url,
            isAccessible: $this->isAccessible,
            status: $this->status,
            responseTime: $this->responseTime,
            error: $this->error,
            redirectUrl: $redirectUrl,
            headers: $this->headers
        );
    }

    /**
     * Prüft, ob Status-Code erfolgreich ist (2xx).
     */
    public function isSuccessful(): bool
    {
        return $this->status->isSuccess();
    }

    /**
     * Prüft, ob ein Redirect vorliegt (3xx).
     */
    public function isRedirect(): bool
    {
        return $this->status->isRedirection();
    }

    /**
     * Prüft, ob Response-Zeit akzeptabel ist.
     */
    public function isResponseTimeFast(Duration $threshold): bool
    {
        return $this->responseTime->toMilliseconds() < $threshold->toMilliseconds();
    }

    /**
     * Konvertiert zu Array.
     *
     * @return array<string, mixed>
     */
    public function toArray(): array
    {
        return [
            'url' => $this->url->toString(),
            'is_accessible' => $this->isAccessible,
            'is_successful' => $this->isSuccessful(),
            'status_code' => $this->status->value,
            'status_description' => $this->status->getDescription(),
            'response_time_ms' => $this->responseTime->toMilliseconds(),
            'response_time_human' => $this->responseTime->toHumanReadable(),
            'error' => $this->error,
            'redirect_url' => $this->redirectUrl?->toString(),
            'is_redirect' => $this->isRedirect(),
            'headers' => $this->headers?->all(),
        ];
    }
}
