<?php

namespace App\Http\Controllers\Client;

use App\Http\Controllers\Controller;
use App\Models\Addon;
use App\Models\Facility;
use App\Models\MealPackage;
use App\Models\PriceModifier;
use App\Models\RoomCategory;
use App\Services\Client\BookingSessionService;
use App\Services\Client\MealPackageAvailabilityService;
use App\Services\Client\PricingService;
use App\Services\Client\RoomDetailService;
use App\Services\Client\SearchSessionService;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Inertia\Inertia;

class RoomController extends Controller
{


    public function search(Request $request)
    {
        SearchSessionService::update([
            'check_in' => Carbon::parse($request->check_in)->format('Y-m-d'),
            'check_out' => Carbon::parse($request->check_out)->format('Y-m-d'),
            'adults' => $request->adults,
            'children' => $request->children,
        ]);


        BookingSessionService::clear();

        return redirect()->route('rooms');
    }

    // Load the rooms page with serach params and avaialbe rooms
    public function rooms()
    {
        $search = SearchSessionService::get();
        $checkIn = $search['check_in'];
        $checkOut = $search['check_out'];
        $adults = $search['adults'] ?? 1;
        $children = $search['children'] ?? 0;

        $roomCategories = RoomCategory::query()
            ->where('max_adults', '>=', $adults)
            ->where('max_children', '>=', $children)
            ->with([
                'facilities:id,name,is_icon,icon_value',
                'rooms' => function ($q) use ($checkIn, $checkOut) {
                    $q->availableFor($checkIn, $checkOut);
                },
            ])
            ->withCount(['rooms as available_rooms_count' => function ($q) use ($checkIn, $checkOut) {
                $q->availableFor($checkIn, $checkOut);
            }])
            ->orderBy('sort_order', 'asc')
            ->having('available_rooms_count', '>', 0) // only categories with available 
            ->get(['id', 'name', 'short_name', 'slug', 'description', 'base_price', 'currency', 'max_adults', 'max_children'])
            ->map(function ($category) {
                $category->setRelation('facilities',  collect($category->facilities->map(fn($f) =>  ['name' => $f->name,  'is_icon' => $f->is_icon,  'icon_value' => $f->icon_value])));
                $category->setRelation('rooms',  collect($category->rooms->map(fn($r) =>  ['url' => $r->thumbnail()?->url, 'alt_text' => $r->thumbnail()?->alt_text])));
                return $category;
            });

        return Inertia::render('home/rooms', [
            'roomCategories' => $roomCategories,
            'mealPackages' => MealPackageAvailabilityService::getPublicMealPackages(),
            'maxAdults' => RoomCategory::getMaxAdultsAllowed(),
            'maxChildren' =>  RoomCategory::getMaxChildrenAllowed()
        ]);
    }

    // show only avaialbe rooms in room details page
    public function show(string $slug, Request $request)
    {
        $search = SearchSessionService::get();
        $checkIn = $search['check_in'];
        $checkOut = $search['check_out'];
        $adults = $search['adults'] ?? 1;
        $children = $search['children'] ?? 0;

        // -----------------------------------------------------------------------------------------------<  Get all rooms that are availble for the cheick in and check out date
        $category = RoomDetailService::getCategory($slug, $checkIn, $checkOut, $adults, $children, true);

        // If roomId is set, validate it exists in the category
        $activeRoomTab = $request->query('room');
        if ($activeRoomTab && !$category->rooms->contains('room_number', $activeRoomTab)) {
            abort(404); // or redirect to another page
        }

        // ----------------------------------------------------------------------------------------------< Prcing for room, calculate total and avarage and diplay the price for each night
        $checkInDate = isset($search['check_in']) ? Carbon::parse($search['check_in']) : now();
        $calendarStart = $checkInDate->copy()->startOfMonth(); // Start from the 1st day of check-in month
        $calendarEnd = $calendarStart->copy()->addMonths(2)->endOfMonth();   // End two months later

        $pricingService = new PricingService();

        foreach ($category->rooms as $room) {

            // Room price calculation
            $room->room_daily_prices = $pricingService->roomDailyPrices($room, $checkIn, $checkOut, $category);

            // Attach calendar prices
            $room->calendar_prices = $pricingService->availableCalendar($room,  $calendarStart,  $calendarEnd,  $category);

            // Final availability
            $room->isAvailable =  $category->max_adults >= $adults && $category->max_children >= $children;

            // Filter addons amd meals for room
            $room->setRelation('mealPackages',  MealPackageAvailabilityService::filterAvailbleItems($room->mealPackages, $checkIn, $checkOut));
            $room->setRelation('addOns',  RoomDetailService::filterByDates($room->addOns, $checkIn, $checkOut));
        }

        // /------------------------------------------------------------------------------------------<  MealPackage and Addons for category
        $category->setRelation('mealPackages', MealPackageAvailabilityService::filterAvailbleItems($category->mealPackages, $checkIn, $checkOut));

        // $category->setRelation('mealPackages',  RoomDetailService::filterByDates($category->mealPackages, $checkIn, $checkOut));
        $category->setRelation('addOns',  RoomDetailService::filterByDates($category->addOns, $checkIn, $checkOut));
        $allRoomItems = RoomDetailService::getAllRoomItems($checkIn, $checkOut);

        return Inertia::render('home/room/index', [
            'category' => $category,
            ...$allRoomItems,
            'activeRoom' => $activeRoomTab

        ]);
    }

    // show all rooms in room details page and metion availble and not availble rooms: load from home page rooms section
    public function showAll(string $slug, Request $request)
    {
        $search = SearchSessionService::get();
        $checkIn = $search['check_in'];
        $checkOut = $search['check_out'];
        $adults = $search['adults'] ?? 1;
        $children = $search['children'] ?? 0;

        // -----------------------------------------------------------------------------------------------<  Get all rooms that avalable and not  for the cheick in and check out date
        $category = RoomDetailService::getCategory($slug, $checkIn, $checkOut, $adults, $children, false);

        // If roomId is set, validate it exists in the category
        $activeRoomTab = $request->query('room');
        if ($activeRoomTab && !$category->rooms->contains('room_number', $activeRoomTab)) {
            abort(404); // or redirect to another page
        }

        // ----------------------------------------------------------------------------------------------< Prcing for room, calculate total and avarage and diplay the price for each night
        $checkInDate = isset($search['check_in']) ? Carbon::parse($search['check_in']) : now();
        $calendarStart = $checkInDate->copy()->startOfMonth(); // Start from the 1st day of check-in month
        $calendarEnd = $calendarStart->copy()->addMonths(2)->endOfMonth();   // End two months later

        $pricingService = new PricingService();

        foreach ($category->rooms as $room) {

            // Availability check (clean + reusable) | Mark availability per room
            $dateAvailable = $room->isAvailableFor($checkIn, $checkOut);

            // Capacity availability from category
            $capacityAvailable =
                $category->max_adults >= $adults &&
                $category->max_children >= $children;

            // Final availability
            $room->isAvailable = $dateAvailable && $capacityAvailable;

            /// Room price calculation
            $room->room_daily_prices = $pricingService->roomDailyPrices($room, $checkIn, $checkOut, $category);

            // Attach calendar prices
            $room->calendar_prices = $pricingService->availableCalendar($room,  $calendarStart,  $calendarEnd,  $category);

            // Filter addons amd meals for room
            $room->setRelation('mealPackages',  MealPackageAvailabilityService::filterAvailbleItems($room->mealPackages, $checkIn, $checkOut));
            $room->setRelation('addOns',  RoomDetailService::filterByDates($room->addOns, $checkIn, $checkOut));
        }

        // /------------------------------------------------------------------------------------------<  MealPackage and Addons for category
        $category->setRelation('mealPackages', MealPackageAvailabilityService::filterAvailbleItems($category->mealPackages, $checkIn, $checkOut));

        $category->setRelation('addOns',  RoomDetailService::filterByDates($category->addOns, $checkIn, $checkOut));
        $allRoomItems = RoomDetailService::getAllRoomItems($checkIn, $checkOut);

        return Inertia::render('home/room/index', [
            'category' => $category,
            ...$allRoomItems,
            'activeRoom' => $activeRoomTab

        ]);
    }
}
