<?php

namespace App\Services\Rules;

use App\Models\Rule;

class RuleEngine
{
    public function evaluate(int $tenantId, string $module, array $facts): array
    {
        $effects = [];

        Rule::query()
            ->where('tenant_id', $tenantId)
            ->where('module', $module)
            ->where('is_active', true)
            ->orderBy('priority')
            ->get()
            ->each(function (Rule $rule) use ($facts, &$effects) {
                if ($this->matches($rule->conditions ?? [], $facts)) {
                    $effects[] = ['rule_id' => $rule->id, 'actions' => $rule->actions ?? []];
                }
            });

        return $effects;
    }

    private function matches(array $conditions, array $facts): bool
    {
        foreach ($conditions as $condition) {
            $field = $condition['field'] ?? null;
            $operator = $condition['operator'] ?? '=';
            $value = $condition['value'] ?? null;
            $actual = $facts[$field] ?? null;

            if (!$this->compare($actual, $operator, $value)) {
                return false;
            }
        }

        return true;
    }

    private function compare(mixed $actual, string $operator, mixed $expected): bool
    {
        return match ($operator) {
            '>', 'gt' => $actual > $expected,
            '>=', 'gte' => $actual >= $expected,
            '<', 'lt' => $actual < $expected,
            '<=', 'lte' => $actual <= $expected,
            '!=', 'neq' => $actual != $expected,
            'in' => in_array($actual, (array) $expected, true),
            default => $actual == $expected,
        };
    }
}
