<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Event\Sourcing\Projection;

final class ProjectionDefinition
{
    public function __construct(
        private readonly string $projectionId,
        private readonly string $name,
        private readonly array $aggregateTypes = [],
        private readonly array $eventTypes = [],
        private readonly string $status = 'active',
        private readonly int $version = 1,
        private readonly string $createdAt = ''
    ) {}

    public static function create(string $projectionId, string $name, array $aggregateTypes = [], array $eventTypes = []): self
    {
        return new self($projectionId, $name, $aggregateTypes, $eventTypes, 'active', 1, date('c'));
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['projectionId'] ?? ''),
            (string) ($data['name'] ?? ''),
            (array) ($data['aggregateTypes'] ?? []),
            (array) ($data['eventTypes'] ?? []),
            (string) ($data['status'] ?? 'active'),
            (int) ($data['version'] ?? 1),
            (string) ($data['createdAt'] ?? '')
        );
    }

    public function projectionId(): string { return $this->projectionId; }
    public function name(): string { return $this->name; }
    public function status(): string { return $this->status; }
    public function active(): bool { return $this->status === 'active'; }

    public function accepts(array $event): bool
    {
        if (!$this->active()) {
            return false;
        }

        $aggregateType = (string) ($event['aggregateType'] ?? '');
        $eventType = (string) ($event['eventType'] ?? '');

        $aggregateMatch = $this->aggregateTypes === [] || in_array($aggregateType, $this->aggregateTypes, true);
        $eventMatch = $this->eventTypes === [] || in_array($eventType, $this->eventTypes, true);

        return $aggregateMatch && $eventMatch;
    }

    public function toArray(): array
    {
        return [
            'projectionId' => $this->projectionId,
            'name' => $this->name,
            'aggregateTypes' => $this->aggregateTypes,
            'eventTypes' => $this->eventTypes,
            'status' => $this->status,
            'version' => $this->version,
            'createdAt' => $this->createdAt !== '' ? $this->createdAt : date('c'),
        ];
    }
}
