<?php
// app/Http/Controllers/Api/V1/ServiceBookingController.php

namespace App\Http\Controllers\Api\V1;

use Carbon\Carbon;
use App\Models\Cart;
use App\Models\User;
use App\Models\Coupon;
use App\Models\Booking;
use App\Models\CartServiceAddon;
use App\Models\Package;
use App\Models\Service;
use App\Models\Setting;
use App\Models\TempOrder;
use App\Models\CartSession;
use App\Models\TempBooking;
use App\Models\UserAddress;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use App\Models\ServiceOption;
use App\Models\BookingSession;
use App\Models\CartServiceOption;
use App\Models\ServicePriceMatrix;
use App\Models\TempBookingSession;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Http\Controllers\Controller;
use App\Models\BookingServiceOption;
use Illuminate\Support\Facades\Auth;
use App\Models\TempBookingServiceOption;
use App\Models\TimeSlot;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Http;
class ServiceBookingController extends Controller
{
    private function validateAccessToken(Request $request, $validateToken = true)
    {
        // Step 1: Validate access_token field exists
        if ($validateToken) {
            $rules = ['access_token' => 'required|string'];
            $validator = Validator::make($request->all(), $rules);

            if ($validator->fails()) {
                return [
                    'success' => false,
                    'user' => null,
                    'response' => response()->json([
                        'status' => "0",
                        'message' => 'Access token is required',
                        'error' => $validator->messages(),
                    ], 200)
                ];
            }
        }

        // Step 2: Check if access_token is provided
        if (!$request->has('access_token') || empty($request->access_token)) {
            return [
                'success' => false,
                'user' => null,
                'response' => response()->json([
                    'status' => "0",
                    'message' => 'Access token is required',
                    'error' => (object) []
                ], 200)
            ];
        }

        try {
            // Step 3: Find user with access_token
            $user = User::where('access_token', $request->access_token)
                ->where('role', 2) // Only customers
                ->whereNull('deleted_at')
                ->first();

            // Step 4: Check if user exists
            if (!$user) {
                return [
                    'success' => false,
                    'user' => null,
                    'response' => response()->json([
                        'status' => "0",
                        'message' => 'Invalid or expired access token. Please login again.',
                        'error' => (object) []
                    ], 401)
                ];
            }

            // Step 5: Check if user is active (optional - if you have status field)
            if (isset($user->status) && $user->status != 1) {
                return [
                    'success' => false,
                    'user' => null,
                    'response' => response()->json([
                        'status' => "0",
                        'message' => 'Your account is inactive. Please contact support.',
                        'error' => (object) []
                    ], 403)
                ];
            }

            // Success - return user
            return [
                'success' => true,
                'user' => $user,
                'response' => null
            ];

        } catch (\Exception $e) {
            return [
                'success' => false,
                'user' => null,
                'response' => response()->json([
                    'status' => "0",
                    'message' => 'Authentication failed',
                    'error' => ['exception' => $e->getMessage()]
                ], 500)
            ];
        }
    }


    // 1. Service Detail (t)
    public function detail(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'slug' => 'nullable|string',
            'service_id' => 'required|integer|exists:services,id'
        ]);

        if ($validator->fails()) {
            return $this->error('Validation failed', $validator->errors());
        }

        try {
            // $service = Service::findOrFail($request->service_id)->load([
            //     'serviceOptions',
            //     'priceMatrix',
            //     'bookings' => function ($q) {
            //         $q->where('is_reviewed', 1)->where('review_status', '!=', 0)
            //           ->with('user')->orderByDesc('id');
            //     }
            // ]);
            $service = Service::with([
                'serviceOptions',
                'priceMatrix',
                'bookings' => function ($q) {
                    $q->where('is_reviewed', 1)
                        ->where('review_status', '!=', 0)
                        ->with('user')
                        ->orderBy('id', 'desc');
                }
            ])->findOrFail($request->service_id);

            // if ($service->slug !== $request->slug) {
            //     return $this->error('Invalid service slug'.$request->slug);
            // }
            // dd($service);
            $matrices = ServicePriceMatrix::where('service_id', $service->id)
                ->where('is_active', 1)
                ->orderBy('maid_count')
                ->orderBy('hour_count')
                ->get();


            $basePrice = "0.00";

            if ($matrices->isNotEmpty()) {
                // First priority → from price matrix
                $firstMatrix = $matrices->first();
                $basePrice = isset($firstMatrix->base_price)
                    ? (string) number_format($firstMatrix->base_price, 2)
                    : "0.00";
            } elseif ($service->serviceOptions->isNotEmpty()) {
                // Second priority → from service options
                $firstOption = $service->serviceOptions->first();
                $basePrice = isset($firstOption->price)
                    ? (string) number_format($firstOption->price, 2)
                    : "0.00";
            }

            return $this->success('Service details fetched', [
                'service' => [
                    'id' => (string) $service->id,
                    'name' => $service->name,
                    'type' => $service->service_types,
                    'rating' => $service->rating,
                    'rating_count' => $service->rating_count,
                    'description' => $service->description ?? '',
                    'video_url' => $service->video ? $service->video_url : '',
                    'video_thumbnail' => $service->video ? $service->video_thumbnail : '',
                    'short_description' => $service->short_description ?? '',
                    'cover_image' => $service->cover_image_url,
                    'thumb_image' => $service->thumb_image_url,
                    'icon' => $service->icon_url,
                    'surcharge' => (string) ($service->surcharge ?? 0),
                    'base_price' => $basePrice,
                    'ratings' => $service->bookings
                ],
                'price_matrices' => $matrices->map(fn($m) => [
                    'maid_count' => (string) $m->maid_count,
                    'hour_count' => (string) $m->hour_count,
                    'with_materials' => $m->with_materials ? "1" : "0",
                    'base_price' => (string) number_format($m->base_price, 2),
                    'material_surcharge' => (string) number_format($m->material_surcharge, 2),
                    'total_price' => (string) number_format($m->total_price, 2),
                    'combination_text' => $m->combination_text,
                    'is_default' => $m->is_default_combo ? "1" : "0"
                ])->values()
            ]);
        } catch (\Exception $e) {
            return $this->error('Failed to fetch service', $e->getMessage());
        }
    }

    public function book_service_page(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|integer|exists:services,id',
            'edit_cart' => 'nullable|integer|exists:carts,id'
        ]);

        if ($validator->fails()) {
            return $this->error('Validation failed', $validator->errors());
        }

        $service = Service::find($request->service_id);
        if (!$service) {
            return $this->error('Service not found', [], 404);
        }

        // Service Options (with children)
        $service_options = ServiceOption::with([
            'children' => function ($q) {
                $q->where('status', 1)->orderBy('sort_order', 'asc');
            }
        ])
            ->where('service_id', $service->id)
            ->where('status', 1)
            ->where('parent_id', 0)
            ->orderBy('sort_order', 'asc')
            ->get()
            ->map(function ($parent) {

                return [
                    'id' => $parent->id,
                    'title' => $parent->option_title,
                    'price' => (string) ($parent->price),
                    'option_value' => $parent->option_value,
                    'image_url' => $parent->image_url ?? null,
                    'children' => $parent->children->map(function ($child) {
                        return [
                            'id' => $child->id,
                            'title' => $child->option_title,
                            'price' => (string) ($child->price),
                            'option_value' => $child->option_value,
                            // 'image_url' => $child->image_url ? asset('storage/' . $child->image_url) : null,
                        ];
                    })->toArray()
                ];
            });

        // Packages
        $packages = Package::where('service_id', $service->id)
            ->where('status', 1)
            ->orderBy('sort_order', 'asc')
            ->get()
            ->map(function ($p) {
                return [
                    'id' => (string) $p->id,
                    'name' => $p->name,
                    'sessions' => (string) $p->total_sessions,
                    'free_sessions' => (string) ($p->free_session ?? 0),
                    'price' => (string) ($p->price),
                    'save_amount' => (string) ($p->save_amount ?? 0),
                    'per_session' => (string) ($p->per_session_price),
                    'is_popular' => $p->is_popular ? "1" : "0",
                    'description' => $p->package_description
                ];
            });

        // Default Price Matrix
        $default_matrix = ServicePriceMatrix::where('service_id', $service->id)
            ->where('is_active', 1)
            ->orderBy('sort_order', 'asc')
            ->first();

        $default_combo = $default_combo = ServicePriceMatrix::where('service_id', $service->id)->where('is_default_combo', 1)->first();
        if ($default_combo) {
            $default_combo = [
                'id' => $default_combo->id,
                'maid_count' => $default_combo->maid_count,
                'hour_count' => $default_combo->hour_count,
                'with_materials' => $default_combo->with_materials,
                'base_price' => (string) ($default_combo->base_price),
                'material_surcharge' => (string) ($default_combo->material_surcharge),
                'total_price' => (string) ($default_combo->total_price),
            ];
        }

        // Edit Cart Data (if provided)
        $edit_cart = null;
        if ($request->edit_cart) {
            $auth = $this->validateAccessToken($request);

            if (!$auth['success']) {
                return $auth['response']; // Return error response
            }

            $user = $auth['user']; // Get authenticated user

            $cart = Cart::with([
                'sessions',
                'options.serviceOption',
                'priceMatrix',
                'package',
                'address'
            ])
                ->where('id', $request->edit_cart)
                ->where('user_id', $user->id)
                ->first();

            if ($cart) {
                $edit_cart = [
                    'cart_id' => $cart->id,
                    'address_id' => $cart->address_id,
                    'alternate_mobile' => $cart->alternate_mobile_number,
                    'important_info' => $cart->important_information,
                    'file' => $cart->file,
                    'price_matrix_id' => $cart->price_matrix_id,
                    'package_id' => $cart->package_id,
                    'sessions' => $cart->sessions->map(function ($s) {
                        return [
                            'date' => $s->service_date,
                            'time_slot' => $s->slot_from . '-' . $s->slot_to
                        ];
                    })->toArray(),
                    'selected_options' => $cart->options->pluck('quantity', 'service_option_id')->toArray()
                ];
            }
        }

        $basePrice = "0.00";
        $matrices = $service->load('priceMatrix')->priceMatrix->where('is_active', 1);
        // dd($matrices);
        if ($matrices->isNotEmpty()) {
            // First priority → from price matrix
            $firstMatrix = $matrices->first();
            $basePrice = isset($firstMatrix->base_price)
                ? (string) number_format($firstMatrix->base_price, 2)
                : "0.00";
        } elseif ($service->serviceOptions->isNotEmpty()) {
            // Second priority → from service options
            $firstOption = $service->serviceOptions->first();
            $basePrice = isset($firstOption->price)
                ? (string) number_format($firstOption->price, 2)
                : "0.00";
        }
        return $this->success('Book service page loaded', [
            'service' => [
                'id' => (string) $service->id,
                'name' => $service->name,
                'slug' => $service->slug,
                'short_description' => $service->short_description,
                'description' => $service->description,
                'cover_image' => $service->cover_image_url,
                'thumb_image' => $service->thumb_image_url,
                'icon' => $service->icon_url,
                'service_type' => $service->service_types,
                'base_price' => $basePrice
            ],
            'service_options' => $service_options,
            'packages' => $packages,
            'default_combo' => $default_combo,
            'edit_cart' => $edit_cart
        ]);
    }

    // 2. Calculate Price
    public function calculate_price(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|integer|exists:services,id',
            'maid_count' => 'required|integer|min:1|max:10',
            'hour_count' => 'required|integer|min:1|max:24',
            'with_materials' => 'required|in:0,1',
            'package_id' => 'nullable|exists:packages,id'
        ]);

        if ($validator->fails())
            return $this->error('Validation failed', $validator->errors());

        $matrix = ServicePriceMatrix::where([
            'service_id' => $request->service_id,
            'maid_count' => $request->maid_count,
            'hour_count' => $request->hour_count,
            'with_materials' => $request->with_materials,
            'is_active' => 1
        ])->first();

        if (!$matrix)
            return $this->error('Price not available for this combination');

        $price = $matrix->total_price;
        if ($request->package_id) {
            $package = Package::find($request->package_id);
            $price = $package->price / $package->sessions; // per session
        }

        return $this->success('Price calculated', [
            'base_price' => (string) number_format($matrix->base_price, 2),
            'material_price' => (string) number_format($matrix->material_surcharge, 2),
            'subtotal' => (string) number_format($price, 2),
            'surcharge' => "0.00",
            'final_total' => (string) number_format($price, 2)
        ]);
    }

    // 3. Get Packages
    public function packages(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|integer|exists:services,id'
        ]);

        if ($validator->fails())
            return $this->error('Validation failed', $validator->errors());

        $packages = Package::where('service_id', $request->service_id)
            ->where('status', 1)
            ->orderBy('sort_order')
            ->get();

        return $this->success('Packages fetched', [
            'packages' => $packages->map(fn($p) => [
                'id' => (string) $p->id,
                'name' => $p->name,
                'sessions' => (string) $p->sessions,
                'free_sessions' => (string) ($p->free_sessions ?? 0),
                'price' => (string) number_format($p->price, 2),
                'save_amount' => (string) number_format($p->save_amount ?? 0, 2),
                'per_session' => (string) number_format($p->price / $p->sessions, 2),
                'is_popular' => $p->is_popular ? "1" : "0"
            ])->values()
        ]);
    }

    // 4. Get Slots (Single)
    // public function get_slots(Request $request)
    // {
    //     $validator = Validator::make($request->all(), [
    //         'date' => 'required|date|after_or_equal:today',
    //         'hour_count' => 'required|integer'
    //     ]);

    //     if ($validator->fails()) return $this->error('Validation failed', $validator->errors());

    //     $date = Carbon::parse($request->date);
    //     $start = $date->copy()->setTime(8, 0);
    //     $end = $date->copy()->setTime(20, 0);
    //     $slots = [];

    //     while ($start->copy()->addHours($request->hour_count)->lte($end)) {
    //         $endTime = $start->copy()->addHours($request->hour_count);
    //         if ($endTime->gt($end)) break;

    //         $slots[] = [
    //             'start_time' => $start->format('H:i'),
    //             'end_time' => $endTime->format('H:i'),
    //             'label' => $start->format('g:i A') . ' - ' . $endTime->format('g:i A'),
    //             'available' => "1"
    //         ];
    //         $start->addHours(1);
    //     }

    //     return $this->success('Slots available', [
    //         'date' => $date->format('Y-m-d'),
    //         'slots' => $slots
    //     ]);
    // }

    // 5. Get Package Slots
    public function get_package_slots(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'package_id' => 'required|exists:packages,id',
            'start_date' => 'required|date|after_or_equal:today',
            'preferred_days' => 'required|array|min:1|max:7',
            'preferred_days.*' => 'in:Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday',
            'same_time' => 'required|in:0,1',
            'start_time' => 'required_if:same_time,1|date_format:H:i'
        ]);

        if ($validator->fails())
            return $this->error('Validation failed', $validator->errors());

        $package = Package::findOrFail($request->package_id);
        $dates = [];
        $start = Carbon::parse($request->start_date);
        $days = $request->preferred_days;

        for ($i = 0; $i < $package->sessions; $i++) {
            $sessionDate = $start->copy()->next($days[$i % count($days)]);
            $dates[] = [
                'session' => (string) ($i + 1),
                'date' => $sessionDate->format('Y-m-d'),
                'day' => $sessionDate->format('l'),
                'display_date' => $sessionDate->format('d M, Y'),
                'start_time' => $request->same_time ? $request->start_time : '09:00',
                'end_time' => $request->same_time ? Carbon::parse($request->start_time)->addHours(2)->format('H:i') : '11:00'
            ];
        }

        return $this->success('Package slots generated', [
            'package_id' => (string) $package->id,
            'total_sessions' => (string) $package->sessions,
            'dates' => $dates
        ]);
    }

    // 6. Apply Coupon
    public function apply_coupon(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'coupon_code' => 'required|string',
            'total_amount' => 'required|numeric'
        ]);

        if ($validator->fails())
            return $this->error('Validation failed', $validator->errors());

        $coupon = Coupon::where('code', $request->coupon_code)
            ->where('status', 1)
            ->whereDate('valid_from', '<=', now())
            ->whereDate('valid_to', '>=', now())
            ->first();

        if (!$coupon)
            return $this->error('Invalid or expired coupon');

        $discount = $coupon->discount_type === 'percentage'
            ? $request->total_amount * ($coupon->discount_value / 100)
            : $coupon->discount_value;

        $discount = min($discount, $request->total_amount);
        $final = $request->total_amount - $discount;

        return $this->success('Coupon applied', [
            'discount' => (string) number_format($discount, 2),
            'final_amount' => (string) number_format($final, 2)
        ]);
    }

    // 7. Checkout Review
    public function checkout_review(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|integer',
            'maid_count' => 'required|integer',
            'hour_count' => 'required|integer',
            'with_materials' => 'required|in:0,1',
            'address_id' => 'required|exists:user_addresses,id',
            'contact_name' => 'required|string',
            'contact_phone' => 'required|string',
            'notes' => 'nullable|string',
            'tip' => 'nullable|numeric',
            'coupon_code' => 'nullable|string',
            'payment_method' => 'required|in:card,wallet,cash,apple_pay',
            'booking_type' => 'required|in:single,package',
            'package_id' => 'required_if:booking_type,package',
            'selected_date' => 'required_if:booking_type,single|date',
            'selected_slot' => 'required_if:booking_type,single|string',
            'package_slots' => 'required_if:booking_type,package|array'
        ]);

        if ($validator->fails())
            return $this->error('Validation failed', $validator->errors());

        $priceRes = $this->calculate_price($request);
        if ($priceRes->getData()->status === "0")
            return $priceRes;

        $subtotal = (float) $priceRes->getData()->data->final_total;
        $discount = 0;
        if ($request->coupon_code) {
            $couponRes = $this->apply_coupon($request->merge(['total_amount' => $subtotal]));
            if ($couponRes->getData()->status === "1") {
                $discount = (float) $couponRes->getData()->data->discount;
            }
        }

        $tip = $request->tip ?? 0;
        $total = $subtotal - $discount + $tip;

        return $this->success('Checkout ready', [
            'summary' => [
                'service_name' => Service::find($request->service_id)->name,
                'maid_count' => (string) $request->maid_count,
                'hour_count' => (string) $request->hour_count,
                'with_materials' => $request->with_materials ? 'Yes' : 'No',
                'address' => UserAddress::find($request->address_id)->address,
                'contact' => "$request->contact_name ($request->contact_phone)",
                'notes' => $request->notes ?? '',
                'subtotal' => (string) number_format($subtotal, 2),
                'discount' => (string) number_format($discount, 2),
                'tip' => (string) number_format($tip, 2),
                'total' => (string) number_format($total, 2),
                'payment_method' => $request->payment_method,
                'booking_type' => $request->booking_type
            ]
        ]);
    }

    // 8. Place Order (NEW)
    public function place_order(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|integer',
            'maid_count' => 'required|integer',
            'hour_count' => 'required|integer',
            'with_materials' => 'required|in:0,1',
            'address_id' => 'required|exists:user_addresses,id',
            'contact_name' => 'required|string',
            'contact_phone' => 'required|string',
            'notes' => 'nullable|string',
            'tip' => 'nullable|numeric',
            'coupon_code' => 'nullable|string',
            'payment_method' => 'required|in:card,wallet,cash,apple_pay',
            'booking_type' => 'required|in:single,package',
            'package_id' => 'required_if:booking_type,package',
            'selected_date' => 'required_if:booking_type,single|date',
            'selected_slot' => 'required_if:booking_type,single|string',
            'package_slots' => 'required_if:booking_type,package|array'
        ]);

        if ($validator->fails())
            return $this->error('Validation failed', $validator->errors());

        DB::beginTransaction();
        try {
            $review = $this->checkout_review($request);
            if ($review->getData()->status === "0")
                return $review;

            $total = (float) $review->getData()->data->summary->total;

            $booking = Booking::create([
                'user_id' => Auth::id(),
                'service_id' => $request->service_id,
                'address_id' => $request->address_id,
                'maid_count' => $request->maid_count,
                'hour_count' => $request->hour_count,
                'with_materials' => $request->with_materials,
                'contact_name' => $request->contact_name,
                'contact_phone' => $request->contact_phone,
                'notes' => $request->notes,
                'tip' => $request->tip ?? 0,
                'coupon_code' => $request->coupon_code,
                'payment_method' => $request->payment_method,
                'total_price' => $total,
                'booking_status' => $request->payment_method === 'cash' ? 1 : 2, // 1=confirmed, 2=pending
                'booking_type' => $request->booking_type,
                'package_id' => $request->package_id
            ]);

            if ($request->booking_type === 'single') {
                BookingSession::create([
                    'booking_id' => $booking->id,
                    'session_date' => $request->selected_date,
                    'start_time' => explode('-', $request->selected_slot)[0],
                    'end_time' => explode('-', $request->selected_slot)[1] ?? null
                ]);
            } else {
                foreach ($request->package_slots as $slot) {
                    BookingSession::create([
                        'booking_id' => $booking->id,
                        'session_date' => $slot['date'],
                        'start_time' => $slot['start_time'],
                        'end_time' => $slot['end_time']
                    ]);
                }
            }

            DB::commit();

\Log::info('✅ OneSignal REAL response', [
    'status' => $response->status(),
    'body' => $response->body(),
]);
        
            return $this->success('Booking placed successfully', [
                'booking_id' => (string) $booking->id,
                'total' => (string) number_format($total, 2),
                'payment_status' => $request->payment_method === 'cash' ? 'confirmed' : 'pending'
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error('Booking failed', $e->getMessage());
        }
    }

    // 9. Booking Success
    public function booking_success(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'booking_id' => 'required|integer'
        ]);

        if ($validator->fails())
            return $this->error('Invalid booking ID');

        $booking = Booking::with(['service', 'address', 'sessions'])
            ->where('id', $request->booking_id)
            ->where('user_id', Auth::id())
            ->firstOrFail();

        return $this->success('Booking confirmed', [
            'booking_id' => (string) $booking->id,
            'service_name' => $booking->service->name,
            'total' => (string) number_format($booking->total_price, 2),
            'date' => $booking->sessions->first()->session_date ?? '',
            'time' => $booking->sessions->first()->start_time . ' - ' . $booking->sessions->first()->end_time,
            'address' => $booking->address->address,
            'status' => $booking->booking_status == 1 ? 'Confirmed' : 'Pending'
        ]);
    }

    // Helper Methods
    private function success($message, $data = [])
    {
        return response()->json([
            'status' => "1",
            'message' => $message,
            'data' => (object) $data
        ], 200);
    }

    private function error($message, $errors = null)
    {
        return response()->json([
            'status' => "0",
            'message' => $message,
            'error' => $errors ? (object) $errors : (object) []
        ], 200);
    }

    // 3. INIT TEMP BOOKING (Step 3)
    public function init_temp_booking(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|integer|exists:services,id',
            'maid_count' => 'nullable|integer|min:1',
            'hour_count' => 'nullable|integer|min:1',
            'with_materials' => 'nullable|in:0,1',
            'address_id' => 'required|integer|exists:user_addresses,id',
            'alternate_mobile_number' => 'nullable|string|max:20',
            'important_information' => 'nullable|string',
            'sessions' => 'required|array|min:1',
            'sessions.*.date' => 'required|date|after_or_equal:today',
            'sessions.*.time_slot' => 'required|string',
            'selected_options' => 'nullable|array',
            'selected_options.*' => 'integer|min:1',
            'package_id' => 'nullable|integer|exists:packages,id',
            'tip_amount' => 'nullable|numeric|min:0',
            'coupon_code' => 'nullable|string',
            'payment_method' => 'required|in:card,wallet,cash,apple_pay'
        ]);

        if ($validator->fails()) {
            return $this->error('Validation failed', $validator->errors());
        }

        $user = Auth::user();
        $cartGroupId = 'TMP_' . strtoupper(Str::random(10));

        DB::beginTransaction();
        try {
            // === 1. FETCH SERVICE ===
            $service = Service::find($request->service_id);
            if (!$service) {
                throw new \Exception('Service not found');
            }

            // === 2. AUTO FIND PRICE MATRIX ===
            $matrix = ServicePriceMatrix::where([
                'service_id' => $service->id,
                'maid_count' => $request->maid_count,
                'hour_count' => $request->hour_count,
                'with_materials' => $request->with_materials
            ])->first();

            if (!$matrix || !$matrix->id) {
                Log::error('Price matrix not found', [
                    'service_id' => $service->id,
                    'maid_count' => $request->maid_count,
                    'hour_count' => $request->hour_count,
                    'with_materials' => $request->with_materials
                ]);
                throw new \Exception('No price found for this combination');
            }

            // === 3. PACKAGE ===
            $package = $request->package_id ? Package::find($request->package_id) : null;

            // === 4. CALCULATE BASE + OPTIONS ===
            $basePrice = $matrix->total_price;
            $optionTotal = 0;

            if ($request->filled('selected_options')) {
                foreach ($request->selected_options as $optionId => $quantity) {
                    $option = ServiceOption::find($optionId);
                    if ($option) {
                        $optionTotal += $option->price * $quantity;
                    }
                }
            }

            $perSessionPrice = $basePrice + $optionTotal;

            // === 5. PACKAGE PRICING (if selected) ===
            if ($package) {
                $totalSessions = count($request->sessions);
                if ($package->total_sessions != $totalSessions) {
                    throw new \Exception("Package requires {$package->total_sessions} sessions");
                }
                $perSessionPrice = $package->price / $package->total_sessions;
            }

            $subtotal = $perSessionPrice * count($request->sessions);

            // === 6. COUPON ===
            $discount = 0;
            $coupon = null;
            if ($request->coupon_code) {
                $coupon = \App\Models\Coupon::where('code', $request->coupon_code)
                    ->where('status', 1)
                    ->whereDate('valid_from', '<=', now())
                    ->whereDate('valid_to', '>=', now())
                    ->first();

                if ($coupon) {
                    $discount = $coupon->discount_type === 'percentage'
                        ? $subtotal * ($coupon->discount_value / 100)
                        : min($coupon->discount_value, $subtotal);
                }
            }

            $grandTotal = $subtotal - $discount + ($request->tip_amount ?? 0);

            // === 7. CREATE TEMP ORDER ===
            $tempOrder = TempOrder::create([
                'order_number' => 'ORD-' . strtoupper(uniqid()),
                'cart_group_id' => $cartGroupId,
                'user_id' => $user->id,
                'subtotal' => $subtotal,
                'tax_amount' => 0,
                'surcharge' => 0,
                'tip_amount' => $request->tip_amount ?? 0,
                'discount_amount' => $discount,
                'grand_total' => $grandTotal,
                'coupon_id' => $coupon?->id,
                'coupon_code' => $request->coupon_code,
                'payment_method' => $request->payment_method,
                'payment_status' => 'pending',
                'is_completed' => false
            ]);

            if (!$tempOrder?->id) {
                throw new \Exception('Failed to create temp order');
            }

            $file_name = "";
            if ($request->hasFile('file')) {
                $file = $request->file('file');
                $file_name = time() . uniqid() . "." . $file->getClientOriginalExtension();
                $file->storeAs(config('global.order_files'), $file_name, config('global.upload_bucket'));
            }
            // === 8. CREATE TEMP BOOKING ===
            $tempBooking = TempBooking::create([
                'temp_order_id' => $tempOrder->id,
                'booking_number' => 'TMP-' . strtoupper(uniqid()),
                'cart_group_id' => $cartGroupId,
                'user_id' => $user->id,
                'service_id' => $service->id,
                'package_id' => $package?->id,
                'price_matrix_id' => $matrix->id,
                'service_type' => $service->service_types,
                'address_id' => $request->address_id,
                'alternate_mobile_number' => $request->alternate_mobile_number,
                'important_information' => $request->important_information,
                'file' => $file_name,
                'subtotal' => $subtotal,
                'tax_amount' => 0,
                'surcharge' => 0,
                'tip_amount' => $request->tip_amount ?? 0,
                'grand_total' => $grandTotal,
                'discount_amount' => $discount,
                'commission_amount' => 0,
                'coupon_id' => $coupon?->id,
                'coupon_code' => $request->coupon_code,
                'payment_method' => $request->payment_method,
                'booking_status' => 0,
                'is_completed' => 0
            ]);

            if (!$tempBooking?->id) {
                throw new \Exception('Failed to create temp booking');
            }

            // === 9. SESSIONS ===
            foreach ($request->sessions as $session) {
                $time = explode('-', $session['time_slot']);
                TempBookingSession::create([
                    'temp_booking_id' => $tempBooking->id,
                    'service_date' => $session['date'],
                    'slot_from' => $time[0] ?? null,
                    'slot_to' => $time[1] ?? null
                ]);
            }

            // === 10. OPTIONS ===
            if ($request->filled('selected_options')) {
                foreach ($request->selected_options as $optionId => $quantity) {
                    $option = ServiceOption::find($optionId);
                    if ($option) {
                        TempBookingServiceOption::create([
                            'temp_booking_id' => $tempBooking->id,
                            'service_option_id' => $optionId,
                            'quantity' => $quantity,
                            'unit_price' => $option->price,
                            'total_price' => $option->price * $quantity
                        ]);
                    }
                }
            }

            DB::commit();

            return $this->success('Temp booking created', [
                'cart_group_id' => $cartGroupId,
                'temp_booking_id' => (string) $tempBooking->id,
                'subtotal' => number_format($subtotal, 2),
                'discount' => number_format($discount, 2),
                'grand_total' => number_format($grandTotal, 2),
                'payment_method' => $request->payment_method
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Init Temp Booking Failed: ' . $e->getMessage(), $request->all());
            return $this->error('Failed to create temp booking', $e->getMessage());
        }
    }

    // 4. COMPLETE BOOKING (Payment Success)
    public function complete_booking(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'cart_group_id' => 'required|string',
            'payment_response' => 'nullable|array',
            'payment_status' => 'required|in:success,failed'
        ]);

        if ($validator->fails()) {
            return $this->error('Validation failed', $validator->errors());
        }

        $tempOrder = TempOrder::where('cart_group_id', $request->cart_group_id)
            ->where('user_id', Auth::id())
            ->first();

        if (!$tempOrder) {
            return $this->error('Temp order not found');
        }

        if ($tempOrder->is_completed) {
            return $this->error('Booking already completed');
        }

        DB::beginTransaction();
        try {
            if ($request->payment_status === 'failed') {
                $tempOrder->update([
                    'payment_status' => 'failed',
                    'payment_response' => json_encode($request->payment_response)
                ]);
                DB::commit();
                return $this->error('Payment failed');
            }

            // Update TempOrder
            $tempOrder->update([
                'payment_status' => 'completed',
                'payment_response' => $request->payment_response ? json_encode($request->payment_response) : null,
                'is_completed' => true
            ]);

            // Get all temp bookings
            $tempBookings = TempBooking::where('cart_group_id', $request->cart_group_id)->get();

            foreach ($tempBookings as $tempBooking) {
                // Create real Booking
                $booking = Booking::create([
                    'booking_number' => 'BKG-' . strtoupper(uniqid()),
                    'user_id' => $tempBooking->user_id,
                    'service_id' => $tempBooking->service_id,
                    'package_id' => $tempBooking->package_id,
                    'price_matrix_id' => $tempBooking->price_matrix_id,
                    'service_type' => $tempBooking->service_type,
                    'address_id' => $tempBooking->address_id,
                    'alternate_mobile_number' => $tempBooking->alternate_mobile_number,
                    'important_information' => $tempBooking->important_information,
                    'file' => $tempBooking->file,
                    'subtotal' => $tempBooking->subtotal,
                    'tax_amount' => $tempBooking->tax_amount,
                    'surcharge' => $tempBooking->surcharge,
                    'tip_amount' => $tempBooking->tip_amount,
                    'grand_total' => $tempBooking->grand_total,
                    'discount_amount' => $tempBooking->discount_amount,
                    'commission_amount' => $tempBooking->commission_amount,
                    'coupon_id' => $tempBooking->coupon_id,
                    'coupon_code' => $tempBooking->coupon_code,
                    'payment_method' => $tempBooking->payment_method,
                    'payment_response' => $tempBooking->payment_response,
                    'booking_status' => $tempBooking->payment_method === 'cash' ? 1 : 1, // Confirmed
                    'cart_group_id' => $tempBooking->cart_group_id,
                    'created_at' => now(),
                    'updated_at' => now()
                ]);

                // Copy sessions
                foreach ($tempBooking->sessions as $session) {
                    BookingSession::create([
                        'booking_id' => $booking->id,
                        'service_date' => $session->service_date,
                        'slot_from' => $session->slot_from,
                        'slot_to' => $session->slot_to
                    ]);
                }

                // Copy service options
                foreach ($tempBooking->serviceOptions as $option) {
                    BookingServiceOption::create([
                        'booking_id' => $booking->id,
                        'service_option_id' => $option->service_option_id,
                        'quantity' => $option->quantity,
                        'unit_price' => $option->unit_price,
                        'total_price' => $option->total_price
                    ]);
                }
            }

            DB::commit();

            return $this->success('Booking completed successfully', [
                'cart_group_id' => $request->cart_group_id,
                'booking_count' => $tempBookings->count()
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->error('Failed to complete booking', $e->getMessage());
        }
    }

    // ----------------------

    public function get_packages_with_selection(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|exists:services,id',
            'maid_count' => 'required|integer|min:1',
            'hour_count' => 'required|integer|min:1',
            'with_materials' => 'required'
        ]);
        if ($validator->fails()) {
            $errors = $validator->errors()->toArray();
            $message = "Please check the form below for errors.";
        } else {
            $service_id = $request->service_id;
            $maid_count = $request->maid_count;
            $hour_count = $request->hour_count;
            $with_materials = $request->with_materials;

            //get packages
            $packages = Package::where('service_id', $service_id)->where('status', 1)->orderBy('sort_order', 'asc')->get();



            //get selected combo price matrix
            $selected_combo = ServicePriceMatrix::where('service_id', $service_id)
                ->where('maid_count', $maid_count)
                ->where('hour_count', $hour_count)
                ->where('with_materials', $with_materials)
                ->where('is_active', 1)
                ->first();
            if ($selected_combo) {
                $o_data['selected_combo'] = [
                    'id' => $selected_combo->id,
                    'maid_count' => $selected_combo->maid_count,
                    'hour_count' => $selected_combo->hour_count,
                    'with_materials' => $selected_combo->with_materials,
                    'base_price' => $selected_combo->base_price,
                    'material_surcharge' => $selected_combo->material_surcharge,
                    'total_price' => $selected_combo->total_price,
                ];
                foreach ($packages as $p_index => $package) {
                    $free_sessions = $package->free_session;
                    $total_sessions = $package->total_sessions;
                    $full_sessions = $total_sessions - $free_sessions;
                    $ovall_price = $full_sessions * $selected_combo->total_price;
                    $this_package_price = $total_sessions * $selected_combo->total_price;
                    $free_price = $free_sessions * $selected_combo->total_price;
                    $packages[$p_index]->overall_price = $ovall_price;
                    $packages[$p_index]->this_package_price = $this_package_price;
                    $packages[$p_index]->free_price = $free_price;
                }
                $o_data['packages'] = $packages;
                $status = "1";
                $message = "Packages and pricing loaded.";
            } else {
                $status = "0";
                $message = "This combination of service is not providing now.";
                return response()->json([
                    'status' => $status,
                    'message' => $message,
                    'data' => (object) $o_data,
                    'errors' => (object) $errors
                ]);
            }
        }
        return response()->json([
            'status' => $status,
            'message' => $message,
            'data' => (object) $o_data,
            'errors' => (object) $errors
        ]);
    }

    public function generate_summary(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|exists:services,id',
            'maid_count' => 'required|integer|min:1',
            'hour_count' => 'required|integer|min:1',
            'with_materials' => 'required'
        ]);
        if ($validator->fails()) {
            $errors = $validator->errors()->toArray();
            $message = "Please check the form below for errors.";
        } else {
            $service_id = $request->service_id;
            $maid_count = $request->maid_count;
            $hour_count = $request->hour_count;
            $with_materials = $request->with_materials;
            $package_id = $request->package_id;

            //get selected combo price matrix
            $selected_combo = ServicePriceMatrix::where('service_id', $service_id)
                ->where('maid_count', $maid_count)
                ->where('hour_count', $hour_count)
                ->where('with_materials', $with_materials)
                ->where('is_active', 1)
                ->first();
            if ($selected_combo) {
                $o_data['selected_combo'] = [
                    'id' => $selected_combo->id,
                    'maid_count' => $selected_combo->maid_count,
                    'hour_count' => $selected_combo->hour_count,
                    'with_materials' => $selected_combo->with_materials,
                    'base_price' => $selected_combo->base_price,
                    'material_surcharge' => $selected_combo->material_surcharge,
                    'total_price' => $selected_combo->total_price,
                ];
                //get package details if any
                if ($package_id) {
                    $package = Package::where('id', $package_id)->where('service_id', $service_id)->where('status', 1)->first();
                    if (!$package) {
                        $package = Package::where('service_id', $service_id)->where('status', 1)->orderBy('sort_order', 'asc')->first();
                    }
                } else {
                    $package = Package::where('service_id', $service_id)->where('status', 1)->orderBy('sort_order', 'asc')->first();
                }
                $o_data['package'] = $package;
                if ($package) {
                    $free_sessions = $package->free_session;
                    $total_sessions = $package->total_sessions;
                    $full_sessions = $total_sessions - $free_sessions;
                    $base_price = $selected_combo->base_price * $total_sessions;
                    $material_surcharge = $selected_combo->with_materials ? $selected_combo->material_surcharge * $total_sessions : 0;
                    $ovall_price = $full_sessions * $selected_combo->total_price;
                    $this_package_price = $total_sessions * $selected_combo->total_price;
                    $free_price = $free_sessions * $selected_combo->total_price;
                    $package->overall_price = $ovall_price;
                    $package->this_package_price = $this_package_price;
                    $package->free_price = $free_price;
                }
                $status = "1";
                $message = "Summary generated.";
                $o_data['summary'] = [
                    'service_id' => $service_id,
                    'maid_count' => $maid_count,
                    'hour_count' => $hour_count,
                    'with_materials' => $with_materials,
                    'package_id' => $package ? $package->id : null,
                    'price_matrix_id' => $selected_combo->id,
                    'total_price' => $package ? $package->overall_price : 0,
                    'package_price' => $package ? $package->this_package_price : 0,
                    'free_price' => $package ? $package->free_price : 0,
                    'base_price' => $base_price,
                    'material_surcharge' => $material_surcharge,
                ];
            }
        }
        return response()->json([
            'status' => $status,
            'message' => $message,
            'data' => (object) $o_data,
            'errors' => (object) $errors
        ]);
    }

    public function get_slots(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'date' => 'nullable',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'status' => '0',
                'message' => 'Invalid date format. Please use Y-m-d.',
                'errors' => $validator->errors()
            ], 422);
        }

        $settings = Setting::first();
        if (!$settings || !$settings->operating_from || !$settings->operating_to) {
            return response()->json([
                'status' => '0',
                'message' => 'Operating hours are not configured.',
                'data' => []
            ]);
        }

        $timezone = 'Asia/Dubai';
        $dateInput = $request->input('date', Carbon::now($timezone)->format('Y-m-d'));

        // Try to parse the date - handle both Y-m-d and ISO formats
        try {
            if (strpos($dateInput, 'T') !== false) {
                // ISO format (e.g., 2025-10-25T00:00:00.000000Z)
                $requestedDate = Carbon::parse($dateInput, $timezone)->startOfDay();
            } else {
                // Y-m-d format
                $requestedDate = Carbon::createFromFormat('Y-m-d', $dateInput, $timezone)->startOfDay();
            }
        } catch (\Exception $e) {
            // Fallback: try general parse
            $requestedDate = Carbon::parse($dateInput, $timezone)->startOfDay();
        }
        $nowInDubai = Carbon::now($timezone);

        $isToday = $requestedDate->isToday();

        $slots = [];

        // Parse time from database - handle both H:i and H:i:s formats
        try {
            // Try to parse as Carbon time object first
            $operatingFromTime = Carbon::parse($settings->operating_from, $timezone);
            $operatingToTime = Carbon::parse($settings->operating_to, $timezone);

            $operatingFrom = $operatingFromTime->format('H:i');
            $operatingTo = $operatingToTime->format('H:i');
        } catch (\Exception $e) {
            // Fallback: extract just the time portion if it's a full datetime
            $operatingFrom = substr($settings->operating_from, 0, 5);
            $operatingTo = substr($settings->operating_to, 0, 5);
        }

        // Combine date and time
        $startTime = Carbon::parse($requestedDate->format('Y-m-d') . ' ' . $operatingFrom, $timezone);
        $endTime = Carbon::parse($requestedDate->format('Y-m-d') . ' ' . $operatingTo, $timezone);
        $slotGap = $settings->slot_gap ?? 30;

        $currentTime = $startTime->copy();

        while ($currentTime < $endTime) {
            $slot_from = $currentTime->copy();
            $slot_to = $currentTime->copy()->addMinutes($slotGap);

            if ($slot_to > $endTime) {
                break;
            }

            $is_available = 1;
            if ($isToday && $slot_from->isPast()) {
                $is_available = 0;
            }

            $slots[] = [
                'time_from' => $slot_from->format('H:i'),
                'time_to' => $slot_to->format('H:i'),
                'is_available' => $is_available,
            ];

            $currentTime->addMinutes($slotGap);
        }

        return response()->json([
            'status' => '1',
            'message' => 'Slots retrieved successfully.',
            'data' => $slots
        ]);
    }
    public function get_slots_with_price(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'date' => 'nullable|date',
        ]);

        if ($validator->fails()) {
            return response()->json([
                'status' => '0',
                'message' => 'Invalid date format. Please use Y-m-d.',
                'errors' => $validator->errors()
            ], 422);
        }

        $settings = Setting::first();
        if (!$settings || !$settings->operating_from || !$settings->operating_to) {
            return response()->json([
                'status' => '0',
                'message' => 'Operating hours are not configured.',
                'data' => []
            ]);
        }

        $timezone = 'Asia/Dubai';
        $dateInput = $request->input('date', Carbon::now($timezone)->format('Y-m-d'));

        // Parse the date
        try {
            if (strpos($dateInput, 'T') !== false) {
                $requestedDate = Carbon::parse($dateInput, $timezone)->startOfDay();
            } else {
                $requestedDate = Carbon::createFromFormat('Y-m-d', $dateInput, $timezone)->startOfDay();
            }
        } catch (\Exception $e) {
            $requestedDate = Carbon::parse($dateInput, $timezone)->startOfDay();
        }

        $nowInDubai = Carbon::now($timezone);
        $isToday = $requestedDate->isToday();

        // Get all time slots for the requested date
        $timeSlots = TimeSlot::where('slot_date', $requestedDate->format('Y-m-d'))
            ->where('status', 1)
            ->get()
            ->keyBy(function ($slot) {
                // Format time to H:i to match our comparison format (remove seconds if present)
                return substr($slot->time_from, 0, 5); // Get HH:mm from HH:mm or HH:mm:ss
            });

        $slots = [];

        // Parse operating hours
        try {
            $operatingFromTime = Carbon::parse($settings->operating_from, $timezone);
            $operatingToTime = Carbon::parse($settings->operating_to, $timezone);
            $operatingFrom = $operatingFromTime->format('H:i');
            $operatingTo = $operatingToTime->format('H:i');
        } catch (\Exception $e) {
            $operatingFrom = substr($settings->operating_from, 0, 5);
            $operatingTo = substr($settings->operating_to, 0, 5);
        }

        // Generate slots
        $startTime = Carbon::parse($requestedDate->format('Y-m-d') . ' ' . $operatingFrom, $timezone);
        $endTime = Carbon::parse($requestedDate->format('Y-m-d') . ' ' . $operatingTo, $timezone);
        $slotGap = $settings->slot_gap ?? 30;

        $currentTime = $startTime->copy();

        while ($currentTime < $endTime) {
            $slot_from = $currentTime->copy();
            $slot_to = $currentTime->copy()->addMinutes($slotGap);

            if ($slot_to > $endTime) {
                break;
            }

            $is_available = 1;
            if ($isToday && $slot_from->isPast()) {
                $is_available = 0;
            }

            $timeFromFormatted = $slot_from->format('H:i');

            // Check if this slot has a price in time_slots table
            $price = '0.00';
            if (isset($timeSlots[$timeFromFormatted])) {
                $price = number_format((float) $timeSlots[$timeFromFormatted]->price, 2);
            }

            $slots[] = [
                'time_from' => $timeFromFormatted,
                'time_to' => $slot_to->format('H:i'),
                'is_available' => $is_available,
                'price' => $price
            ];

            $currentTime->addMinutes($slotGap);
        }

        return response()->json([
            'status' => '1',
            'message' => 'Slots retrieved successfully.',
            'data' => $slots
        ]);
    }

    public function get_option_children(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];

        $validator = Validator::make($request->all(), [
            'parent_id' => 'required|exists:service_options,id',
            'service_id' => 'required|exists:services,id'
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors()->toArray();
            $message = "Invalid request parameters.";
            return response()->json([
                'status' => $status,
                'message' => $message,
                'data' => (object) $o_data,
                'errors' => (object) $errors
            ], 422);
        }

        $parent_id = $request->parent_id;
        $service_id = $request->service_id;
        $addons = Service::where('id', $service_id)
            ->with('addons')->first();

        // Get children for this parent
        $children = ServiceOption::where('parent_id', $parent_id)
            ->where('service_id', $service_id)
            ->where('status', 1)
            ->with('addons')
            ->orderBy('sort_order', 'asc')
            ->get();

        if ($children->isEmpty()) {
            $message = "No options available.";
            return response()->json([
                'status' => $status,
                'message' => $message,
                'data' => (object) $o_data,
                'errors' => (object) $errors
            ]);
        }

        // Map children and check if they have sub-children
        $childrenData = $children->map(function ($child) {
            $hasChildren = ServiceOption::where('parent_id', $child->id)
                ->where('status', 1)
                ->with('addons')
                ->exists();

            return [
                'id' => $child->id,
                'option_title' => $child->option_title,
                'option_description' => $child->option_description,
                'option_value' => $child->option_value,
                'price' => $child->price,
                'image_url' => $child->image_url,
                'has_children' => $hasChildren,

            ];
        });

        $o_data['children'] = $childrenData;
        $o_data['addons'] = ($addons) ? $addons->addons : '';
        $status = "1";
        $message = "Options loaded successfully.";

        return response()->json([
            'status' => $status,
            'message' => $message,
            'data' => (object) $o_data,
            'errors' => (object) $errors
        ]);
    }
    public function get_service_addons(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];

        $validator = Validator::make($request->all(), [
            'service_id' => 'required|exists:services,id'
        ]);

        if ($validator->fails()) {
            $errors = $validator->errors()->toArray();
            $message = "Invalid request parameters.";
            return response()->json([
                'status' => $status,
                'message' => $message,
                'data' => (object)$o_data,
                'errors' => (object)$errors
            ], 422);
        }

        $parent_id = $request->parent_id;
        $service_id = $request->service_id;
        $addons = Service::where('id', $request->service_id)
        ->with('addons')->first();

        if ($addons->addons->isEmpty()) {
            $message = "No addons available.";
            return response()->json([
                'status' => $status,
                'message' => $message,
                'data' => (object)$o_data,
                'errors' => (object)$errors
            ]);
        }
        $o_data['addons'] =($addons)? $addons->addons:'';
        $status = "1";
        $message = "Options loaded successfully.";

        return response()->json([
            'status' => $status,
            'message' => $message,
            'data' => (object)$o_data,
            'errors' => (object)$errors
        ]);
    }
    public function load_variable_options(Request $request)
    {
        $status = "0";
        $message = "";
        $o_data = [];
        $errors = [];
        $validator = Validator::make($request->all(), [
            'service_id' => 'required|exists:services,id'
        ]);
        if ($validator->fails()) {
            $errors = $validator->errors()->toArray();
            $message = "Please check the form below for errors.";
        } else {
            $service_id = $request->service_id;
            $parents = ServiceOption::where('service_id', $service_id)->where(function ($q) {
                $q->whereNull('parent_id')->orWhere('parent_id', 0);
            })->orderBy('sort_order', 'asc')->get();

            $data = $parents->map(function ($p) {
                $children = ServiceOption::where('parent_id', $p->id)->orderBy('sort_order', 'asc')->get()->map(function ($c) {
return ['id' => $c->id, 'title' => $c->option_title, 'price' => $c->price, 'option_value' => $c->option_value];
                });
                return ['id' => $p->id, 'title' => $p->option_title, 'children' => $children];
            });
            $o_data['options'] = $data;

            //get default combo
            $default_combo = ServicePriceMatrix::where('service_id', $service_id)->where('is_default_combo', 1)->first();
            if ($default_combo) {
                $o_data['default_combo'] = [
                    'id' => $default_combo->id,
                    'maid_count' => $default_combo->maid_count,
                    'hour_count' => $default_combo->hour_count,
                    'with_materials' => $default_combo->with_materials,
                    'base_price' => $default_combo->base_price,
                    'material_surcharge' => $default_combo->material_surcharge,
                    'total_price' => $default_combo->total_price,
                ];
            } else {
                $o_data['default_combo'] = (object) [];
            }
            $status = "1";
            $message = "Options loaded.";

        }
        return response()->json([
            'status' => $status,
            'message' => $message,
            'data' => (object) $o_data,
            'errors' => (object) $errors
        ]);
    }
    //----------------------------------
    public function add_to_cart(Request $request)
    {
        // Validate token and get user
        $auth = $this->validateAccessToken($request);

        if (!$auth['success']) {
            return $auth['response']; // Return error response
        }

        $user = $auth['user']; // Get authenticated user

        $validator = Validator::make($request->all(), [
            'cart_id' => 'nullable|integer|exists:carts,id',
            'service_id' => 'required|integer|exists:services,id',
            'package_id' => 'required|integer|exists:packages,id',
            'price_matrix_id' => 'required|integer|exists:service_price_matrices,id',
            'address_id' => 'required|integer|exists:user_addresses,id',
            'alternate_mobile_number' => 'nullable|string|max:20',
            'important_information' => 'nullable|string',
            'sessions' => 'required|array|min:1',
            'sessions.*.date' => 'required|date|after_or_equal:today',
            'sessions.*.time_slot' => 'required|string',
            'selected_options' => 'nullable|array',
            'selected_options.*' => 'integer|min:1'
        ]);

        if ($validator->fails()) {
            return $this->error('Validation failed', $validator->errors());
        }

        DB::beginTransaction();
        try {
            // Get service to fetch service_type
            $service = Service::findOrFail($request->service_id);

            // Check if updating existing cart
            if ($request->filled('cart_id')) {
                $cart = Cart::where('id', $request->cart_id)
                    ->where('user_id', $user->id)
                    ->first();

                if (!$cart) {
                    return $this->error('Cart item not found', null, 404);
                }
                $file_name = "";
                if ($request->hasFile('file')) {
                    $file = $request->file('file');
                    $file_name = time() . uniqid() . "." . $file->getClientOriginalExtension();
                    $file->storeAs(config('global.order_files'), $file_name, config('global.upload_bucket'));
                }

                // Update cart entry
                $cart->update([
                    'service_id' => $request->service_id,
                    'package_id' => $request->package_id,
                    'price_matrix_id' => $request->price_matrix_id,
                    'service_type' => $service->service_types,
                    'address_id' => $request->address_id,
                    'alternate_mobile_number' => $request->alternate_mobile_number,
                    'important_information' => $request->important_information,
                    'file' => $file_name,
                ]);
                if ($file_name) {
                    $cart->update([
                        'file' => $file_name,
                    ]);
                }

                // Delete existing sessions and options
                CartSession::where('cart_id', $cart->id)->delete();
                CartServiceOption::where('cart_id', $cart->id)->delete();
                CartServiceAddon::where('cart_id', $cart->id)->delete();
                $message = "Cart updated successfully";
            } else {
                $file_name = "";
                if ($request->hasFile('file')) {
                    $file = $request->file('file');
                    $file_name = time() . uniqid() . "." . $file->getClientOriginalExtension();
                    $file->storeAs(config('global.order_files'), $file_name, config('global.upload_bucket'));
                }
                // Create new cart entry
                $cart = Cart::create([
                    'user_id' => $user->id,
                    'service_id' => $request->service_id,
                    'package_id' => $request->package_id,
                    'price_matrix_id' => $request->price_matrix_id,
                    'service_type' => $service->service_types,
                    'address_id' => $request->address_id,
                    'alternate_mobile_number' => $request->alternate_mobile_number,
                    'important_information' => $request->important_information,
                    'file' => $file_name,
                ]);

                $message = "Item added to cart successfully";
            }

            // Add sessions
            $slot_price = 0;
            foreach ($request->sessions as $session) {
                // Parse time slot (format: "HH:mm-HH:mm")
                $timeParts = explode('-', $session['time_slot']);
                $date = $session['date'];
                if (strpos($date, '/') !== false) {
                    // dd/mm/yyyy format
                    $dateParts = explode('/', $date);
                    $formattedDate = $dateParts[2] . '-' . $dateParts[1] . '-' . $dateParts[0];
                } else {
                    // Assume Y-m-d format
                    $formattedDate = $date;
                }

                CartSession::create([
                    'cart_id' => $cart->id,
                    'service_date' => Carbon::parse($session['date'])->format('Y-m-d'),
                    'slot_from' => $timeParts[0] ?? null,
                    'slot_to' => $timeParts[1] ?? null,
                ]);
                if ($timeParts[0]) {
                    $timeFrom = substr($timeParts[0], 0, 5);
                    $foundSlot = TimeSlot::where('slot_date', $formattedDate)
                        ->whereRaw("SUBSTRING(CAST(time_from AS TEXT), 1, 5) = ?", [$timeFrom])
                        ->first();
                    if ($foundSlot) {
                        $slot_price += $foundSlot->price;
                    }
                }
            }
            $cart->slot_price = $slot_price;
            $cart->save();

            // Add selected service options
            if ($request->filled('selected_options') && is_array($request->selected_options)) {
                foreach ($request->selected_options as $optionId => $quantity) {
                    CartServiceOption::create([
                        'cart_id' => $cart->id,
                        'service_option_id' => $optionId,
                        'quantity' => $quantity ?? 1,
                    ]);
                }
            }
            if ($request->filled('addons') && is_array($request->addons)) {
                foreach ($request->addons as $addonId => $addonData) {
                    $quantity = is_array($addonData)
                        ? ($addonData['quantity'] ?? 1)
                        : $addonData; 
                    $parent_id = is_array($addonData)
                        ? ($addonData['parent_id'] ?? 1)
                        : $addonData;
                    CartServiceAddon::create([
                        'cart_id' => $cart->id,
                        'addon_id' => $addonId,
                        'quantity' => $quantity ?? 1,
                        'parent_id' => $parent_id ?? 1,
                    ]);
                }
            }

            DB::commit();

            return $this->success($message, [
                'cart_id' => (string) $cart->id
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Add to cart failed: ' . $e->getMessage(), $request->all());
            return $this->error('Failed to add to cart', $e->getMessage());
        }
    }

    /**
     * Add or Update Cart Item (Fixed Price Services)
     * For services with fixed pricing based on service options only
     */
    public function add_to_cart_fixed(Request $request)
    {
        // Check authentication
        // Validate token and get user
        $auth = $this->validateAccessToken($request);

        if (!$auth['success']) {
            return $auth['response']; // Return error response
        }

        $user = $auth['user']; // Get authenticated user

        $validator = Validator::make($request->all(), [
            'cart_id' => 'nullable|integer|exists:carts,id',
            'service_id' => 'required|integer|exists:services,id',
            'address_id' => 'required|integer|exists:user_addresses,id',
            'alternate_mobile_number' => 'nullable|string|max:20',
            'important_information' => 'nullable|string',
            'sessions' => 'required|array|min:1',
            'sessions.*.date' => 'required|string',
            'sessions.*.time_slot' => 'required|string',
            'selected_options' => 'nullable|array',
            'selected_options.*.quantity' => 'integer|min:1'
        ]);

        if ($validator->fails()) {
            return $this->error('Validation failed', $validator->errors());
        }

        DB::beginTransaction();
        try {
            // Get service
            $service = Service::findOrFail($request->service_id);

            // Check if updating existing cart
            if ($request->filled('cart_id')) {
                $cart = Cart::where('id', $request->cart_id)
                    ->where('user_id', $user->id)
                    ->first();

                if (!$cart) {
                    return $this->error('Cart item not found', null, 404);
                }
                $file_name = "";
                if ($request->hasFile('file')) {
                    $file = $request->file('file');
                    $file_name = time() . uniqid() . "." . $file->getClientOriginalExtension();
                    $file->storeAs(config('global.order_files'), $file_name, config('global.upload_bucket'));
                }

                // Update cart entry
                $cart->update([
                    'service_id' => $request->service_id,
                    'package_id' => 0,
                    'price_matrix_id' => 0,
                    'service_type' => $service->service_types,
                    'address_id' => $request->address_id,
                    'alternate_mobile_number' => $request->alternate_mobile_number,
                    'important_information' => $request->important_information,
                ]);
                if ($file_name) {
                    $cart->update(['file' => $file_name]);
                }

                // Delete existing sessions and options
                CartSession::where('cart_id', $cart->id)->delete();
                CartServiceOption::where('cart_id', $cart->id)->delete();
                CartServiceAddon::where('cart_id', $cart->id)->delete();

                $message = "Cart updated successfully";
            } else {
                $file_name = "";
                if ($request->hasFile('file')) {
                    $file = $request->file('file');
                    $file_name = time() . uniqid() . "." . $file->getClientOriginalExtension();
                    $file->storeAs(config('global.order_files'), $file_name, config('global.upload_bucket'));
                }
                // Create new cart entry
                $cart = Cart::create([
                    'user_id' => $user->id,
                    'service_id' => $request->service_id,
                    'package_id' => 0,
                    'price_matrix_id' => 0,
                    'service_type' => $service->service_types,
                    'address_id' => $request->address_id,
                    'alternate_mobile_number' => $request->alternate_mobile_number,
                    'important_information' => $request->important_information,
                    'file' => $file_name
                ]);

                $message = "Item added to cart successfully";
            }

            // Add sessions
            $slot_price = 0;
            foreach ($request->sessions as $session) {
                // Parse time slot (format: "HH:mm-HH:mm")
                $timeParts = explode('-', $session['time_slot']);

                // Parse date - handle both dd/mm/yyyy and Y-m-d formats
                $date = $session['date'];
                if (strpos($date, '/') !== false) {
                    // dd/mm/yyyy format
                    $dateParts = explode('/', $date);
                    $formattedDate = $dateParts[2] . '-' . $dateParts[1] . '-' . $dateParts[0];
                } else {
                    // Assume Y-m-d format
                    $formattedDate = $date;
                }

                CartSession::create([
                    'cart_id' => $cart->id,
                    'service_date' => $formattedDate,
                    'slot_from' => $timeParts[0] ?? null,
                    'slot_to' => $timeParts[1] ?? null,
                ]);
                if ($timeParts[0]) {
                    $timeFrom = substr($timeParts[0], 0, 5);
                    $foundSlot = TimeSlot::where('slot_date', $formattedDate)
                        ->whereRaw("SUBSTRING(CAST(time_from AS TEXT), 1, 5) = ?", [$timeFrom])
                        ->first();
                    if ($foundSlot) {
                        $slot_price += $foundSlot->price;
                    }
                }
            }

            $cart->slot_price = $slot_price;
            $cart->save();

            // Add selected service options
            // Note: We don't store price - always fetch current price from service_options
            if ($request->filled('selected_options') && is_array($request->selected_options)) {
                foreach ($request->selected_options as $optionId => $optionData) {
                    $quantity = is_array($optionData)
                        ? ($optionData['quantity'] ?? 1)
                        : $optionData;

                    CartServiceOption::create([
                        'cart_id' => $cart->id,
                        'service_option_id' => $optionId,
                        'quantity' => $quantity
                    ]);
                }
            }

            if ($request->filled('addons') && is_array($request->addons)) {
                foreach ($request->addons as $addonId => $addonData) {
                    $quantity = is_array($addonData)
                        ? ($addonData['quantity'] ?? 1)
                        : $addonData; 
                    $parent_id = is_array($addonData)
                        ? ($addonData['parent_id'] ?? 1)
                        : $addonData;
                    CartServiceAddon::create([
                        'cart_id' => $cart->id,
                        'addon_id' => $addonId,
                        'quantity' => $quantity ?? 1,
                        'parent_id' => $parent_id ?? 1,
                    ]);
                }
            }

            DB::commit();

            return $this->success($message, [
                'cart_id' => (string) $cart->id
            ]);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Add to cart (fixed) failed: ' . $e->getMessage(), $request->all());
            return $this->error('Failed to add to cart', $e->getMessage());
        }
    }

    /**
     * Get User Cart
     * Returns all cart items for the logged-in user with calculated totals
     */
    public function get_cart(Request $request)
    {
        // Validate token and get user
        $auth = $this->validateAccessToken($request);

        if (!$auth['success']) {
            return $auth['response']; // Return error response
        }

        $user = $auth['user']; // Get authenticated user

        try {
            $timezone = 'Asia/Dubai';
            $todayInTz = Carbon::now($timezone);
            $hasPastItem = false;

            // Get all cart items for the logged-in user
            $carts = Cart::with([
                'service',
                'package',
                'priceMatrix',
                'address',
                'sessions',
                'serviceOptions.serviceOption',
                'addons.addon'
            ])
                ->where('user_id', $user->id)
                ->orderBy('created_at', 'desc')
                ->get();
            if ($carts->isEmpty()) {
                return $this->success('Cart is empty', [
                    'cart_items' => [],
                    'total_amount' => "0.00",
                    'total_items' => "0",
                    'has_past_item' => "0"
                ]);
            }

            $totalAmount = 0;
            $totalSlotPrice = 0;
            $cartItems = [];

            foreach ($carts as $cart) {
                $itemTotal = 0;
                $hasPastSession = false;
                $totalSlotPrice += $cart->slot_price;

                // Check for past sessions
                if ($cart->sessions && $cart->sessions->count() > 0) {
                    foreach ($cart->sessions as $s) {
                        try {
                            $sessionDate = Carbon::createFromFormat('Y-m-d', $s->service_date, $timezone)->startOfDay();
                        } catch (\Exception $e) {
                            $sessionDate = Carbon::parse($s->service_date, $timezone)->startOfDay();
                        }

                        if ($s->slot_from) {
                            try {
                                $sessionDateTime = Carbon::createFromFormat('Y-m-d H:i', $s->service_date . ' ' . $s->slot_from, $timezone);
                            } catch (\Exception $e) {
                                $sessionDateTime = $sessionDate;
                            }
                        } else {
                            $sessionDateTime = $sessionDate;
                        }

                        if ($sessionDateTime->lt($todayInTz)) {
                            $hasPastSession = true;
                            $hasPastItem = true;
                            break;
                        }
                    }
                }

                // Calculate item total
                if ($cart->service && $cart->service->service_types == 'fixed_price') {
                    // Fixed price service - calculate from current service option prices
                    foreach ($cart->serviceOptions as $cartOption) {
                        if ($cartOption->serviceOption) {
                            $currentPrice = $cartOption->serviceOption->price;
                            $quantity = $cartOption->quantity;
                            $itemTotal += ($currentPrice * $quantity);
                        }
                        
                       
                    }
                     foreach ($cart->addons as $opt) {
                            if ($opt->addon) {
                                $currentPrice = $opt->addon->price;
                                $quantity = $opt->quantity;
                                $itemTotal += $opt->addon->price * $opt->quantity;
                            }
                        }
                    
                } elseif ($cart->priceMatrix) {
                    // Variable pricing service
                    if ($cart->package_id == 1) {
                        // One-time booking
                        $itemTotal = $cart->priceMatrix->total_price;
                    } else {
                        // Multiple sessions with package
                        $package = $cart->package;
                        if ($package) {
                            $totalSessions = $package->total_sessions ?? $cart->sessions->count();
                            $itemTotal = $totalSessions * $cart->priceMatrix->total_price;
                        } else {
                            $itemTotal = $cart->sessions->count() * $cart->priceMatrix->total_price;
                        }
                    }
                }

                $totalAmount += $itemTotal;

                // Format sessions
                $sessions = $cart->sessions->map(function ($s) {
                    return [
                        'date' => $s->service_date,
                        'day' => Carbon::parse($s->service_date)->format('l'),
                        'display_date' => Carbon::parse($s->service_date)->format('d M, Y'),
                        'time_slot' => ($s->slot_from && $s->slot_to)
                            ? $s->slot_from . '-' . $s->slot_to
                            : null,
                        'slot_from' => $s->slot_from,
                        'slot_to' => $s->slot_to
                    ];
                });


                // Format service options
                $options = $cart->serviceOptions->map(function ($opt) {
                    return [
                        'option_id' => (string) $opt->service_option_id,
                        'option_title' => $opt->serviceOption->option_title ?? '',
                        'quantity' => (string) $opt->quantity,
                        'unit_price' => number_format($opt->serviceOption->price ?? 0, 2),
                        'total_price' => number_format(($opt->serviceOption->price ?? 0) * $opt->quantity, 2)
                    ];
                });
                $addons = $cart->addons->map(function ($opt) {
                    return [
                        'addon_id' => (string) $opt->addon_id,
                        'addon_title' => $opt->addon->title ?? '',
                        'quantity' => (string) $opt->quantity,
                        'parent_id' => (string) $opt->parent_id,
                        'unit_price' => number_format($opt->addon->price ?? 0, 2),
                        'total_price' => number_format(($opt->addon->price ?? 0) * $opt->quantity, 2)
                    ];
                });
                $package = $cart->package;
                $cartItems[] = [
                    'cart_id' => (string) $cart->id,
                    'service_id' => (string) $cart->service_id,
                    'service_name' => $cart->service->name ?? '',
                    'service_type' => $cart->service->service_types ?? '',
                    'service_icon' => $cart->service->icon_url ?? '',
                    'cover_image' => $cart->service->cover_image_url,
                    'thumb_image' => $cart->service->thumb_image_url,
                    'package_id' => (string) $cart->package_id,
                    'package_name' => $cart->package->name ?? '',
                    'address_id' => (string) $cart->address_id,
                    'address' => $cart->address->address ?? '',
                    'alternate_mobile' => $cart->alternate_mobile_number,
                    'important_info' => $cart->important_information,
                    'file' => $cart->file_url,
                    'slot_price' => (string) $cart->slot_price,
                    'item_total' => number_format($itemTotal, 2),
                    'has_past_session' => $hasPastSession ? "1" : "0",
                    'sessions' => $sessions,
                    'options' => $options,
                    'addons' => $addons,
                    'price_matrix' => $cart->priceMatrix ? [
                        'maid_count' => (string) $cart->priceMatrix->maid_count,
                        'hour_count' => (string) $cart->priceMatrix->hour_count,
                        'with_materials' => $cart->priceMatrix->with_materials ? "1" : "0",
                        'base_price' => (string) ($cart->priceMatrix->base_price * ($package->total_sessions ?? 1)),
                        'material_surcharge' => (string) (($cart->priceMatrix->material_surcharge ?? 0) * ($package->total_sessions ?? 1)),
                        'total_price' => number_format(($cart->priceMatrix->total_price * ($package->total_sessions ?? 1)), 2)
                    ] : null,
                    'created_at' => $cart->created_at->format('Y-m-d H:i:s')
                ];
            }
            return $this->success('Cart fetched successfully', [
                'cart_items' => $cartItems,
                'total_amount' => number_format($totalAmount, 2),
                'total_items' => (string) $carts->count(),
                'has_past_item' => $hasPastItem ? "1" : "0",
                'total_slot_price' => (string) $totalSlotPrice
            ]);
        } catch (\Exception $e) {
            Log::error('Get cart failed: ' . $e->getMessage());
            return $this->error('Failed to fetch cart', $e->getMessage());
        }
    }

    /**
     * Remove Cart Item
     */
    public function remove_cart_item(Request $request)
    {
        // Validate token and get user
        $auth = $this->validateAccessToken($request);

        if (!$auth['success']) {
            return $auth['response']; // Return error response
        }

        $user = $auth['user']; // Get authenticated user


        $validator = Validator::make($request->all(), [
            'cart_id' => 'required|integer|exists:carts,id'
        ]);

        if ($validator->fails()) {
            return $this->error('Validation failed', $validator->errors());
        }

        try {
            // Find cart item
            $cart = Cart::where('id', $request->cart_id)
                ->where('user_id', $user->id)
                ->first();

            if (!$cart) {
                return $this->error('Cart item not found', null, 404);
            }

            // Delete related sessions and options
            $cart->sessions()->delete();
            $cart->serviceOptions()->delete();

            // Delete cart item
            $cart->delete();

            return $this->success('Item removed from cart successfully', [
                'cart_id' => (string) $request->cart_id
            ]);
        } catch (\Exception $e) {
            Log::error('Remove cart item failed: ' . $e->getMessage(), $request->all());
            return $this->error('Failed to remove item', $e->getMessage());
        }
    }

    /**
     * Checkout - Get cart summary for checkout
     */
    public function checkout(Request $request)
    {
        // Validate token and get user
        $auth = $this->validateAccessToken($request);

        if (!$auth['success']) {
            return $auth['response']; // Return error response
        }

        $user = $auth['user']; // Get authenticated user


        $validator = Validator::make($request->all(), [
            'cart_id' => 'nullable|integer|exists:carts,id'
        ]);

        if ($validator->fails()) {
            return $this->error('Validation failed', $validator->errors());
        }

        try {
            $timezone = 'Asia/Dubai';
            $todayInTz = Carbon::now($timezone);

            // If cart_id provided, get specific cart item
            // Otherwise, get all cart items
            if ($request->filled('cart_id')) {
                $carts = Cart::with([
                    'service',
                    'package',
                    'priceMatrix',
                    'address',
                    'user',
                    'sessions',
                    'serviceOptions.serviceOption'
                ])
                    ->where('id', $request->cart_id)
                    ->where('user_id', $user->id)
                    ->get();
            } else {
                $carts = Cart::with([
                    'service',
                    'package',
                    'priceMatrix',
                    'address',
                    'user',
                    'sessions',
                    'serviceOptions.serviceOption'
                ])
                    ->where('user_id', $user->id)
                    ->get();
            }

            if ($carts->isEmpty()) {
                return $this->error('Cart is empty', null, 404);
            }

            $totalAmount = 0;
            $checkoutItems = [];

            foreach ($carts as $cart) {
                $itemTotal = 0;

                // Check for past sessions
                $hasPastSession = false;
                if ($cart->sessions && $cart->sessions->count() > 0) {
                    foreach ($cart->sessions as $s) {
                        try {
                            $sessionDateTime = Carbon::createFromFormat('Y-m-d H:i', $s->service_date . ' ' . ($s->slot_from ?? '00:00'), $timezone);
                        } catch (\Exception $e) {
                            $sessionDateTime = Carbon::parse($s->service_date, $timezone)->startOfDay();
                        }

                        if ($sessionDateTime->lt($todayInTz)) {
                            $hasPastSession = true;
                            break;
                        }
                    }
                }

                // Skip items with past sessions
                if ($hasPastSession) {
                    continue;
                }

                // Calculate total
                if ($cart->service && $cart->service->service_types == 'fixed_price') {
                    foreach ($cart->serviceOptions as $cartOption) {
                        if ($cartOption->serviceOption) {
                            $itemTotal += ($cartOption->serviceOption->price * $cartOption->quantity);
                        }
                    }
                } elseif ($cart->priceMatrix) {
                    if ($cart->package_id == 1) {
                        $itemTotal = $cart->priceMatrix->total_price;
                    } else {
                        $package = $cart->package;
                        if ($package) {
                            $totalSessions = $package->total_sessions ?? $cart->sessions->count();
                            $itemTotal = $totalSessions * $cart->priceMatrix->total_price;
                        } else {
                            $itemTotal = $cart->sessions->count() * $cart->priceMatrix->total_price;
                        }
                    }
                }

                $totalAmount += $itemTotal;

                $checkoutItems[] = [
                    'cart_id' => (string) $cart->id,
                    'service_name' => $cart->service->name ?? '',
                    'package_name' => $cart->package->name ?? 'One-time Service',
                    'address' => $cart->address->address ?? '',
                    'sessions_count' => (string) $cart->sessions->count(),
                    'item_total' => number_format($itemTotal, 2)
                ];
            }

            if (empty($checkoutItems)) {
                return $this->error('No valid items for checkout', null, 200);
            }

            // $user = $user->id;;

            return $this->success('Checkout data fetched', [
                'user' => [
                    'name' => $user->name ?? '',
                    'email' => $user->email ?? '',
                    'phone' => $user->phone ?? ''
                ],
                'items' => $checkoutItems,
                'subtotal' => number_format($totalAmount, 2),
                'tax_amount' => "0.00",
                'discount' => "0.00",
                'grand_total' => number_format($totalAmount, 2)
            ]);
        } catch (\Exception $e) {
            Log::error('Checkout failed: ' . $e->getMessage(), $request->all());
            return $this->error('Failed to load checkout', $e->getMessage());
        }
    }
}
