<?php

declare(strict_types=1);

namespace PpPhp\Core\Maintenance\Results;

final class MaintenanceResult
{
    /**
     * @var MaintenanceIssue[]
     */
    private array $issues = [];

    public function __construct(
        private readonly string $providerId,
        private readonly string $providerLabel
    ) {
    }

    public function providerId(): string
    {
        return $this->providerId;
    }

    public function providerLabel(): string
    {
        return $this->providerLabel;
    }

    public function add(MaintenanceIssue $issue): void
    {
        $this->issues[] = $issue;
    }

    public function info(string $message, string $source = '', string $suggestion = '', array $metadata = []): void
    {
        $this->add(new MaintenanceIssue(MaintenanceIssue::INFO, $message, $source, $suggestion, $metadata));
    }

    public function warning(string $message, string $source = '', string $suggestion = '', array $metadata = []): void
    {
        $this->add(new MaintenanceIssue(MaintenanceIssue::WARNING, $message, $source, $suggestion, $metadata));
    }

    public function error(string $message, string $source = '', string $suggestion = '', array $metadata = []): void
    {
        $this->add(new MaintenanceIssue(MaintenanceIssue::ERROR, $message, $source, $suggestion, $metadata));
    }

    /**
     * @return MaintenanceIssue[]
     */
    public function issues(): array
    {
        return $this->issues;
    }

    public function errorCount(): int
    {
        return count(array_filter($this->issues, static fn (MaintenanceIssue $issue): bool => $issue->isError()));
    }

    public function warningCount(): int
    {
        return count(array_filter($this->issues, static fn (MaintenanceIssue $issue): bool => $issue->isWarning()));
    }

    public function hasProblems(): bool
    {
        return $this->errorCount() > 0 || $this->warningCount() > 0;
    }

    public function toArray(): array
    {
        return [
            'providerId' => $this->providerId,
            'providerLabel' => $this->providerLabel,
            'errors' => $this->errorCount(),
            'warnings' => $this->warningCount(),
            'issues' => array_map(
                static fn (MaintenanceIssue $issue): array => $issue->toArray(),
                $this->issues
            ),
        ];
    }
}
