<?php

declare(strict_types=1);

namespace App\Domain\Meta\Entity;

use App\Domain\Meta\ValueObject\MetaData;
use DateTimeImmutable;

class MetaEntry
{
    public function __construct(
        public ?int               $id = null,
        public ?string            $routePattern = null,
        public ?string            $entityType = null,
        public ?int               $entityId = null,
        public ?MetaData          $metaData = null,
        public int                $priority = 0,
        public bool               $active = true,
        public ?DateTimeImmutable $createdAt = null,
        public ?DateTimeImmutable $updatedAt = null,
    ) {
        $this->metaData ??= new MetaData();
        $this->createdAt ??= new DateTimeImmutable();
        $this->updatedAt ??= new DateTimeImmutable();
    }

    public static function forRoute(string $routePattern, MetaData $metaData, int $priority = 0): self
    {
        return new self(
            routePattern: $routePattern,
            metaData: $metaData,
            priority: $priority
        );
    }

    public static function forEntity(string $entityType, int $entityId, MetaData $metaData, int $priority = 0): self
    {
        return new self(
            entityType: $entityType,
            entityId: $entityId,
            metaData: $metaData,
            priority: $priority
        );
    }

    public function updateMetaData(MetaData $metaData): void
    {
        $this->metaData = $metaData;
        $this->updatedAt = new DateTimeImmutable();
    }

    public function activate(): void
    {
        $this->active = true;
        $this->updatedAt = new DateTimeImmutable();
    }

    public function deactivate(): void
    {
        $this->active = false;
        $this->updatedAt = new DateTimeImmutable();
    }

    public function isRouteEntry(): bool
    {
        return $this->routePattern !== null;
    }

    public function isEntityEntry(): bool
    {
        return $this->entityType !== null && $this->entityId !== null;
    }

    public function matchesRoute(string $route): bool
    {
        if (! $this->isRouteEntry()) {
            return false;
        }

        // Exakte Übereinstimmung
        if ($this->routePattern === $route) {
            return true;
        }

        // Pattern-Matching (einfache Wildcard-Unterstützung)
        $pattern = str_replace(['*', '{', '}'], ['.*', '(?P<', '>[^/]+)'], $this->routePattern);

        return (bool) preg_match('#^' . $pattern . '$#', $route);
    }

    public function matchesEntity(string $entityType, int $entityId): bool
    {
        return $this->isEntityEntry()
            && $this->entityType === $entityType
            && $this->entityId === $entityId;
    }

    public function toArray(): array
    {
        return [
            'id' => $this->id,
            'route_pattern' => $this->routePattern,
            'entity_type' => $this->entityType,
            'entity_id' => $this->entityId,
            'meta_data' => $this->metaData?->toArray(),
            'priority' => $this->priority,
            'active' => $this->active,
            'created_at' => $this->createdAt?->format('Y-m-d H:i:s'),
            'updated_at' => $this->updatedAt?->format('Y-m-d H:i:s'),
        ];
    }
}
