<?php
declare(strict_types=1);

namespace App\Modules\Facilities\Services;

use App\Modules\Facilities\Models\Facility;
use App\Modules\Facilities\Models\FacilityTimeSlot;
use App\Modules\Facilities\Models\FacilityBlackoutDate;

class FacilityService
{
    /**
     * Get all active facilities.
     */
    public static function getActive(): array
    {
        return Facility::allActive();
    }

    /**
     * Get active facilities filtered by facility type.
     */
    public static function getByType(string $type): array
    {
        return Facility::getByType($type);
    }

    /**
     * Get available time slots for a facility on a given date.
     *
     * Checks the day_of_week from the date, fetches matching time slots
     * that are active and of type 'available', and excludes any that fall
     * within blackout date windows.
     */
    public static function getAvailableSlots(int $facilityId, string $date): array
    {
        // Determine day of week (0 = Sunday, 6 = Saturday)
        $dayOfWeek = (int) date('w', strtotime($date));

        // Get all active slots for this facility on this day
        $slots = FacilityTimeSlot::query()
            ->where('facility_id', '=', $facilityId)
            ->where('day_of_week', '=', $dayOfWeek)
            ->where('slot_type', '=', 'available')
            ->where('is_active', '=', 1)
            ->orderBy('start_time', 'ASC')
            ->get();

        if (empty($slots)) {
            return [];
        }

        // Filter out slots that overlap with blackout dates
        $available = [];
        foreach ($slots as $slot) {
            $startTime = $slot['start_time'] ?? null;
            if (!FacilityBlackoutDate::isBlackedOut($facilityId, $date, $startTime)) {
                $available[] = $slot;
            }
        }

        return $available;
    }

    /**
     * Get the correct hourly rate for a facility.
     *
     * @param int    $facilityId  The facility ID
     * @param bool   $isMember    Whether the person is a club member
     * @param string $timeTier    'AM' for morning rates, 'PM' for evening rates
     */
    public static function getRate(int $facilityId, bool $isMember, string $timeTier = 'AM'): float
    {
        $facility = Facility::find($facilityId);
        if (!$facility) {
            return 0.0;
        }
        return $facility->getRate($isMember, $timeTier);
    }

    /**
     * Get all active facilities grouped by facility_type.
     */
    public static function getGroupedByType(): array
    {
        $facilities = Facility::allActive();
        $grouped = [];

        // Initialize all type keys
        foreach (Facility::getTypes() as $key => $label) {
            $grouped[$key] = [];
        }

        foreach ($facilities as $f) {
            $type = $f['facility_type'] ?? 'pitch';
            if (!isset($grouped[$type])) {
                $grouped[$type] = [];
            }
            $grouped[$type][] = $f;
        }

        return $grouped;
    }

    /**
     * Block a slot by creating a blackout date entry.
     */
    public static function blockSlot(
        int $facilityId,
        string $date,
        ?string $startTime,
        ?string $endTime,
        string $reason
    ): object {
        return FacilityBlackoutDate::create([
            'facility_id'   => $facilityId,
            'blackout_date' => $date,
            'start_time'    => $startTime ?: null,
            'end_time'      => $endTime ?: null,
            'reason'        => $reason,
            'created_by'    => $_SESSION['user_id'] ?? null,
        ]);
    }
}
