<?php

declare(strict_types=1);

namespace App\Domain\Policy;

use DateTimeImmutable;

/**
 * Distribution policy. Each policy has a set of (category_id => threshold)
 * entries: an IP appears on this policy's blocklist when **any** mapped
 * category meets its threshold. Categories absent from `thresholds` are
 * ignored entirely by the policy (per SPEC §4 / §5).
 */
final class Policy
{
    /**
     * @param array<int, float> $thresholds category_id => threshold
     */
    public function __construct(
        public readonly int $id,
        public readonly string $name,
        public readonly ?string $description,
        public readonly bool $includeManualBlocks,
        public readonly array $thresholds,
        public readonly DateTimeImmutable $createdAt,
    ) {
    }

    /**
     * Returns the policy's threshold for a category, or null if the category
     * is not part of this policy.
     */
    public function thresholdFor(int $categoryId): ?float
    {
        return $this->thresholds[$categoryId] ?? null;
    }

    /**
     * @param array<int, string> $slugByCategoryId
     * @return array<string, mixed>
     */
    public function toArray(array $slugByCategoryId = []): array
    {
        $thresholds = [];
        foreach ($this->thresholds as $categoryId => $threshold) {
            $slug = $slugByCategoryId[$categoryId] ?? null;
            $thresholds[] = [
                'category_id' => $categoryId,
                'category_slug' => $slug,
                'threshold' => $threshold,
            ];
        }

        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'include_manual_blocks' => $this->includeManualBlocks,
            'thresholds' => $thresholds,
            'created_at' => $this->createdAt->format('Y-m-d\TH:i:s\Z'),
        ];
    }
}
