<?php

namespace App\Http\Controllers\Client;

use App\Http\Controllers\Controller;
use App\Models\Booking;
use App\Models\BookingRoom;
use App\Models\Guest;
use App\Models\Room;
use App\Models\RoomCategory;
use App\Services\BookingService;
use App\Services\Client\BookingSessionService;
use App\Services\Client\CurrencyService;
use App\Services\Client\SearchSessionService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;

class BookingController extends Controller
{


    // --------------------------------------------------------------------------------------------< Function
    public function addRoom(Request $request)
    {
        $booking = BookingSessionService::get();
        $search = SearchSessionService::get();

        $roomData = $request->only([
            'room_id',
            'room_number',
            'slug',
            'title',
            'image_url',
            'adults',
            'children',
            'addons',
            'meal_package',
            'room_daily_prices',
        ]);

        // Update if exists or add
        $index = collect($booking['rooms'])->search(fn($r) => $r['room_id'] == $roomData['room_id']);
        if ($index !== false) $booking['rooms'][$index] = $roomData;
        else $booking['rooms'][] = $roomData;

        $booking['check_in'] = $search['check_in'];
        $booking['check_out'] = $search['check_out'];
        $booking['nights'] = $search['nights'];

        BookingSessionService::update($booking);

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

    public function removeRoom(Request $request)
    {
        $booking = BookingSessionService::get();
        $booking['rooms'] = collect($booking['rooms'])
            ->reject(fn($r) => $r['room_id'] == $request->room_id)
            ->values()->toArray();

        BookingSessionService::update($booking);
        return back();
    }

    public function clear()
    {
        BookingSessionService::clear();
        return redirect()->route('rooms');
    }

    public function summary()
    {
        BookingSessionService::updatePriceData();

        $booking = BookingSessionService::get();

        if (!$booking || empty($booking['rooms'])) {
            return redirect('/rooms');
        }


        $capacities = Room::with('roomCategory:id,max_adults,max_children')
            ->select('id', 'room_category_id')
            ->get()
            ->map(function ($room) {
                return [
                    'id' => $room->id,
                    'max_adults' => $room->roomCategory?->max_adults ?? 0,
                    'max_children' => $room->roomCategory?->max_children ?? 0,
                ];
            });

        return Inertia::render('home/summary', [
            'booking' => $booking,
            'room_capacities' => $capacities,
        ]);
    }

    public function saveSummary(Request $request)
    {

        $booking = array_merge(
            BookingSessionService::get(),
            $request->only([
                'rooms',
                'total_adults',
                'total_children',
                'total_price',
                'check_in',
                'check_out',
                'booking_addons'
            ])
        );

        BookingSessionService::update($booking);

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

    public function saveSummeryAndRoomDetails(Request $request, string $slug, string $room_number)
    {
        $booking = array_merge(
            BookingSessionService::get(),
            $request->only([
                'rooms',
                'total_adults',
                'total_children',
                'total_price',
                'check_in',
                'check_out',
                'booking_addons'
            ])
        );


        // Save updated booking to session
        BookingSessionService::update($booking);
        return redirect("/rooms/{$slug}?room={$room_number}");
    }

    public function checkout(Request $request)
    {
        BookingSessionService::updatePriceData();
        $booking = BookingSessionService::get();
        if (!$booking || empty($booking['rooms'])) {
            abort(404, 'Please select a room first.');
        }




        return Inertia::render('home/checkout', compact('booking'));
    }

    public function updateCheckout(Request $request)
    {

        $validated = $request->validate([
            'guest.first_name' => 'required|string|max:255',
            'guest.last_name'  => 'required|string|max:255',
            'guest.email'      => 'required|email|max:255',
            'guest.phone'      => 'required|string|max:50',
            'guest.passport'   => 'nullable|string|max:50',
            'guest.country'    => 'required|string|max:100',
            'guest.special_requests' => 'nullable|string|max:1000',
            'payment_option'   => 'required|in:pay_now,pay_at_hotel'
        ], [
            'guest.first_name.required' => 'Please enter your first name.',
            'guest.first_name.string'   => 'First name must be a valid text.',
            'guest.first_name.max'      => 'First name cannot be longer than 255 characters.',

            'guest.last_name.required'  => 'Please enter your last name.',
            'guest.last_name.string'    => 'Last name must be a valid text.',
            'guest.last_name.max'       => 'Last name cannot be longer than 255 characters.',

            'guest.email.required'      => 'Please enter your email address.',
            'guest.email.email'         => 'Please enter a valid email address.',
            'guest.email.max'           => 'Email cannot be longer than 255 characters.',

            'guest.phone.required'      => 'Please provide your phone number.',
            'guest.phone.string'        => 'Phone number must be valid.',
            'guest.phone.max'           => 'Phone number cannot exceed 50 characters.',

            'guest.passport.string'     => 'Passport must be a valid text.',
            'guest.passport.max'        => 'Passport cannot be longer than 50 characters.',

            'guest.country.required'    => 'Please select your country.',
            'guest.country.string'      => 'Country must be valid text.',
            'guest.country.max'         => 'Country cannot exceed 100 characters.',

            'guest.special_requests.string' => 'Special requests must be valid text.',
            'guest.special_requests.max'    => 'Special requests cannot exceed 1000 characters.',

            'payment_option.required'   => 'Please select a payment option.',
            'payment_option.in'         => 'Payment option must be either "Pay Now" or "Pay at Hotel".',
        ]);

        BookingSessionService::updateGuest($validated['guest']);
        BookingSessionService::updateCurrency();
        BookingSessionService::updatePaymentMethod($validated['payment_option']);

        return back()->with('success', 'Booking info updated.');
    }

    public function store(Request $request, BookingService $service)
    {

        DB::beginTransaction();

        try {

            $booking = BookingSessionService::makeBooking($service);

            DB::commit();

            // Step 3: Save booking ID in session for temporary access
            session(['booking_success_id' => $booking->id]);

            // Remove ONLY booking-related session data
            $request->session()->forget(['booking', 'search']);

            // Step 4: Redirect to success page
            return redirect('/booking/success');
        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json([
                'status' => false,
                'message' => $e->getMessage()
            ], 500);
        }



        //     // temporary unique placeholder
        //     $tempReference = 'TMP-' . uniqid(); // e.g., TMP-605b7f3a2a4c8


        //     $data = $request->all();

        //     /*
        // |-----------------------------------------
        // | 1. Create Guest
        // |-----------------------------------------
        // */
        //     $guestData = $data['guest'];

        //     $guest = Guest::create([
        //         'reference' => $tempReference,
        //         'first_name' => $guestData['first_name'],
        //         'last_name'  => $guestData['last_name'],
        //         'email'      => $guestData['email'],
        //         'phone'      => $guestData['phone'],
        //         'passport'   => $guestData['passport'],
        //         'country'    => $guestData['country'],
        //     ]);

        //     /*
        // |-----------------------------------------
        // | 2. Create Booking
        // |-----------------------------------------
        // */

        //     $booking = Booking::create([
        //         'reference' => $tempReference,

        //         'guest_id' => $guest->id,

        //         'check_in' => $data['check_in'],
        //         'check_out' => $data['check_out'],

        //         'total_price' => $data['total_price'],
        //         'base_currency' => $data['base_currency'],

        //         'display_total_price' => $data['display_total_price'] ?? $data['total_price'],
        //         'display_currency' => $data['display_currency'] ?? $data['base_currency'],

        //         'exchange_rate' => $data['exchange_rate'] ?? 1,

        //         'currency_rate_id' => $data['currency_rate_id'],

        //         'payment_option' => $data['payment_option'],

        //         'price_data' => $data['price_data'] ?? null,

        //         // add addons later

        //         'note'    => $guestData['special_requests'] ?? null,

        //         'status' => 'pending'
        //     ]);

        //     /*
        // |-----------------------------------------
        // | 3. Store Rooms
        // |-----------------------------------------
        // */

        //     foreach ($data['rooms'] as $room) {

        //         BookingRoom::create([
        //             'booking_id' => $booking->id,
        //             'room_id' => $room['room_id'],

        //             'room_title' => $room['title'],
        //             'room_slug' => $room['slug'],
        //             'room_number' => $room['room_number'],

        //             'adults' => $room['adults'],
        //             'children' => $room['children'],

        //             'meal_package' => $room['meal_package'] ?? null,
        //             'addons' => $room['addons'] ?? null,

        //             'room_daily_prices' => $room['room_daily_prices'],

        //             // meal,package total ,addon_total, grand total
        //             // 'grand_total' => $room['grand_total']
        //         ]);
        //     }

        //     DB::commit();

        //     // Step 2: Refresh to get final reference
        //     $booking = $booking->fresh();

        //     // Step 3: Save booking ID in session for temporary access
        //     session(['booking_success_id' => $booking->id]);

        //     // Remove ONLY booking-related session data
        //     $request->session()->forget(['booking', 'search']);

        //     // Step 4: Redirect to success page
        //     return redirect('/booking/success');
        // } catch (\Exception $e) {

        //     DB::rollBack();

        //     return response()->json([
        //         'status' => false,
        //         'message' => $e->getMessage()
        //     ], 500);
        // }
    }


    public function test(Request $request)
    {
        // Step 3: Save booking ID in session for temporary access
        session(['booking_success_id' => 1]);

        // Step 4: Redirect to success page
        return redirect()->route('booking.success');
    }

    public function success(Request $request)
    {
        $bookingId = $request->session()->get('booking_success_id');

        if (!$bookingId) {
            // User manually opened the page without POST → block
            abort(404, 'Booking details are not available.');
        }

        $booking = Booking::with(['guest', 'rooms'])->findOrFail($bookingId);

        // Clear session after showing success (optional)
        // $request->session()->forget('booking_success_id');

        return Inertia::render('home/success', [
            'bookingSave' => $booking
        ]);
    }

    public function view(Request $request)
    {
        $request->validate([
            'reference' => 'required|string',
            'email' => 'required|email'
        ]);


        $booking = Booking::where('reference', $request->reference)
            ->whereHas('guest', function ($q) use ($request) {
                $q->where('email', $request->email);
            })
            ->with(['guest', 'rooms'])
            ->first();

        if (!$booking) {
            abort(404, 'Booking not found or access denied.');
        }

        return Inertia::render('home/booking-details', [
            'bookingData' => $booking
        ]);
    }
}
