<?php

declare(strict_types=1);

namespace App\Framework\Database\Monitoring\Health;

/**
 * Represents the result of multiple health checks
 */
final class HealthCheckResult
{
    /**
     * @var array<string, array{id: string, name: string, status: HealthCheckStatus, description: string}> Health checks by ID
     */
    private array $checks = [];

    /**
     * @var array<string, array{id: string, name: string, message: string}> Errors by ID
     */
    private array $errors = [];

    /**
     * @var string The connection name
     */
    private string $connection;

    /**
     * @var \DateTimeImmutable The timestamp when the health check was performed
     */
    private \DateTimeImmutable $timestamp;

    public function __construct(string $connection)
    {
        $this->connection = $connection;
        $this->timestamp = new \DateTimeImmutable();
    }

    /**
     * Add a health check
     */
    public function addCheck(string $id, string $name, HealthCheckStatus $status, string $description): void
    {
        $this->checks[$id] = [
            'id' => $id,
            'name' => $name,
            'status' => $status,
            'description' => $description,
        ];
    }

    /**
     * Add an error
     */
    public function addError(string $id, string $name, string $message): void
    {
        $this->errors[$id] = [
            'id' => $id,
            'name' => $name,
            'message' => $message,
        ];
    }

    /**
     * Get all health checks
     *
     * @return array<string, array{id: string, name: string, status: HealthCheckStatus, description: string}>
     */
    public function getChecks(): array
    {
        return $this->checks;
    }

    /**
     * Get all errors
     *
     * @return array<string, array{id: string, name: string, message: string}>
     */
    public function getErrors(): array
    {
        return $this->errors;
    }

    /**
     * Get the connection name
     */
    public function getConnection(): string
    {
        return $this->connection;
    }

    /**
     * Get the timestamp
     */
    public function getTimestamp(): \DateTimeImmutable
    {
        return $this->timestamp;
    }

    /**
     * Check if there are any errors
     */
    public function hasErrors(): bool
    {
        return ! empty($this->errors);
    }

    /**
     * Check if there are any warnings
     */
    public function hasWarnings(): bool
    {
        foreach ($this->checks as $check) {
            if ($check['status']->isWarning()) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if all checks are OK
     */
    public function isHealthy(): bool
    {
        if ($this->hasErrors()) {
            return false;
        }

        foreach ($this->checks as $check) {
            if (! $check['status']->isOk()) {
                return false;
            }
        }

        return true;
    }

    /**
     * Get the overall status
     */
    public function getOverallStatus(): string
    {
        if ($this->hasErrors()) {
            return HealthCheckStatus::ERROR;
        }

        if ($this->hasWarnings()) {
            return HealthCheckStatus::WARNING;
        }

        return HealthCheckStatus::OK;
    }

    /**
     * Get the result as an array
     * @return array<string, mixed>
     */
    public function toArray(): array
    {
        $checks = [];
        foreach ($this->checks as $check) {
            $checks[$check['id']] = [
                'id' => $check['id'],
                'name' => $check['name'],
                'status' => $check['status']->status,
                'message' => $check['status']->message,
                'description' => $check['description'],
            ];
        }

        $errors = [];
        foreach ($this->errors as $error) {
            $errors[$error['id']] = [
                'id' => $error['id'],
                'name' => $error['name'],
                'message' => $error['message'],
            ];
        }

        return [
            'connection' => $this->connection,
            'timestamp' => $this->timestamp->format('Y-m-d H:i:s'),
            'overall_status' => $this->getOverallStatus(),
            'is_healthy' => $this->isHealthy(),
            'checks' => $checks,
            'errors' => $errors,
        ];
    }
}
