<?php

namespace App\Appointment\Availability\Picker;

use App\Shared\Time\TimeInterval;

/**
 * هر چیزی که یک استراتژی برای مرتب‌کردن کاندیدها لازم دارد.
 *
 * عمداً readonly و بدون دسترسی به دیتابیس: استراتژی باید تابع خالصی از داده‌ای باشد
 * که موتور از قبل خوانده — وگرنه هر استراتژی تازه یک کوئری تازه داخل حلقهٔ کاندید
 * می‌آورد و همان چیزی را می‌شکند که تسک ۰۶ برایش بودجهٔ نیم‌ثانیه گذاشت.
 */
final readonly class PickContext
{
    /**
     * @param array<int, list<TimeInterval>> $freeWindows شناسهٔ منبع => پنجره‌های آزاد
     * @param list<TimeInterval>             $needed      بازه‌هایی که این نقش لازم دارد
     * @param list<int>                      $preferredResourceIds ترجیح — نه الزام
     */
    public function __construct(
        public array $freeWindows,
        public array $needed,
        public int $slotStart,
        public array $preferredResourceIds = [],
    ) {}

    /** زودترین لحظه‌ای که این نقش لازم دارد. */
    public function neededStart(): int
    {
        $starts = array_map(static fn (TimeInterval $i): int => $i->start, $this->needed);

        return $starts === [] ? $this->slotStart : min($starts);
    }

    /** دیرترین لحظه‌ای که این نقش لازم دارد. */
    public function neededEnd(): int
    {
        $ends = array_map(static fn (TimeInterval $i): int => $i->end, $this->needed);

        return $ends === [] ? $this->slotStart : max($ends);
    }
}
