<?php

namespace App\Services;

use App\Models\ExternalBusyWindow;
use Carbon\Carbon;

class AvailabilityService
{
    public function __construct(
        private readonly string $tz = 'Europe/London',
        private readonly int $bufferMins = 40
    ) {}

    /**
     * Check if a single slot (date + time) is blocked by external busy windows,
     * considering a travel buffer before start and after end.
     */
    public function isSlotBlockedByExternalBusy(string $dateYmd, string $timeHi, int $durationMins = 60): bool
    {
        // Build slot window in UTC
        $slotStartLocal = Carbon::createFromFormat('Y-m-d H:i', "{$dateYmd} {$timeHi}", $this->tz);
        $slotStartUtc   = $slotStartLocal->clone()->utc();
        $slotEndUtc     = $slotStartUtc->clone()->addMinutes($durationMins);

        // Expand comparison bounds by buffer
        $slotStartMinusBuffer = $slotStartUtc->clone()->subMinutes($this->bufferMins);
        $slotEndPlusBuffer    = $slotEndUtc->clone()->addMinutes($this->bufferMins);

        // Overlap: busyStart < slotEnd+buffer  AND  busyEnd > slotStart-buffer
        return ExternalBusyWindow::query()
            ->where('starts_at', '<', $slotEndPlusBuffer)
            ->where('ends_at',   '>', $slotStartMinusBuffer)
            ->exists();
    }

    /**
     * For block-booking: given a set of future candidate dates for a given time,
     * return the subset that are blocked (with reasons).
     *
     * @param array<string> $dateListYmd  e.g. ['2025-10-27','2025-11-03', ...]
     * @return array<int, array{date:string, blocked:bool}>
     */
    public function checkSeriesConflicts(array $dateListYmd, string $timeHi, int $durationMins = 60): array
    {
        $results = [];
        foreach ($dateListYmd as $ymd) {
            $blocked = $this->isSlotBlockedByExternalBusy($ymd, $timeHi, $durationMins);
            $results[] = [
                'date'    => $ymd,
                'blocked' => $blocked,
            ];
        }
        return $results;
    }
}