<?php
declare(strict_types=1);

namespace PpPhp\Core\Platform\Rules\Validation;

use PpPhp\Core\Platform\Rules\DecisionTable;
use PpPhp\Core\Platform\Rules\RuleAction;
use PpPhp\Core\Platform\Rules\RuleCondition;
use PpPhp\Core\Platform\Rules\RuleDefinition;
use PpPhp\Core\Platform\Rules\RuleSet;
use PpPhp\Core\Platform\Rules\RulesRuntime;

final class RulesRuntimeVerifier
{
    public function verify(string $basePath): array
    {
        $runtime = RulesRuntime::resetInstance($basePath);
        $runtime->clear();

        $ruleSet = $runtime->registerRuleSet(RuleSet::create('loan_rules', 'Loan Rules', [
            RuleDefinition::create('loan_high_value', 'High Value Loan', [
                RuleCondition::create('amount', 'greaterThanOrEqual', 5000)->toArray(),
                RuleCondition::create('risk', 'equals', 'low')->toArray(),
            ], [
                RuleAction::create('approve_loan', 'setDecision', ['decision' => 'approve'])->toArray(),
            ], 10)->toArray(),
            RuleDefinition::create('loan_reject_risk', 'Reject High Risk', [
                RuleCondition::create('risk', 'equals', 'high')->toArray(),
            ], [
                RuleAction::create('reject_loan', 'setDecision', ['decision' => 'reject'])->toArray(),
            ], 20)->toArray(),
        ]));

        $table = $runtime->registerDecisionTable(DecisionTable::create('loan_decision_table', 'Loan Decision Table', ['amount', 'risk'], ['decision'], [
            [
                'rowId' => 'row_approve',
                'conditions' => [
                    RuleCondition::create('amount', 'greaterThanOrEqual', 5000)->toArray(),
                    RuleCondition::create('risk', 'equals', 'low')->toArray(),
                ],
                'outputs' => ['decision' => 'approve', 'route' => 'fast_track'],
            ],
            [
                'rowId' => 'row_review',
                'conditions' => [
                    RuleCondition::create('amount', 'lessThan', 5000)->toArray(),
                ],
                'outputs' => ['decision' => 'review', 'route' => 'manual'],
            ],
        ]));

        $result = $runtime->evaluate('loan_rules', ['amount' => 7000, 'risk' => 'low']);
        $decision = $runtime->decide('loan_decision_table', ['amount' => 7000, 'risk' => 'low']);
        $runtime->save();

        $second = RulesRuntime::resetInstance($basePath);
        $second->hydrate();

        $summary = $second->summary();
        $stats = $summary['statistics'];

        $checks = [
            'ruleSet' => $ruleSet->ruleSetId() === 'loan_rules',
            'evaluation' => $result->matched() && count($result->actions()) === 1,
            'decisionTable' => $table->tableId() === 'loan_decision_table' && $decision->matched(),
            'statistics' => ($stats['ruleSets'] ?? 0) === 1 && ($stats['rules'] ?? 0) === 2 && ($stats['decisionTables'] ?? 0) === 1,
            'persistence' => $second->store()->exists(),
            'hydration' => count($summary['ruleSets']) === 1 && count($summary['decisionTables']) === 1,
        ];

        $issues = [];
        foreach ($checks as $check => $ok) {
            if (!$ok) {
                $issues[] = ['check' => $check, 'message' => 'Rules runtime verification failed: ' . $check];
            }
        }

        return [
            'ok' => !in_array(false, $checks, true),
            'checks' => $checks,
            'issues' => $issues,
            'summary' => [
                'ruleSets' => $stats['ruleSets'] ?? 0,
                'rules' => $stats['rules'] ?? 0,
                'decisionTables' => $stats['decisionTables'] ?? 0,
                'evaluations' => $stats['evaluations'] ?? 0,
                'score' => in_array(false, $checks, true) ? 80 : 100,
            ],
        ];
    }
}
