<?php
declare(strict_types=1);

namespace ROITheme\Shared\Domain\ValueObjects;

/**
 * Value Object: Exclusion por ID de post/pagina
 *
 * Evalua si el post/pagina actual esta en la lista de IDs excluidos.
 *
 * @package ROITheme\Shared\Domain\ValueObjects
 */
final class PostIdExclusion extends ExclusionRule
{
    /**
     * @param array<int> $excludedPostIds Lista de IDs de posts/paginas
     */
    public function __construct(
        private readonly array $excludedPostIds = []
    ) {}

    /**
     * {@inheritdoc}
     *
     * Contexto esperado:
     * - post_id: int
     */
    public function matches(array $context): bool
    {
        if (!$this->hasValues()) {
            return false;
        }

        $postId = $context['post_id'] ?? 0;

        if ($postId === 0) {
            return false;
        }

        return in_array($postId, $this->excludedPostIds, true);
    }

    public function hasValues(): bool
    {
        return !empty($this->excludedPostIds);
    }

    public function serialize(): string
    {
        return json_encode($this->excludedPostIds);
    }

    /**
     * @return array<int>
     */
    public function getExcludedPostIds(): array
    {
        return $this->excludedPostIds;
    }

    /**
     * Crea instancia desde JSON
     */
    public static function fromJson(string $json): self
    {
        $decoded = json_decode($json, true);

        if (!is_array($decoded)) {
            return self::empty();
        }

        // Asegurar que son enteros
        $ids = array_map('intval', $decoded);
        $ids = array_filter($ids, fn(int $id): bool => $id > 0);

        return new self(array_values($ids));
    }

    /**
     * Crea instancia vacia
     */
    public static function empty(): self
    {
        return new self([]);
    }
}
