<?php

declare(strict_types=1);

namespace App\Framework\Database\Middleware;

use App\Framework\Database\Exception\DatabaseException;
use App\Framework\Database\HealthCheck\ConnectionHealthChecker;
use App\Framework\Database\HealthCheck\HealthCheckResult;

final readonly class HealthCheckMiddleware implements QueryMiddleware
{
    private ConnectionHealthChecker $healthChecker;

    public function __construct(
        private int $healthCheckInterval = 30, // Sekunden
        private bool $enabled = true
    ) {
        $this->healthChecker = new ConnectionHealthChecker();
    }

    public function process(QueryContext $context, callable $next): mixed
    {
        if (!$this->enabled) {
            return $next($context);
        }

        // Prüfe ob Health Check notwendig ist
        $lastHealthCheck = $context->getMetadata('last_health_check', 0);
        $currentTime = time();

        if (($currentTime - $lastHealthCheck) >= $this->healthCheckInterval) {
            $this->performHealthCheck($context);
            $context = $context->withMetadata('last_health_check', $currentTime);
        }

        return $next($context);
    }

    public function getPriority(): int
    {
        return 80; // Hohe Priorität - vor Retry aber nach Lazy Loading
    }

    private function performHealthCheck(QueryContext $context): void
    {
        $result = $this->healthChecker->checkHealth($context->connection);

        if (!$result->isHealthy) {
            throw new DatabaseException(
                "Health check failed: {$result->message}",
                0,
                $result->exception
            );
        }

        // Speichere Health Check Ergebnis im Kontext
        $context->metadata['health_check_result'] = $result;
    }

    public function getLastHealthCheckResult(QueryContext $context): ?HealthCheckResult
    {
        return $context->getMetadata('health_check_result');
    }
}
