<?php
declare(strict_types=1);

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

final class QueryFilter
{
    public function __construct(private readonly array $criteria = []) {}

    public static function create(array $criteria = []): self
    {
        return new self($criteria);
    }

    public static function fromArray(array $data): self
    {
        return new self((array) ($data['criteria'] ?? $data));
    }

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

    public function matches(array $row): bool
    {
        foreach ($this->criteria as $field => $expected) {
            $actual = $this->value($row, (string) $field);

            if (is_array($expected)) {
                if (!in_array($actual, $expected, true)) {
                    return false;
                }
                continue;
            }

            if ($actual !== $expected) {
                return false;
            }
        }

        return true;
    }

    private function value(array $row, string $field): mixed
    {
        $parts = explode('.', $field);
        $value = $row;

        foreach ($parts as $part) {
            if (!is_array($value) || !array_key_exists($part, $value)) {
                return null;
            }

            $value = $value[$part];
        }

        return $value;
    }

    public function toArray(): array
    {
        return ['criteria' => $this->criteria];
    }
}
