<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Rules;

final class DecisionTable
{
    public function __construct(
        private readonly string $tableId,
        private readonly string $name,
        private readonly array $inputs = [],
        private readonly array $outputs = [],
        private readonly array $rows = [],
        private readonly string $hitPolicy = 'FIRST',
        private readonly string $createdAt = ''
    ) {}

    public static function create(string $tableId, string $name, array $inputs = [], array $outputs = [], array $rows = [], string $hitPolicy = 'FIRST'): self
    {
        return new self($tableId, $name, $inputs, $outputs, $rows, $hitPolicy, date('c'));
    }

    public static function fromArray(array $data): self
    {
        return new self(
            (string) ($data['tableId'] ?? ''),
            (string) ($data['name'] ?? ''),
            (array) ($data['inputs'] ?? []),
            (array) ($data['outputs'] ?? []),
            (array) ($data['rows'] ?? []),
            (string) ($data['hitPolicy'] ?? 'FIRST'),
            (string) ($data['createdAt'] ?? '')
        );
    }

    public function tableId(): string { return $this->tableId; }

    public function evaluate(array $facts): array
    {
        $matches = [];

        foreach ($this->rows as $row) {
            $ok = true;
            foreach ((array) ($row['conditions'] ?? []) as $condition) {
                if (!RuleCondition::fromArray((array) $condition)->evaluate($facts)) {
                    $ok = false;
                    break;
                }
            }

            if ($ok) {
                $matches[] = [
                    'rowId' => (string) ($row['rowId'] ?? ''),
                    'outputs' => (array) ($row['outputs'] ?? []),
                ];

                if ($this->hitPolicy === 'FIRST') {
                    break;
                }
            }
        }

        return $matches;
    }

    public function toArray(): array
    {
        return [
            'tableId' => $this->tableId,
            'name' => $this->name,
            'inputs' => $this->inputs,
            'outputs' => $this->outputs,
            'rows' => $this->rows,
            'hitPolicy' => $this->hitPolicy,
            'createdAt' => $this->createdAt !== '' ? $this->createdAt : date('c'),
        ];
    }
}
