<?php

namespace App\Http\Controllers;

use App\Models\Room;
use App\Models\RoomBooking;
use App\Models\Vehicle;
use App\Models\VehicleBooking;
use Carbon\Carbon;
use Illuminate\Support\Collection;

class LandingController extends Controller
{
    private const ACTIVE_STATUSES = ['approved', 'final_approved'];

    public function index()
    {
        $now = now();

        $rooms = Room::query()
            ->with(['bookings' => fn ($query) => $query
                ->whereIn('status', self::ACTIVE_STATUSES)
                ->where('end_time', '>=', $now)
                ->orderBy('start_time')])
            ->get()
            ->map(fn (Room $room) => $this->decorateRoom($room, $now));

        $vehicles = Vehicle::query()
            ->with([
                'divisi',
                'bookings' => fn ($query) => $query
                    ->whereIn('status', self::ACTIVE_STATUSES)
                    ->where('end_time', '>=', $now)
                    ->orderBy('start_time'),
            ])
            ->orderBy('created_at', 'desc')
            ->get()
            ->map(fn (Vehicle $vehicle) => $this->decorateVehicle($vehicle, $now));

        return view('landing.index', compact('rooms', 'vehicles'));
    }

    private function decorateRoom(Room $room, Carbon $now): Room
    {
        $activeSchedule = $this->activeSchedule($room->bookings, $now);
        $nearestSchedule = $activeSchedule ?? $this->nearestSchedule($room->bookings, $now);
        $isOperational = !in_array($room->manual_status, ['maintenance', 'closed'], true);

        $room->landing_is_used = $activeSchedule !== null || !$isOperational;
        $room->landing_status = $room->landing_is_used ? 'Dipakai' : 'Tersedia';
        $room->landing_status_class = $room->landing_is_used
            ? 'bg-rose-600 text-white border-rose-300/70'
            : 'bg-emerald-600 text-white border-emerald-300/70';
        $room->landing_schedule = $this->formatScheduleDescription($nearestSchedule, 'Dipakai');

        return $room;
    }

    private function decorateVehicle(Vehicle $vehicle, Carbon $now): Vehicle
    {
        $activeSchedule = $this->activeSchedule($vehicle->bookings, $now);
        $nearestSchedule = $activeSchedule ?? $this->nearestSchedule($vehicle->bookings, $now);
        $isOperational = !in_array($vehicle->status, ['maintenance', 'unavailable'], true);

        $vehicle->landing_is_used = $activeSchedule !== null || !$isOperational;
        $vehicle->landing_status = $vehicle->landing_is_used ? 'Dipakai' : 'Tersedia';
        $vehicle->landing_status_class = $vehicle->landing_is_used
            ? 'bg-rose-600 text-white border-rose-300/70'
            : 'bg-emerald-600 text-white border-emerald-300/70';
        $vehicle->landing_schedule = $this->formatScheduleDescription($nearestSchedule, 'Dipakai');

        return $vehicle;
    }

    private function activeSchedule(Collection $bookings, Carbon $now): ?object
    {
        return $bookings
            ->first(fn ($booking) => Carbon::parse($booking->start_time)->lte($now)
                && Carbon::parse($booking->end_time)->gt($now));
    }

    private function nearestSchedule(Collection $bookings, Carbon $now): ?object
    {
        return $bookings
            ->filter(fn ($booking) => Carbon::parse($booking->end_time)->gte($now))
            ->sortBy(fn ($booking) => Carbon::parse($booking->start_time)->timestamp)
            ->first();
    }

    private function formatScheduleDescription(?object $booking, string $prefix): string
    {
        if (!$booking) {
            return '';
        }

        $start = Carbon::parse($booking->start_time);
        $end = Carbon::parse($booking->end_time);

        $datePart = $start->translatedFormat('d M Y');
        $timePart = $start->format('H:i') . '-' . $end->format('H:i');

        if (!$start->isSameDay($end)) {
            $timePart = $start->format('H:i') . ' - ' . $end->translatedFormat('d M Y, H:i');
        }

        return "{$prefix} {$datePart}, {$timePart}";
    }
}
