<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Rules;

final class RuleCondition
{
    public function __construct(
        private readonly string $field,
        private readonly string $operator,
        private readonly mixed $value,
        private readonly string $createdAt = ''
    ) {}

    public static function create(string $field, string $operator, mixed $value): self
    {
        return new self($field, $operator, $value, date('c'));
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['field'] ?? ''),
            (string) ($data['operator'] ?? 'equals'),
            $data['value'] ?? null,
            (string) ($data['createdAt'] ?? '')
        );
    }

    public function evaluate(array $facts): bool
    {
        $actual = $facts[$this->field] ?? null;

        return match ($this->operator) {
            'equals', '=' => $actual == $this->value,
            'notEquals', '!=' => $actual != $this->value,
            'greaterThan', '>' => is_numeric($actual) && is_numeric($this->value) && $actual > $this->value,
            'greaterThanOrEqual', '>=' => is_numeric($actual) && is_numeric($this->value) && $actual >= $this->value,
            'lessThan', '<' => is_numeric($actual) && is_numeric($this->value) && $actual < $this->value,
            'lessThanOrEqual', '<=' => is_numeric($actual) && is_numeric($this->value) && $actual <= $this->value,
            'in' => is_array($this->value) && in_array($actual, $this->value, true),
            'contains' => is_array($actual) && in_array($this->value, $actual, true),
            'exists' => array_key_exists($this->field, $facts),
            default => false,
        };
    }

    public function toArray(): array
    {
        return [
            'field' => $this->field,
            'operator' => $this->operator,
            'value' => $this->value,
            'createdAt' => $this->createdAt !== '' ? $this->createdAt : date('c'),
        ];
    }
}
