<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event;

use PpPhp\Core\Platform\Event\Contracts\StoppableEventInterface;

class Event implements StoppableEventInterface
{
    private bool $stopped = false;

    public function __construct(
        private readonly string $name,
        private readonly array $payload = [],
        private readonly array $metadata = [],
        private readonly string $occurredAt = ''
    ) {}

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

    public function occurredAt(): string
    {
        return $this->occurredAt !== '' ? $this->occurredAt : date('c');
    }

    public function payload(): array
    {
        return $this->payload;
    }

    public function metadata(): array
    {
        return $this->metadata;
    }

    public function isPropagationStopped(): bool
    {
        return $this->stopped;
    }

    public function stopPropagation(): void
    {
        $this->stopped = true;
    }

    public function withMetadata(string $key, mixed $value): self
    {
        $metadata = $this->metadata;
        $metadata[$key] = $value;

        return new self($this->name, $this->payload, $metadata, $this->occurredAt());
    }

    public function toArray(): array
    {
        return [
            'name' => $this->name(),
            'occurredAt' => $this->occurredAt(),
            'payload' => $this->payload(),
            'metadata' => $this->metadata(),
            'stopped' => $this->isPropagationStopped(),
        ];
    }
}
