<?php

declare(strict_types=1);

namespace App\Framework\Notification;

use App\Framework\Notification\Channels\ChannelResult;

/**
 * Result of a notification send operation across all channels
 */
final readonly class NotificationResult
{
    /**
     * @param Notification $notification The notification that was sent
     * @param array<ChannelResult> $channelResults Results from each channel
     */
    public function __construct(
        public Notification $notification,
        public array $channelResults
    ) {
    }

    /**
     * Check if notification was successfully sent via at least one channel
     *
     * @return bool True if at least one channel succeeded
     */
    public function isSuccess(): bool
    {
        foreach ($this->channelResults as $result) {
            if ($result->isSuccess()) {
                return true;
            }
        }

        return false;
    }

    /**
     * Check if notification failed on all channels
     *
     * @return bool True if all channels failed
     */
    public function isFailure(): bool
    {
        return ! $this->isSuccess();
    }

    /**
     * Get successful channel results
     *
     * @return array<ChannelResult>
     */
    public function getSuccessful(): array
    {
        return array_filter(
            $this->channelResults,
            fn (ChannelResult $result) => $result->isSuccess()
        );
    }

    /**
     * Get failed channel results
     *
     * @return array<ChannelResult>
     */
    public function getFailed(): array
    {
        return array_filter(
            $this->channelResults,
            fn (ChannelResult $result) => $result->isFailure()
        );
    }

    /**
     * Get error messages from failed channels
     *
     * @return array<string>
     */
    public function getErrors(): array
    {
        $errors = [];

        foreach ($this->getFailed() as $result) {
            if ($result->errorMessage !== null) {
                $errors[] = "{$result->channel->value}: {$result->errorMessage}";
            }
        }

        return $errors;
    }
}
