<?php


namespace App\Services\APIs\CustomerAPIs;

use Illuminate\Support\Facades\DB;
use App\Models\CustomerFavouriteRestaurant;
use App\Models\IamPrincipal;
use App\Models\IamPrincipalRestaurantRole;
use App\Models\ManageRestaurant;
use App\Models\RedeemRestaurant;
use App\Helpers\onesignalhelper;
use App\Models\RestaurantTimeInterval;
use App\Models\TimeInterval;
use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use App\Jobs\FetchOperatingHours;
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
use GuzzleHttp\Promise\Utils;



class RestaurantApiServices
{
    public function getCoordinates($customerIamId)
    {
        try {
            // Fetch all active restaurants
            $restaurants = ManageRestaurant::with('closedRestaurant')
                ->select('id', 'name', 'image', 'address', 'short_id', 'latitude', 'longtitude', 'state_xid')
                ->where('is_active', '1')->get();

            foreach ($restaurants as &$restaurant) {
                $restaurant['image'] = ListingImageUrl('restaurant_images', $restaurant['image']);
                $isFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
                    ->where('restaurant_xid', $restaurant['id'])
                    ->exists();
                $restaurant['is_favourite'] = $isFavourite;

                $hoursData = getOperatingHours($restaurant['name'], $restaurant['address']);
                $restaurant['operating_hours'] = $hoursData['operating_hours'];
                $restaurant['is_restaurant_open_now_as_per_google'] = $hoursData['is_open_now'];


                $lastRedeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
                ->where('manage_restaurants_xid', $restaurant->id)
                ->where('is_redeem', 1)
                ->orderBy('redeem_date', 'desc')
                ->first();

            $restTime = RestaurantTimeInterval::select('time_hours')->where('manage_restaurants_xid', $restaurant->id)->first();
            $stateTime = TimeInterval::select('time_hours')->where('manage_state_xid', $restaurant->state_xid)->first();

            $restTimeHours = $restTime ? $restTime->time_hours : 0;
            $stateTimeHours = $stateTime ? $stateTime->time_hours : 0;

            $restaurant['next_redeem_time'] = "Now";
            $currentTime = Carbon::now();


            if ($lastRedeem) {
                $lastRedeemTime = Carbon::parse($lastRedeem->redeem_date);

                $restAllowedRedeemTime = $lastRedeemTime->copy()->addHours(intval($restTimeHours));
                $stateAllowedRedeemTime = $lastRedeemTime->copy()->addHours(intval($stateTimeHours));

                if ($currentTime < $restAllowedRedeemTime) {
                    $restaurant['next_redeem_time'] = $restAllowedRedeemTime->toDateTimeString();
                } else if ($currentTime < $stateAllowedRedeemTime) {
                    $restaurant['next_redeem_time'] = $stateAllowedRedeemTime->toDateTimeString();
                }
            }

            // Include logic for preventing redemption in the same state
            if ($restaurant['next_redeem_time'] === "Now") {
                // Fetch the last redeem time for any restaurant in the same state
                $lastStateRedeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
                    ->where('state_xid', $restaurant->state_xid)
                    ->where('is_redeem', 1)
                    ->orderBy('redeem_date', 'desc')
                    ->first();

                if ($lastStateRedeem) {
                    $lastStateRedeemTime = Carbon::parse($lastStateRedeem->redeem_date);
                    $stateAllowedRedeemTime = $lastStateRedeemTime->copy()->addHours(intval($stateTimeHours));

                    if ($currentTime < $stateAllowedRedeemTime) {
                        $restaurant['next_redeem_time'] = $stateAllowedRedeemTime->toDateTimeString();
                    }
                }
            }            }

            return jsonResponseWithSuccessMessage(__('auth.data_fetched_successfully'), $restaurants, 200);
        } catch (Exception $ex) {
            Log::error('Restaurant Get service failed : ' . $ex->getMessage());
            return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
        }
    }





    public function addToFavourite($customerIamId, $request)
    {
        try {
            DB::beginTransaction();

            $restaurant = ManageRestaurant::where('short_id', $request->id)->where('is_active', '1')->first();
            if (!$restaurant) {
                return jsonResponseWithErrorMessage(__('auth.restaurant_data_not_found'), 404);
            }

            $existingFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
                ->where('restaurant_xid', $restaurant->id)
                ->first();

            if ($existingFavourite) {
                return jsonResponseWithErrorMessage(__('auth.restaurant_already_favourite'), 409);
            }

            $favRestaurant = new CustomerFavouriteRestaurant();
            $favRestaurant->principal_xid = $customerIamId;
            $favRestaurant->restaurant_xid = $restaurant->id;
            $favRestaurant->save();

            DB::commit();

            return jsonResponseWithSuccessMessage(__('auth.data_updated_successfully'), 200);
        } catch (\Exception $ex) {
            DB::rollBack();
            Log::error('Favourite Restaurant service failed: ' . $ex->getMessage());
            return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
        }
    }


    public function listFavRestaurant($customerIamId)
    {
        try {
            // Get list of favorite restaurant IDs
            $customerFavouriteRestaurants = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
                ->pluck('restaurant_xid')
                ->toArray();

            // Fetch the restaurant details
            $restaurants = ManageRestaurant::with('closedRestaurant')->where('is_active', '1')
                ->whereIn('id', $customerFavouriteRestaurants)
                ->get();



            foreach ($restaurants as &$res) {
                $res['image'] = ListingImageUrl('restaurant_images', $res['image']);

                // Fetch operating hours and open status using the helper function
                $data = getOperatingHours($res->name, $res->address);

                $res['operating_hours'] = $data['operating_hours'];
                $res['is_restaurant_open_now_as_per_google'] = $data['is_open_now'];
            }

            return jsonResponseWithSuccessMessage(__('auth.data_updated_successfully'), $restaurants, 200);
        } catch (Exception $ex) {
            Log::error('List of Favourite Restaurant service failed : ' . $ex->getMessage());
            return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
        }
    }




    //
    // public function DetailRestaurant($customerIamId, $id)
    // {
    //     try {
    //         $rest = ManageRestaurant::with('closedRestaurant')->select('id', 'short_id', 'name', 'description', 'restaurant_id', 'address', 'image', 'bio', 'try_on_1', 'try_on_2', 'try_on_3', 'try_on_4', 'exclusion', 'latitude', 'longtitude', 'state_xid')
    //             ->where('short_id', $id)
    //             ->where('is_active', '1')
    //             ->first();

    //         if ($rest) {
    //             $rest->image = ListingImageUrl('restaurant_images', $rest->image);

    //             $isFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
    //                 ->where('restaurant_xid', $rest->id)
    //                 ->exists();

    //             $rest->is_favourite = $isFavourite;

    //             $redeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
    //                 ->where('manage_restaurants_xid', $rest->id)
    //                 ->where('is_redeem', "1")
    //                 ->first();

    //             $restTime = RestaurantTimeInterval::where('manage_restaurants_xid', $rest->id)->first();
    //             $restTimeHours = $restTime ? $restTime->time_hours : 0;

    //             // Initialize Guzzle HTTP client
    //             $client = new Client();
    //             $googlePlaceApiKey = config('constants.googlePlaces.api_key');

    //             // Cache key for operating hours
    //             $cacheKey = 'restaurant_hours_' . $rest->name;
    //             $cacheKeyIsRestaurantOpen = 'is_restaurant_open_now_' . $rest->name;

    //             if (Cache::has($cacheKey)) {
    //                 $rest->operating_hours = Cache::get($cacheKey);
    //                 $rest->is_restaurant_open_now_as_per_google = Cache::get($cacheKeyIsRestaurantOpen);
    //             } else {
    //                 // Prepare the first request to get the place_id
    //                 $placeResponse = $client->get('https://maps.googleapis.com/maps/api/place/findplacefromtext/json', [
    //                     'query' => [
    //                         'fields' => 'place_id',
    //                         'input' => $rest->name . ' ' . $rest->address,
    //                         'inputtype' => 'textquery',
    //                         'key' => $googlePlaceApiKey
    //                     ]
    //                 ]);
    //                 $placeData = json_decode($placeResponse->getBody(), true);

    //                 if (isset($placeData['candidates'][0]['place_id'])) {
    //                     $placeId = $placeData['candidates'][0]['place_id'];

    //                     // Prepare the second request to get the operating hours
    //                     $detailResponse = $client->get('https://maps.googleapis.com/maps/api/place/details/json', [
    //                         'query' => [
    //                             'fields' => 'opening_hours',
    //                             'place_id' => $placeId,
    //                             'key' => $googlePlaceApiKey
    //                         ]
    //                     ]);
    //                     $detailData = json_decode($detailResponse->getBody(), true);

    //                     if (isset($detailData['result']['opening_hours']['weekday_text'])) {
    //                         $hours = $detailData['result']['opening_hours']['weekday_text'];
    //                         $isOpenNow = $detailData['result']['opening_hours']['open_now'];
    //                         Cache::put($cacheKey, $hours, now()->addHours(2));
    //                         Cache::put($cacheKeyIsRestaurantOpen, $isOpenNow, now()->addHours(2));

    //                         $rest->operating_hours = $hours;
    //                         $rest->is_restaurant_open_now_as_per_google = $isOpenNow;
    //                     } else {
    //                         $rest->operating_hours = "N/A";

    //                         $rest->is_restaurant_open_now_as_per_google = false;

    //                     }
    //                 } else {
    //                     $rest->operating_hours = "N/A";
    //                     $rest->is_restaurant_open_now_as_per_google = false;

    //                 }
    //             }

    //             if ($redeem) {
    //                 $rest->is_Redeemed = true;
    //                 $rest->redeem_date = \Carbon\Carbon::parse($redeem->redeem_date)->addHours(intval($restTimeHours))->toDateTimeString();
    //             } else {
    //                 $rest->is_Redeemed = false;
    //                 $rest->redeem_date = null;
    //             }

    //             // Calculate next redemption time
    //             $lastRedeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
    //                 ->where('manage_restaurants_xid', $rest->id)
    //                 ->where('is_redeem', 1)
    //                 ->orderBy('redeem_date', 'desc')
    //                 ->first();

    //             $stateTime = TimeInterval::select('time_hours')->where('manage_state_xid', $rest->state_xid)->first();
    //             $stateTimeHours = $stateTime ? $stateTime->time_hours : 0;

    //             $currentTime = Carbon::now();
    //             $nextRedeemTime = "Now";

    //             if ($lastRedeem) {
    //                 $lastRedeemTime = Carbon::parse($lastRedeem->redeem_date);

    //                 $restAllowedRedeemTime = $lastRedeemTime->copy()->addHours(intval($restTimeHours));
    //                 $stateAllowedRedeemTime = $lastRedeemTime->copy()->addHours(intval($stateTimeHours));

    //                 if ($currentTime < $restAllowedRedeemTime) {
    //                     $nextRedeemTime = $restAllowedRedeemTime->toDateTimeString();
    //                 } else if ($currentTime < $stateAllowedRedeemTime) {
    //                     $nextRedeemTime = $stateAllowedRedeemTime->toDateTimeString();
    //                 }
    //             }

    //             // Include logic for preventing redemption in the same state
    //             if ($nextRedeemTime === "Now") {
    //                 $lastStateRedeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
    //                     ->where('state_xid', $rest->state_xid)
    //                     ->where('is_redeem', 1)
    //                     ->orderBy('redeem_date', 'desc')
    //                     ->first();

    //                 if ($lastStateRedeem) {
    //                     $lastStateRedeemTime = Carbon::parse($lastStateRedeem->redeem_date);
    //                     $stateAllowedRedeemTime = $lastStateRedeemTime->copy()->addHours(intval($stateTimeHours));

    //                     if ($currentTime < $stateAllowedRedeemTime) {
    //                         $nextRedeemTime = $stateAllowedRedeemTime->toDateTimeString();
    //                     }
    //                 }
    //             }

    //             $rest->next_redeem_time = $nextRedeemTime;
    //         }

    //         if (!$rest) {
    //             return jsonResponseWithErrorMessage(__('auth.restaurant_data_not_found'), 404);
    //         }

    //         return jsonResponseWithSuccessMessage(__('auth.data_fetched_successfully'), $rest, 200);
    //     } catch (Exception $e) {
    //         Log::error("Error fetching restaurant data: " . $e->getMessage());
    //         return jsonResponseWithErrorMessage(__('auth.something_went_wrong'), 500);
    //     }
    // }
    public function DetailRestaurant($customerIamId, $id)
    {
        try {
            $rest = ManageRestaurant::with('closedRestaurant')
                ->select('id', 'short_id', 'name', 'description', 'restaurant_id', 'address', 'image', 'bio', 'try_on_1', 'try_on_2', 'try_on_3', 'try_on_4', 'exclusion', 'latitude', 'longtitude', 'state_xid')
                ->where('short_id', $id)
                ->where('is_active', '1')
                ->first();

            if ($rest) {
                $rest->image = ListingImageUrl('restaurant_images', $rest->image);

                $isFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
                    ->where('restaurant_xid', $rest->id)
                    ->exists();
                $rest->is_favourite = $isFavourite;

                $redeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
                    ->where('manage_restaurants_xid', $rest->id)
                    ->where('is_redeem', "1")
                    ->first();

                $hoursData = getOperatingHours($rest->name, $rest->address);
                $rest->operating_hours = $hoursData['operating_hours'];
                $rest->is_restaurant_open_now_as_per_google = $hoursData['is_open_now'];




                $restTime = RestaurantTimeInterval::where('manage_restaurants_xid', $rest->id)->first();
                $restTimeHours = $restTime ? $restTime->time_hours : 0;
                if ($redeem) {
                    $rest->is_Redeemed = true;
                    $rest->redeem_date = \Carbon\Carbon::parse($redeem->redeem_date)->addHours(intval($restTimeHours))->toDateTimeString();
                } else {
                    $rest->is_Redeemed = false;
                    $rest->redeem_date = null;
                }

                $lastRedeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
                    ->where('manage_restaurants_xid', $rest->id)
                    ->where('is_redeem', 1)
                    ->orderBy('redeem_date', 'desc')
                    ->first();

                $stateTime = TimeInterval::select('time_hours')->where('manage_state_xid', $rest->state_xid)->first();
                $stateTimeHours = $stateTime ? $stateTime->time_hours : 0;

                $currentTime = Carbon::now();
                $nextRedeemTime = "Now";

                if ($lastRedeem) {
                    $lastRedeemTime = Carbon::parse($lastRedeem->redeem_date);

                    $restAllowedRedeemTime = $lastRedeemTime->copy()->addHours(intval($restTimeHours));
                    $stateAllowedRedeemTime = $lastRedeemTime->copy()->addHours(intval($stateTimeHours));

                    if ($currentTime < $restAllowedRedeemTime) {
                        $nextRedeemTime = $restAllowedRedeemTime->toDateTimeString();
                    } else if ($currentTime < $stateAllowedRedeemTime) {
                        $nextRedeemTime = $stateAllowedRedeemTime->toDateTimeString();
                    }
                }

                // Include logic for preventing redemption in the same state
                if ($nextRedeemTime === "Now") {
                    $lastStateRedeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
                        ->where('state_xid', $rest->state_xid)
                        ->where('is_redeem', 1)
                        ->orderBy('redeem_date', 'desc')
                        ->first();

                    if ($lastStateRedeem) {
                        $lastStateRedeemTime = Carbon::parse($lastStateRedeem->redeem_date);
                        $stateAllowedRedeemTime = $lastStateRedeemTime->copy()->addHours(intval($stateTimeHours));

                        if ($currentTime < $stateAllowedRedeemTime) {
                            $nextRedeemTime = $stateAllowedRedeemTime->toDateTimeString();
                        }
                    }
                }

                $rest->next_redeem_time = $nextRedeemTime;
            }


            if (!$rest) {
                return jsonResponseWithErrorMessage(__('auth.restaurant_data_not_found'), 404);
            }

            return jsonResponseWithSuccessMessage(__('auth.data_fetched_successfully'), $rest, 200);
        } catch (Exception $e) {
            Log::error("Error fetching restaurant data: " . $e->getMessage());
            return jsonResponseWithErrorMessage(__('auth.something_went_wrong'), 500);
        }
    }


    public function removeFromFavourite($customerIamId, $request)
    {
        try {
            DB::beginTransaction();

            $restaurant = ManageRestaurant::where('short_id', $request->id)->where('is_active', '1')->first();
            if (!$restaurant) {
                return jsonResponseWithErrorMessage(__('auth.restaurant_data_not_found'), 404);
            }

            $existingFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
                ->where('restaurant_xid', $restaurant->id)
                ->first();
            if (!$existingFavourite) {
                return jsonResponseWithErrorMessage(__('auth.data_not_found'), 404);
            }
            if ($existingFavourite) {
                $existingFavourite->delete();
            }
            DB::commit();

            return jsonResponseWithSuccessMessage(__('auth.data_updated_successfully'), 200);
        } catch (\Exception $ex) {
            DB::rollBack();
            Log::error('Favourite Restaurant service failed: ' . $ex->getMessage());
            return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
        }
    }


    public function searchFromFavourite($customerIamId, $request)
    {
        try {
            // Get list of favorite restaurant IDs
            $customerFavouriteRestaurants = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
                ->pluck('restaurant_xid')
                ->toArray();

            // Fetch the restaurant details
            $restaurantsQuery = ManageRestaurant::with('closedRestaurant')->where('is_active', '1')
                ->whereIn('id', $customerFavouriteRestaurants);

            $searchData = $request->input('search_data');

            if (!empty($searchData)) {
                $restaurantsQuery->where(function ($query) use ($searchData) {
                    $query->where('name', 'like', "%$searchData%")
                        ->orWhere('description', 'like', "%$searchData%")
                        ->orWhere('address', 'like', "%$searchData%")
                        ->orWhereHas('state', function ($stateQuery) use ($searchData) {
                            $stateQuery->where('name', 'like', "%$searchData%");
                        });
                });
            }

            $restaurants = $restaurantsQuery->get();

            foreach ($restaurants as &$res) {
                $res['image'] = ListingImageUrl('restaurant_images', $res['image']);

                $data = getOperatingHours($res->name, $res->address);

                $res['operating_hours'] = $data['operating_hours'];
                $res['is_restaurant_open_now_as_per_google'] = $data['is_open_now'];
            }

            return jsonResponseWithSuccessMessageApi(__('auth.restaurant_search'), $restaurants, 200);
        } catch (Exception $ex) {
            Log::error('Search from favourite restaurant service failed: ' . $ex->getMessage());
            return response()->json([
                'message' => __('auth.something_went_wrong')
            ], 500);
        }
    }



    public function redeemRestaurant($customerIamId, $request)
    {
        try {
            $restaurantId = $request->id;

            $restaurant = ManageRestaurant::with('operatingHours')->where('short_id', $restaurantId)->first();
            if (!$restaurant) {
                return jsonResponseWithErrorMessageApi(__('auth.restaurant_not_found'), 404);
            }

            // Check if the restaurant has already been redeemed
            $restaurantExist = RedeemRestaurant::where('manage_restaurants_xid', $restaurant->id)
                ->where('iam_principal_xid', $customerIamId)
                ->where('is_redeem', 1)
                ->first();


            if ($restaurantExist) {
                return jsonResponseWithErrorMessageApi(__('auth.restaurant_already_redeemed'), 403);
            }

            $stateLimitation = TimeInterval::where('manage_state_xid', $restaurant->state_xid)->first();
            $stateMaxLimitation = $stateLimitation ? $stateLimitation->quantity : 0;
            $stateMaxIntervalLimitation = $stateLimitation ? $stateLimitation->time_interval : "month";

            $restaurantLimitation = RestaurantTimeInterval::where('manage_restaurants_xid', $restaurant->id)->first();
            $restaurantMaxLimitation = $restaurantLimitation ? $restaurantLimitation->quantity : 0;
            $restaurantMaxIntervalLimitation = $restaurantLimitation ? $restaurantLimitation->time_interval : "month";


            // Calculate the state interval start date
            $stateIntervalStartDate = $this->calculateIntervalStartDate($stateMaxIntervalLimitation);

            // Count the redeems within the state interval
            $redeemCountState = RedeemRestaurant::where('state_xid', $restaurant->state_xid)
                ->where('iam_principal_xid', $customerIamId)
                ->count();

            if ($redeemCountState >= $stateMaxLimitation) {
                return jsonResponseWithDataErrorMessageApi(__('limitexceed'), ('You have reached the maximum limit for redeeming vouchers.'));
            }

            // Calculate the restaurant interval start date
            $restaurantIntervalStartDate = $this->calculateIntervalStartDate($restaurantMaxIntervalLimitation);

            // Count the redeems within the restaurant interval
            $redeemCountRestaurant = RedeemRestaurant::where('manage_restaurants_xid', $restaurant->id)
                ->where('is_redeem', 1)
                ->where('iam_principal_xid', $customerIamId)
                ->count();

            if ($redeemCountRestaurant >= $restaurantMaxLimitation) {
                return jsonResponseWithDataErrorMessageApi(__('limitexceed'), ('You have reached the maximum limit for redeeming vouchers.'));
            }

            // Get the last redeem time
            $lastRedeem = RedeemRestaurant::where('iam_principal_xid', $customerIamId)
                ->where('state_xid', $restaurant->state_xid)
                ->where('is_redeem', 1)
                ->orderBy('redeem_date', 'desc')
                ->first();

            $restTime = RestaurantTimeInterval::select('time_hours')->where('manage_restaurants_xid', $restaurant->id)->first();
            $stateTime = TimeInterval::select('time_hours')->where('manage_state_xid', $restaurant->state_xid)->first();

            $restTimeHours = $restTime ? $restTime->time_hours : 0;
            $stateTimeHours = $stateTime ? $stateTime->time_hours : 0;



            if ($lastRedeem) {
                $lastRedeemTime = Carbon::parse($lastRedeem->redeem_date);
                $currentTime = Carbon::now();

                $stateAllowedRedeemTime = $lastRedeemTime->copy()->addHours(intval($stateTimeHours));
                $restAllowedRedeemTime = $lastRedeemTime->copy()->addHours(intval($restTimeHours));

                if ($currentTime < $stateAllowedRedeemTime) {
                    $remainingTime = $currentTime->diff($stateAllowedRedeemTime);
                    $hours = $remainingTime->h;
                    $minutes = $remainingTime->i;
                    return jsonResponseWithDataErrorMessageApi(__('limitexceed'), ('Please wait before redeeming the next voucher.' . " {$hours} hours and {$minutes} minutes remaining."));
                }

                if ($currentTime < $restAllowedRedeemTime) {
                    $remainingTime = $currentTime->diff($restAllowedRedeemTime);
                    $hours = $remainingTime->h;
                    $minutes = $remainingTime->i;
                    return jsonResponseWithDataErrorMessageApi(__('limitexceed'), ('Please wait before redeeming the next voucher.' . " {$hours} hours and {$minutes} minutes remaining."));
                }
            }



            // Create a new redeem entry if it doesn't exist
            $redeemRestaurant = new RedeemRestaurant();
            $redeemRestaurant->iam_principal_xid = $customerIamId;
            $redeemRestaurant->manage_restaurants_xid = $restaurant->id;
            $redeemRestaurant->state_xid = $restaurant->state_xid;
            $redeemRestaurant->is_redeem = 1; // Redeem restaurant
            $redeemRestaurant->redeem_date = now();
            $redeemRestaurant->is_redeemption_undone = 0;
            $redeemRestaurant->redeemption_undone_date = null;
            $redeemRestaurant->save();

            $imagePath = ListingImageUrl('restaurant_images', $restaurant->image);

            $customerTitle = "Your Redemption was successful for " . $restaurant->name;
            $customerMessage = $restaurant->name . " Voucher Redeemed Successfully";
            $customerContentType = 'Voucher_Redemption';
            $customerImageUrl = $imagePath;

            $customerData = IamPrincipal::where('id', $customerIamId)
                ->where('notification_status', 1)
                ->where('principal_type_xid', 3)
                ->first();

            $restaurants = IamPrincipalRestaurantRole::select('id', 'principal_xid')
                ->where('restaurant_xid', $restaurant->id)
                ->get();

            foreach ($restaurants as $restaurantRole) {
                $restUser = IamPrincipal::where('id', $restaurantRole->principal_xid)
                    ->where('notification_status', 1)
                    ->where('principal_type_xid', 4)
                    ->first();

                if ($restUser) {
                    $restImagePath = ListingImageUrl('restaurant_images', $restaurant->image);
                    $restTitle = "New redemption for " . $restaurant->name;
                    $restMessage = $restaurant->name . " new voucher Redeemed Successfully";
                    $restContent_type = 'Voucher_Redemption';
                    $restImageUrl = $restImagePath;

                    // Sending notification to restaurant
                    onesignalhelper::restSendNotificationApi(
                        $restUser->one_signal_player_id,
                        $restTitle,
                        $restMessage,
                        $restContent_type,
                        $restImageUrl,
                        $id = null
                    );
                    onesignalhelper::StoreNotificationDetails($restUser->id, $restContent_type, $restTitle, $restImageUrl);
                }
            }

            if ($customerData) {
                // Sending notification to customer
                onesignalhelper::sendNotificationApi(
                    $customerData->one_signal_player_id,
                    $customerTitle,
                    $customerMessage,
                    $customerContentType,
                    $customerImageUrl,
                    $id = null
                );
                onesignalhelper::StoreNotificationDetails($customerData->id, $customerContentType, $customerTitle, $customerImageUrl);
            }

            return jsonResponseWithSuccessMessageApi(__('success.restaurant_redeem'), $redeemRestaurant, 200);
        } catch (Exception $ex) {
            Log::error('Restaurant Redeem service failed: ' . $ex->getMessage());
            return jsonResponseWithErrorMessageApi(__('auth.something_went_wrong'), 500);
        }
    }

    private function calculateIntervalStartDate($interval)
    {
        $now = Carbon::now();

        switch ($interval) {
            case 'day':
                return $now->copy()->subDay();
            case 'week':
                return $now->copy()->subWeek();
            case 'month':
            default:
                return $now->copy()->subMonth();
        }
    }



    public function searchRestaurant($customerIamId, $request)
    {
        try {
            $restaurantsQuery = ManageRestaurant::with('state', 'closedRestaurant')
                ->where('is_active', '1');

            $searchData = $request->input('search_data');

            if (!empty($searchData)) {
                $restaurantsQuery->where(function ($query) use ($searchData) {
                    $query->where('name', 'like', "%$searchData%")
                        ->orWhere('description', 'like', "%$searchData%")
                        ->orWhere('address', 'like', "%$searchData%")
                        ->orWhereHas('state', function ($stateQuery) use ($searchData) {
                            $stateQuery->where('name', 'like', "%$searchData%");
                        });
                });
            }

            $restaurants = $restaurantsQuery->get();

            foreach ($restaurants as &$restaurant) {
                $restaurant['image'] = ListingImageUrl('restaurant_images', $restaurant['image']);

                $isFavourite = CustomerFavouriteRestaurant::where('principal_xid', $customerIamId)
                    ->where('restaurant_xid', $restaurant['id'])
                    ->exists();
                $restaurant['is_favourite'] = $isFavourite;

                $data = getOperatingHours($restaurant->name, $restaurant->address);

                $restaurant['operating_hours'] = $data['operating_hours'];
                $restaurant['is_restaurant_open_now_as_per_google'] = $data['is_open_now'];
            }

            return jsonResponseWithSuccessMessageApi(__('auth.restaurant_search'), $restaurants, 200);
        } catch (Exception $ex) {
            Log::error('Search restaurant service failed: ' . $ex->getMessage());
            return response()->json([
                'message' => __('auth.something_went_wrong')
            ], 500);
        }
    }
}
