<?php

namespace App\Policy\ValueObject;

/**
 * نتیجهٔ اعمال یک دسته قانون: اثرهای ترکیب‌شده + ردِ قانون‌هایی که اعمال شدند.
 *
 * `appliedPolicies` شناسه **و نسخه** را نگه می‌دارد. فقط شناسه کافی نیست: قانون فردا
 * نسخهٔ ۲ می‌گیرد و آن‌وقت «چرا این نوبت این قیمت را گرفت؟» جواب اشتباه می‌دهد.
 */
final readonly class PolicyOutcome
{
    /**
     * @param array<string, mixed>       $effects        نوعِ اثر => مقدار ترکیب‌شده
     * @param list<array<string, mixed>> $appliedPolicies
     * @param list<string>               $forbidReasons  پیام‌های انسانیِ ممنوعیت
     */
    public function __construct(
        public array $effects = [],
        public array $appliedPolicies = [],
        public array $forbidReasons = [],
    ) {}

    public function isForbidden(): bool
    {
        return $this->forbidReasons !== [];
    }

    public function effect(string $type, mixed $default = null): mixed
    {
        return $this->effects[$type] ?? $default;
    }

    public function toArray(): array
    {
        return [
            'effects'          => (object) $this->effects,
            'applied_policies' => $this->appliedPolicies,
            'forbidden'        => $this->isForbidden(),
            'forbid_reasons'   => $this->forbidReasons,
        ];
    }
}
