<?php

namespace App\Http\Controllers\API\v1\FamilyMember;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Controllers\API\BaseController as BaseController;
use App\Http\Controllers\API\DefaultController as DefaultController;
use App\Models\Menu;
use App\Models\MenuAddOnCategory;
use App\Models\MenuAddOn;
use App\Models\AssociateEventRestaurant;
use App\Models\Order;
use App\Models\OrderPayment;
use App\Models\OrderMenuItem;
use App\Models\OrderMenuAddOnItem;
use App\Models\OrderInvoice;
use App\Models\User;
use Validator;
use DB, Hash, Mail;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use Illuminate\Support\Str;
use App\Services\DefaultServices;
use App\Services\PaymentGatewayApiServices;
use App\Services\OrderServices;
use Exception;

class OrderController extends Controller
{
    protected $baseController;
    protected $defaultController;
    protected $request;
    protected $defaultServices;
    protected $paymentGatewayApiServices;
    protected $orderServices;

    public function __construct(BaseController $baseController, DefaultServices $defaultServices, DefaultController $defaultController, PaymentGatewayApiServices $paymentGatewayApiServices, OrderServices $orderServices)
    {
        $this->baseController = $baseController;
        $this->defaultController = $defaultController;
        $this->defaultServices  = $defaultServices;
        $this->paymentGatewayApiServices = $paymentGatewayApiServices;
        $this->orderServices = $orderServices;
        $this->middleware('apiTokenVal');
    }

    public function placeOrderSubmission($flag, Request $request)
    {
        $status_code = 0;
        $success = [];                    
        $inputs = $request->all();
        $inputs = $this->defaultServices->getTrimmedValue($inputs);
        $messageArr['input'] = $inputs;
        $userType = 'family-member';

        try 
        {
            $tokenDetails = Auth::user()->token();
            $additionalArr['user_id'] = $user_id = $tokenDetails->user_id;

            if(isset($inputs['dish_items']) && is_string($inputs['dish_items']) && $inputs['dish_items']) {
                $inputs['dish_items'] = json_decode($inputs['dish_items'], true);
            }

            $messages = [
                'restaurant_id.required' => 'Please select restaurant',
                'current_timestamp.required' => 'Please provide current timestamp',
                'pickup_date.required' => 'Please select pickup date',
                'pickup_time.required' => 'Please select pickup time',
                'event_id.required' => 'Please select event',
                'name_on_card.required' => 'Please enter name on card',
                'card_number.required' => 'Please enter card number',
                'expiration.required' => 'Please enter expiry date',
                'cvv.required' => 'Please enter cvv number',
                'dish_items.required' => 'Please add items',                               
            ];

            $validator = Validator::make($inputs, [
                "restaurant_id" => 'required',
                "current_timestamp" => 'required',
                "pickup_date" => 'required',
                "pickup_time" => 'required',
                "event_id" => 'required',
                "name_on_card" => 'required',
                "card_number" => 'required',
                "expiration" => 'required',
                "cvv" => 'required',
                "dish_items" => 'required|array',
                                
            ], $messages);

            if($validator->fails()) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, $validator->errors()->first(), 200, $messageArr, $additionalArr);
                exit(0);
            }

            $pickup_date = date('Y-m-d', strtotime($inputs['pickup_date']));
            $pickup_time = date('H:i:s', strtotime($inputs['pickup_time']));

            $inputs['pickup_datetime'] = date('Y-m-d H:i:s', strtotime("$pickup_date $pickup_time"));
            $inputs['pickup_datetime'] = date('Y-m-d H:i:s', strtotime($inputs['pickup_datetime']));

            if( strtotime($inputs['pickup_datetime']) < $inputs['current_timestamp'] ) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Please select valid pickup date and time', 200, $messageArr, $additionalArr);
                exit(0);
            }

            $associateEventRestaurant = AssociateEventRestaurant::where("event_id", $inputs['event_id'])
                            ->where('restaurant_id', $inputs['restaurant_id'])
                            ->where("is_interest_send_by_admin", 1)
                            ->where("is_confirm_by_restaurant", 1)
                            ->where("is_active", 1)->first();

            if(empty(objectToArray($associateEventRestaurant))) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Restaurant does not associated with event.', 200, $messageArr, $additionalArr);
                exit(0);
            }

            $eventDetails = $associateEventRestaurant->getEvent;
            $restaurantDetails = $associateEventRestaurant->getRestaurant;
            $organizationDetails = $eventDetails->eventCharitableOrganization->first();
            $familyMemberDetails = $organizationDetails->getFamilyMember->where("id", $user_id)->first();

            if(empty(objectToArray($familyMemberDetails))) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Your organization is not associated with this campaign.', 200, $messageArr, $additionalArr);
                exit(0);
            }

            $restaurantAvailabilityDetails = $restaurantDetails->restaurantAvailability->where("event_id", $inputs['event_id'])->where("promotion_date", date("Y-m-d", strtotime($inputs['pickup_datetime'])))->first();

            if(empty(objectToArray($restaurantAvailabilityDetails))) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Restaurant is unable to accept order. Please change pickup date', 200, $messageArr, $additionalArr);
                exit(0);
            }

            $time_status = 0;
            if( strtotime($restaurantAvailabilityDetails->start_time) <= strtotime(date("H:i:s", strtotime($inputs['pickup_datetime']))) && 
                strtotime( $restaurantAvailabilityDetails->end_time) > strtotime(date("H:i:s", strtotime($inputs['pickup_datetime']))) ) {
                $time_status = 1;                
            }

            if(!$time_status) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Restaurant is unable to accept order. Please change pickup time', 200, $messageArr, $additionalArr);
                exit(0);
            }

            $order_items = $inputs['dish_items'];

            $orderArr = $orderMenuItemsArr = $orderItemsArr = [];
            $avgFoodPreparationTime = 0;
            $totalFullFinalPrice = 0;
            $totalFoodBasePrice = 0;
            $totalFoodPrice = 0;
            $totalTaxPrice = 0;
            $taxPercentage = get_setting('order-tax')??0;
            $adminCommission = 0;
            $totalAdminCommissionPrice = 0;

            foreach ($order_items as $key => $items) {

                $menuFilter['restaurant_id'] = $inputs['restaurant_id'];
                $menuFilter['id'] = $items['dish_id'];
                $menuFilter['is_active'] = 1;
                $menuFilter['is_delete'] = 0;

                $menuDetails = Menu::where($menuFilter)->first();

                if(empty(objectToArray($menuDetails))) {
                    return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'No dish found', 200, $messageArr, $additionalArr);
                    exit(0);
                }

                if($menuDetails->final_price != $items['dish_Price']) {
                    return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Item price has been changed', 200, $messageArr, $additionalArr);
                    exit(0);
                }

                //$avgFoodPreparationTime += $menuDetails->food_prep_time*$items['dish_count'];
                if($menuDetails->food_prep_time > $avgFoodPreparationTime) {
                    $avgFoodPreparationTime = $menuDetails->food_prep_time;
                }

                if(empty($orderArr)) {
                    $orderArr['user_id'] = $user_id;
                    $orderArr['restaurant_id'] = $inputs['restaurant_id'];
                    $orderArr['order_ID'] = '';
                    $orderArr['event_id'] = $inputs['event_id'];
                    $orderArr['user_note'] = $inputs['user_note']??'';
                    $orderArr['order_date_time'] = date('Y-m-d H:i:s', $inputs['current_timestamp']);
                    $orderArr['pickup_date_time'] = $inputs['pickup_datetime'];
                    $orderArr['schedule_pickup_time'] = date('H:i:s', strtotime($inputs['pickup_datetime']));
                    $orderArr['avg_food_prep_time'] = 0;
                    $orderArr['is_confirm'] = 0;
                    $orderArr['is_ready_for_pickup'] = 0;
                    $orderArr['is_deliver'] = 0;
                    $orderArr['is_active'] = 1;
                    $orderArr['created_at'] = date('Y-m-d H:i:s');
                    $orderArr['updated_at'] = date('Y-m-d H:i:s');
                }

                if($items['dish_addOn'] && (count($items['dish_addOn']) != $items['dish_count'])) {
                    return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'You have added extra addOn', 200, $messageArr, $additionalArr);
                    exit(0);
                }

                for($dishCount = 0; $dishCount < $items['dish_count']; $dishCount++)
                {
                    $orderMenuItem = [];
                    $orderMenuItem['order_id'] = '';
                    $orderMenuItem['restaurant_id'] = $inputs['restaurant_id'];
                    $orderMenuItem['menu_id'] = $menuDetails->id;
                    $orderMenuItem['has_add_on'] = 0;
                    $orderMenuItem['base_price'] = $menuDetails->price??0;
                    $orderMenuItem['price'] = $menuDetails->final_price??0;
                    $orderMenuItem['quantity'] = 1;
                    $orderMenuItem['total_price'] = $orderMenuItem['quantity']*$orderMenuItem['price'];
                    $orderMenuItem['tax_percentage'] = $taxPercentage;
                    $orderMenuItem['tax_price'] = $this->taxPrice($orderMenuItem['total_price'], $orderMenuItem['tax_percentage'])??0.00;
                    $orderMenuItem['admin_commission'] = $adminCommission = $menuDetails->admin_commission??0;
                    //$orderMenuItem['admin_commission_price'] = $this->adminCommissionPrice($orderMenuItem['base_price'], $orderMenuItem['quantity'], $orderMenuItem['admin_commission'])??0.00;

                    $orderMenuItem['admin_commission_price'] = ($orderMenuItem['price'] - $orderMenuItem['base_price'])*$orderMenuItem['quantity'];
                    $totalFoodBasePrice += $orderMenuItem['base_price'];
                    $totalFoodPrice += $orderMenuItem['total_price'];

                    $orderMenuItem['final_price'] = $this->finalPrice($orderMenuItem['total_price'], $orderMenuItem['tax_percentage'])??0.00;
                    $orderMenuItem['final_price'] = number_format($orderMenuItem['final_price'], 2, '.', '');
                    $orderMenuItem['total_price'] = number_format($orderMenuItem['total_price'], 2, '.', '');
                    $orderMenuItem['is_active'] = 1;
                    $orderMenuItem['created_at'] = date('Y-m-d H:i:s');
                    $orderMenuItem['updated_at'] = date('Y-m-d H:i:s');
                    $orderMenuItem['dish_addOn'] = [];

                    $totalFullFinalPrice += $this->finalPriceCalculation($orderMenuItem['total_price'], $orderMenuItem['tax_percentage'])??0.00; //$orderMenuItem['final_price'];
                    //$totalFoodBasePrice += $orderMenuItem['base_price'];
                    // $totalFoodPrice += $orderMenuItem['total_price'];
                    $totalTaxPrice += $orderMenuItem['tax_price'];
                    $totalAdminCommissionPrice += $orderMenuItem['admin_commission_price'];

                    if(isset($items['dish_addOn'][$dishCount]) && is_array($items['dish_addOn'][$dishCount]) && $items['dish_addOn'][$dishCount])
                    {
                        $orderMenuItem['has_add_on'] = 1;

                        foreach ($items['dish_addOn'][$dishCount] as $key => $addOn_cat) {

                            $menuAddOnCatFilter['menu_id'] = $menuDetails->id;
                            $menuAddOnCatFilter['id'] = $addOn_cat['addon_categoryId'];
                            $menuAddOnCatFilter['is_active'] = 1;
                            $menuAddOnCatFilter['is_delete'] = 0;

                            $menuAddOnCategory = MenuAddOnCategory::where($menuAddOnCatFilter)->first();

                            if(empty(objectToArray($menuAddOnCategory))) {
                                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Dish addOn category not found', 200, $messageArr, $additionalArr);
                                exit(0);
                            }

                            $totalAddOnCount = isset($addOn_cat['addon_items'])&&is_array($addOn_cat['addon_items'])?count($addOn_cat['addon_items']):0;

                            if($totalAddOnCount == 0) {
                                continue;
                            }

                            if($menuAddOnCategory->selection_type == 1 && $totalAddOnCount != 1) {
                                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'You can not add multiple addOn for single selection', 200, $messageArr, $additionalArr);
                                exit(0);
                            }

                            foreach ($addOn_cat['addon_items'] as $key => $addOnItem) {

                                $menuAddOnFilter['restaurant_id'] = $inputs['restaurant_id'];
                                $menuAddOnFilter['id'] = $addOnItem['item_id'];
                                $menuAddOnFilter['menu_id'] = $menuDetails->id;
                                $menuAddOnFilter['menu_add_on_category_id'] = $menuAddOnCategory->id;
                                $menuAddOnFilter['is_active'] = 1;
                                $menuAddOnFilter['is_delete'] = 0;
                                
                                $menuAddOnDetails = MenuAddOn::where($menuAddOnFilter)->first();

                                if(empty(objectToArray($menuAddOnDetails))) {
                                    return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Dish addOn does not found', 200, $messageArr, $additionalArr);
                                    exit(0);
                                }

                                if($menuAddOnDetails->final_price != $addOnItem['item_price']) {
                                    return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Item price has been changed', 200, $messageArr, $additionalArr);
                                    exit(0);
                                }

                                $menuAddOnItem = [];
                                $menuAddOnItem['order_id'] = '';
                                $menuAddOnItem['restaurant_id'] = $inputs['restaurant_id'];
                                $menuAddOnItem['order_menu_item_id'] = '';
                                $menuAddOnItem['menu_id'] = $menuDetails->id;
                                $menuAddOnItem['menu_add_on_category_id'] = $menuAddOnCategory->id;
                                $menuAddOnItem['menu_add_on_id'] = $menuAddOnDetails->id;
                                $menuAddOnItem['base_price'] = $menuAddOnDetails->price??0;
                                $menuAddOnItem['price'] = $menuAddOnDetails->final_price??0;
                                $menuAddOnItem['quantity'] = 1;
                                $menuAddOnItem['total_price'] = $menuAddOnItem['quantity']*$menuAddOnItem['price'];
                                $menuAddOnItem['tax_percentage'] = $taxPercentage; //get_setting('order-tax');
                                $menuAddOnItem['tax_price'] = $this->taxPrice($menuAddOnItem['total_price'], $menuAddOnItem['tax_percentage'])??0.00;
                                $menuAddOnItem['admin_commission'] = $menuAddOnDetails->admin_commission??0;
                                //$menuAddOnItem['admin_commission_price'] = $this->adminCommissionPrice($menuAddOnItem['base_price'], $menuAddOnItem['quantity'], $menuAddOnItem['admin_commission'])??0.00;


                                $menuAddOnItem['admin_commission_price'] = ($menuAddOnItem['price'] - $menuAddOnItem['base_price'])*$menuAddOnItem['quantity'];
                                $totalFoodBasePrice += $menuAddOnItem['base_price'];
                                $totalFoodPrice += $menuAddOnItem['total_price'];


                                $menuAddOnItem['final_price'] = $this->finalPrice($menuAddOnItem['total_price'], $menuAddOnItem['tax_percentage'])??0.00;
                                $menuAddOnItem['final_price'] = number_format($menuAddOnItem['final_price'], 2, '.', '');
                                $menuAddOnItem['total_price'] = number_format($menuAddOnItem['total_price'], 2, '.', '');
                                $menuAddOnItem['is_active'] = 1;
                                $menuAddOnItem['created_at'] = date('Y-m-d H:i:s');
                                $menuAddOnItem['updated_at'] = date('Y-m-d H:i:s');

                                $totalFullFinalPrice += $this->finalPriceCalculation($menuAddOnItem['total_price'], $menuAddOnItem['tax_percentage'])??0.00; //$menuAddOnItem['final_price'];
                                //$totalFoodBasePrice += $menuAddOnItem['base_price'];
                                //$totalFoodPrice += $menuAddOnItem['total_price'];
                                $totalTaxPrice += $menuAddOnItem['tax_price'];
                                $totalAdminCommissionPrice += $menuAddOnItem['admin_commission_price'];

                                array_push($orderMenuItem['dish_addOn'], $menuAddOnItem);                                
                            }
                        }
                    }

                    array_push($orderMenuItemsArr, $orderMenuItem);
                    unset($orderMenuItem);
                }
            }

            $pre_preparation_time = get_setting('pre-preparation-order-time');
            $pre_preparation_time = date('H:i', mktime(0, $pre_preparation_time));
            
            //$avg_preparation_time = $avgFoodPreparationTime/count($orderMenuItemsArr);            
            $avg_preparation_time = date('H:i', mktime(0, $avgFoodPreparationTime));

            $total_pre_preparation_time = strtotime($pre_preparation_time) + strtotime($avg_preparation_time);
            $total_pre_preparation_time = date("H:i", $total_pre_preparation_time);

            $pickup_datetime   = Carbon::parse(date("Y-m-d H:i", strtotime($inputs['pickup_datetime'])));
            $current_timestamp = Carbon::parse(date("Y-m-d H:i", $inputs['current_timestamp']));
            $diff_time = 0;

            $minutes = $pickup_datetime->diffInMinutes($current_timestamp);
            
            if($minutes) {
                $diff_time = date('H:i', mktime(0, $minutes));
            }

            if( strtotime(date("Y-m-d", strtotime($inputs['pickup_datetime']))) == strtotime(date('Y-m-d', $inputs['current_timestamp']))
                && ( strtotime($diff_time) < strtotime($total_pre_preparation_time)) ) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Please select another pickup time.', 200, $messageArr, $additionalArr);
                            exit(0);
            }

            $totalTaxPrice = $this->taxPrice($totalFoodPrice, $taxPercentage);
            $totalFullFinalPrice = $totalFoodPrice + $totalTaxPrice;
            
            //$totalFullFinalPrice = number_format($totalFullFinalPrice, 2, '.', '');
            $totalFoodPrice = number_format($totalFoodPrice, 2, '.', '');
            $totalTaxPrice = number_format($totalTaxPrice, 2, '.', '');
            $totalAdminCommissionPrice = number_format($totalAdminCommissionPrice, 2, '.', '');

            $totalFullFinalPrice = strval($totalFullFinalPrice);
            $inputs['final_price'] = strval($inputs['final_price']);

            if($inputs['final_price'] != $totalFullFinalPrice && true) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Mismatch final price', 200, $messageArr, $additionalArr);
                            exit(0);
            }

            $totalFullFinalPrice = floatval($totalFullFinalPrice);
            $inputs['final_price'] = floatval($inputs['final_price']);

            // order storing process --------------

            // order
            $orderDetails = Order::create($orderArr);

            $orderDetails->avg_food_prep_time = $avg_preparation_time;
            $orderDetails->order_ID = "ORD".$orderDetails->id;
            $orderDetails->save();            

            array_walk ( $orderMenuItemsArr, function (&$key) use($orderDetails) { 
                $key["order_id"] = $orderDetails->id; 
            });

            foreach ($orderMenuItemsArr as $key => $orderMenuItem) {

                $orderMenuItemOnly = $orderMenuItem;

                if(isset($orderMenuItem['dish_addOn'])) {
                    unset($orderMenuItemOnly['dish_addOn']);
                }

                // order menu items
                $orderMenuItemDetails = OrderMenuItem::create($orderMenuItemOnly);

                if(isset($orderMenuItem['dish_addOn']) && $orderMenuItem['dish_addOn']) {
                    array_walk ( $orderMenuItem['dish_addOn'], function (&$key) use($orderDetails, $orderMenuItemDetails) { 
                        $key["order_id"] = $orderDetails->id;
                        $key["order_menu_item_id"] = $orderMenuItemDetails->id;
                    });

                    // order menu addon items
                    OrderMenuAddOnItem::insert($orderMenuItem['dish_addOn']);
                }
            }

            // order invoice
            $orderInvoiceArr['order_id'] = $orderDetails->id;
            $orderInvoiceArr['order_date_time'] = date('Y-m-d H:i:s', $inputs['current_timestamp']);
            $orderInvoiceArr['is_active'] = 1;
            $orderInvoiceArr['is_delete'] = 0;
            $orderInvoiceArr['created_at'] = date('Y-m-d H:i:s');
            $orderInvoiceArr['updated_at'] = date('Y-m-d H:i:s');
            
            $orderInvoiceDetails = OrderInvoice::create($orderInvoiceArr);
            $orderInvoiceDetails->invoice_ID = "INV".$orderInvoiceDetails->id;
            $orderInvoiceDetails->save();

            // order payment            
            $orderPaymentArr['user_id'] = $user_id;
            $orderPaymentArr['order_id'] = $orderDetails->id;
            $orderPaymentArr['date_time'] = date('Y-m-d H:i:s', $inputs['current_timestamp']);
            $orderPaymentArr['total_base_price'] = $totalFoodBasePrice??0;
            $orderPaymentArr['total_price'] = $totalFoodPrice??0;
            $orderPaymentArr['tax_percentage'] = $taxPercentage??0;
            $orderPaymentArr['total_tax_price'] = $totalTaxPrice??0;
            $orderPaymentArr['admin_commission'] = $adminCommission??0;
            $orderPaymentArr['total_admin_commission_price'] = $totalAdminCommissionPrice??0;
            $orderPaymentArr['final_price'] = $totalFullFinalPrice??0;
            $orderPaymentArr['is_active'] = 1;
            $orderPaymentArr['is_delete'] = 0;
            $orderPaymentArr['created_at'] = date('Y-m-d H:i:s');
            $orderPaymentArr['updated_at'] = date('Y-m-d H:i:s');
            
            $orderPaymentDetails = OrderPayment::create($orderPaymentArr);

            $totalFullFinalPriceInCent = $totalFullFinalPrice*100;
            $totalFullFinalPriceInCent = round($totalFullFinalPriceInCent);

            $totalTaxPriceInCent = $totalTaxPrice*100;
            $totalTaxPriceInCent = round($totalTaxPriceInCent);

            // end order storing process --------------
            // payment gateway API --------------------
            $data = [
                    'type' => 'sale',
                    'amount' => $totalFullFinalPriceInCent??0,
                    "tax_amount" => $totalTaxPriceInCent??0,
                    'currency' => 'USD',
                    'order_id' => (string)$orderDetails->id,
                    'ip_address' => '4.2.2.2',
                    'email_receipt' => true,
                    'email_address' => 'sabyasachi@digitalaptech.com', //'testdevloper007@gmail.com',
                    'create_vault_record' => true,
                    'payment_method' => 
                        array (
                            'card' => 
                                array (
                                  'entry_type' => 'keyed',
                                  'number' => str_replace(" ", "", $inputs['card_number']),
                                  'expiration_date' => str_replace('\\', '', $inputs['expiration']),
                                  'cvc' => $inputs['cvv'],
                                ),
                        ),
                    'billing_address' => 
                    array (
                    'first_name' => $familyMemberDetails->name,
                    'last_name' => '',
                    'company' => '',
                    'address_line_1' => $familyMemberDetails->userProfile->address??'',
                    'city' => '',
                    'state' => '', //$familyMemberDetails->userProfile->state??'',
                    'postal_code' => '', //$familyMemberDetails->userProfile->zip_code??'',
                    'country' => '', //$familyMemberDetails->userProfile->country??'',
                    'phone' => $familyMemberDetails->phone??'',
                    'fax' => '',
                    'email' => $familyMemberDetails->email??'',
                    ),
                ];

            $beneficiaries_url ='https://sandbox.gotnpgateway.com/api/transaction';
            $data_string = json_encode($data);
            $responseData = $this->paymentGatewayApiServices->makePayment($data_string, $beneficiaries_url);

            $orderPaymentDetails->gateway_response = $responseData;
            $orderPaymentDetails->save();

            $decode_result = json_decode($responseData);
            $payment_status = 0;

            if($decode_result->status == 'failed') {
                $payment_status = 2;  // Error invalid card number / expiration
            }
            else if($decode_result->status == "success" && $decode_result->data->response == "approved") {
                $payment_status = 1;
            }
            else if($decode_result->status == "success" && $decode_result->data->response == "declined") {
                $payment_status = 3;
            }

            $orderPaymentDetails->payment_status = $payment_status;
            $orderPaymentDetails->save();
            
            if($decode_result->status == 'failed') {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Please enter valid card details', 200, $messageArr, $additionalArr);
                exit(0);                                
            }

            $orderPaymentDetails->transaction_id = $decode_result->data->id??NULL;
            $orderPaymentDetails->payment_mode = $decode_result->data->response_body->card->type??NULL;
            $orderPaymentDetails->card_number = $decode_result->data->response_body->card->last_four??NULL;
            $orderPaymentDetails->name_on_card = $inputs['name_on_card']??NULL;
            $orderPaymentDetails->save();

            if($payment_status != 1) {
                    return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Payment issue, please try again later', 200, $messageArr, $additionalArr);
                exit(0);
            }

            // end payment gateway API -----------------
            
            $status_code = 1;
            return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'Order placed successfully', 200, $messageArr, $additionalArr);

        } catch (Exception $e) { 
            $messageArr = [];           
            return $this->baseController->sendFamilyMemberResponse(0, [], $e->getMessage(), 200, $messageArr);
        }
    }

    public function finalPrice($total_price, $tax_percentage)
    {
        $final_price = $total_price*(100+$tax_percentage)/100;
        $final_price = round(ceil($final_price*100)/100, 2);

        return $final_price;
    }

    public function finalPriceCalculation($total_price, $tax_percentage) 
    {
        $full_final_price = $total_price*(100+$tax_percentage)/100;
        $full_final_price = round(ceil($full_final_price*100)/100, 2);
        return $full_final_price;
    }

    public function taxPrice($total_price, $tax_percentage)
    {
        $tax_price = $total_price*($tax_percentage)/100;
        $tax_price = round(ceil($tax_price*100)/100, 2);

        return $tax_price;
    }

    public function adminCommissionPrice($base_price, $quantity, $admin_commission)
    {
        $price = $base_price*$admin_commission*$quantity/100;
        $price = round(ceil($price*100)/100, 2);

        return $price;
    }

    public function getOrderList($flag, Request $request)
    {
        $status_code = 0;
        $success = [];                    
        $inputs = $request->all();
        $inputs = $this->defaultServices->getTrimmedValue($inputs);
        $messageArr['input'] = $inputs;
        $userType = 'family-member';

        try
        {
            $tokenDetails = Auth::user()->token();
            $additionalArr['user_id'] = $user_id = $tokenDetails->user_id;

            $messages = [
                'order_type.required' => 'Please provide order type',
                'page_size.required' => 'Please enter limit',
                'page_count.required' => 'Please enter offset',
                'device_type.required' => 'Please enter device type',
                'current_timestamp.required' => "Please provide timestamp",               
            ];

            $validator = Validator::make($inputs,[
                "order_type" => 'required|in:upcoming,history',
                "page_size" => 'required|numeric',
                "page_count" => 'required|numeric',
                "current_timestamp" => 'required',
                "device_type" => 'required',
            ], $messages);

            if($validator->fails()) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, $validator->errors()->first(), 200, $messageArr, $additionalArr);
                exit(0);
            }

            $userDetails = User::with([
                            'userAssociateCharitableOrganization.getCharitableOrganization',
                            'userRoles'
                        ])
                        ->where('id', $user_id)
                        ->first();

            if(empty(objectToArray($userDetails))) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'User doesn\'t exist', 200, $messageArr, $additionalArr);
                exit(0);
            }

            $filters = [];
            $orderList = $this->orderServices->orderListByUser($user_id, $inputs['current_timestamp'], $inputs['order_type'], $filters);

            $success['total_count'] = $orderList->count();
            $success['order_list'] = [];

            $limit  = ($inputs['page_size'] <= 0) ? 10 : $inputs['page_size'];
            $offset = ($inputs['page_count'] <= 0) ? 1 : $inputs['page_count'];
            $offset = ($limit * $offset) - $limit;

            $allOrders = $orderList->offset($offset)->limit($limit)->get();
            $status_code = 1;

            if(empty(objectToArray($allOrders))) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, "No order has been found.", 200, $messageArr, $additionalArr);
                exit(0);
            }

            foreach ($allOrders as $key => $order) {
                $orderArr['order_id'] = $order->id??0;
                $orderArr['order_ID'] = $order->order_ID??'';
                $orderArr['order_date'] = date("jS F, Y", strtotime($order->order_date_time))?:'';
                $orderArr['order_time'] = date("H:i", strtotime($order->order_date_time))?:'';
                $orderArr['order_value'] = floatval($order->getPayment->final_price)?:0;

                $orderArr['order_items'] = $list = [];
                $orderMenuItems = $order->getOrderMenuItems;

                if(empty(objectToArray($orderMenuItems))) {
                    continue;
                }

                $orderMenuItems = $orderMenuItems->values();

                foreach ($orderMenuItems as $key => $orderMenuItem) {
                    $menuDetails = $orderMenuItem->getMenuItemDetails;

                    $list = [];
                    $list['dish_id'] = $menuDetails->id??'';
                    $list['dish_name'] = $menuDetails->name??'';
                    $list['dish_count'] = $orderMenuItem->quantity??0;

                    if(isset($orderArr['order_items'][$menuDetails->id])) {
                        $orderArr['order_items'][$menuDetails->id]['dish_count'] += $list['dish_count'];
                    }
                    else {                        
                        $orderArr['order_items'][$menuDetails->id] = $list;
                    }
                }

                $orderArr['order_items'] = array_values($orderArr['order_items']);

                array_push($success['order_list'], $orderArr);                             
            }

            $this->defaultController->device_token($inputs, $tokenDetails->user_id, 1);

            return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'success', 200, $messageArr, $additionalArr);

        } catch (Exception $e) { 
            $messageArr = [];           
            return $this->baseController->sendFamilyMemberResponse(0, [], $e->getMessage(), 200, $messageArr);
        }
    }

    public function getOrderDetails($flag, Request $request)
    {
        $status_code = 0;
        $success = [];                    
        $inputs = $request->all();
        $inputs = $this->defaultServices->getTrimmedValue($inputs);
        $messageArr['input'] = $inputs;
        $userType = 'family-member';

        try
        {
            $tokenDetails = Auth::user()->token();
            $additionalArr['user_id'] = $user_id = $tokenDetails->user_id;

            $messages = [
                'order_type.required' => 'Please provide order type',
                'order_id.required' => 'Please enter limit',
                'device_type.required' => 'Please enter device type',               
            ];

            $validator = Validator::make($inputs,[
                "order_type" => 'required|in:upcoming,history',
                "order_id" => 'required|numeric',
                "device_type" => 'required',
            ], $messages);

            if($validator->fails()) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, $validator->errors()->first(), 200, $messageArr, $additionalArr);
                exit(0);
            }

            $userDetails = User::with([
                            'userAssociateCharitableOrganization.getCharitableOrganization',
                            'userRoles'
                        ])
                        ->where('id', $user_id)
                        ->first();

            if(empty(objectToArray($userDetails))) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'User doesn\'t exist', 200, $messageArr, $additionalArr);
                exit(0);
            }

            $filters['id'] = $inputs['order_id'];
            $filters['user_id'] = $user_id;
            $filters['is_active'] = 1;

            $orderDetails = Order::with(["getRestaurant", "getPayment"])
                    ->whereHas('getPayment', function ($query) {
                        $query->where([                            
                            ['payment_status', '=', '1'],                            
                        ]);
                    })
                    ->where($filters)->first();

            if(empty(objectToArray($orderDetails))) {
                return $this->baseController->sendFamilyMemberResponse($status_code, $success, "No order has been found.", 200, $messageArr, $additionalArr);
                exit(0);
            }

            $orderArr['order_id'] = $orderDetails->id??0;
            $orderArr['user_name'] = $orderDetails->getFamilyMember->name??'';
            $orderArr['order_date'] = date("jS F, Y", strtotime($orderDetails->order_date_time))?:'';
            $orderArr['order_time'] = date("H:i", strtotime($orderDetails->order_date_time))?:'';
            $orderArr['event_id'] = $orderDetails->event_id??0;
            $orderArr['event_ID'] = $orderDetails->getEvent->event_ID??'';
            $orderArr['subtotal'] = floatval($orderDetails->getPayment->total_price)?:0;
            $orderArr['tax'] = floatval($orderDetails->getPayment->total_tax_price)?:0;
            $orderArr['total'] = floatval($orderDetails->getPayment->final_price)?:0;
            $orderArr['restaurant_name'] = $orderDetails->getRestaurant->restaurant_name??'';
            $orderArr['pickup_address'] = $orderDetails->getRestaurant->address??'';
            $orderArr['pickup_lattitude'] = $orderDetails->getRestaurant->latitude??'';
            $orderArr['pickup_longitude'] = $orderDetails->getRestaurant->longitude??'';

            $orderArr['organisation_type'] = '';
            $orderArr['organisation_id'] = 0;
            $orderArr['organisation_unique_number'] = '';

            if(isset($orderDetails->getEvent->eventAssociateCharitableOrganization->getCharitableOrganization) && objectToArray($orderDetails->getEvent->eventAssociateCharitableOrganization->getCharitableOrganization))
            {
                $organizationDetails = $orderDetails->getEvent->eventAssociateCharitableOrganization->getCharitableOrganization;

                $orderArr['organisation_type'] = $organizationDetails->is_school==1?"School":"Organisation";
                $orderArr['organisation_id'] = $organizationDetails->id??0;
                $orderArr['organisation_unique_number'] = $organizationDetails->organization_ID??'';
            }
            
            $orderArr['schedule_pickupDate'] = date("jS F, Y", strtotime($orderDetails->pickup_date_time))?:'';
            $orderArr['schedule_pickupTime'] = date("H:i", strtotime($orderDetails->pickup_date_time))?:'';            
            $orderArr['order_invoicePdf'] = url('/familyMember/restaurant/'.encript_decript_data($orderDetails->restaurant_id, 'encript', 2).'/invoice/order/'.encript_decript_data($orderDetails->id, 'encript', 2));

            $orderArr['actual_pickupDate'] = '';
            $orderArr['actual_pickupTime'] = '';
            $orderArr['fundraiser_amount'] = 0;

            if($inputs['order_type'] == "history")
            {
                $orderArr['actual_pickupDate'] = !is_null($orderDetails->actual_pickup_date_time)&&$orderDetails->actual_pickup_date_time?date("jS F, Y", strtotime($orderDetails->actual_pickup_date_time)):'';
                $orderArr['actual_pickupTime'] = !is_null($orderDetails->actual_pickup_date_time)&&$orderDetails->actual_pickup_date_time?date("H:i", strtotime($orderDetails->actual_pickup_date_time)):'';

                $eventDetails = $orderDetails->getEvent;

                $assoEventRestuarantDetails = $eventDetails->eventAssociateRestaurant
                                                ->where("restaurant_id", $orderDetails->restaurant_id)
                                                ->where("is_interest_send_by_admin", 1)
                                                ->where("is_confirm_by_restaurant", 1)
                                                ->where("is_active", 1)->first();

                if(objectToArray($assoEventRestuarantDetails)) {
                    $discount_rate = $assoEventRestuarantDetails->discount_rate??0;
                    $discount_amount = ($orderArr['subtotal']*$discount_rate)/100;
                    $discount_amount = number_format($discount_amount, 2, '.', '');
                    $orderArr['fundraiser_amount'] = floatval($discount_amount)?:0;
                }
            }

            $success = [];
            $orderArr['order_items'] = $list = [];
            $orderMenuItems = $orderDetails->getOrderMenuItems;

            if(objectToArray($orderMenuItems)) {
                $orderMenuItems = $orderMenuItems->values();

                foreach ($orderMenuItems as $key => $orderMenuItem) {
                    $menuDetails = $orderMenuItem->getMenuItemDetails;

                    $list = [];
                    $list['dish_id'] = $menuDetails->id??'';
                    $list['dish_name'] = $menuDetails->name??'';
                    $list['dish_count'] = $orderMenuItem->quantity??0;
                    $list['dish_price'] = floatval($menuDetails->final_price)?:0.00;
                    $list['dish_addOns'] = [];
                    $menuAddOnArr = [];

                    if($orderMenuItem->has_add_on == 1) {
                        $menuAddOnItems = $orderMenuItem->getOrderMenuAddOnItems;
                        
                        if(objectToArray($menuAddOnItems)) {
                            foreach ($menuAddOnItems as $key => $menuAddOnItem) {
                                $menuAddOnDetails = $menuAddOnItem->getMenuAddOnItemDetails;
                                $menuAddOnList['addonId'] = $menuAddOnDetails->id??0;
                                $menuAddOnList['addonName'] = $menuAddOnDetails->name??'';
                                $menuAddOnList['addonPrice'] = floatval($menuAddOnDetails->final_price)?:0;

                                $menuAddOnArr[] = $menuAddOnList;       
                            }                            
                        }
                    }

                    if(isset($orderArr['order_items'][$menuDetails->id])) {
                        $orderArr['order_items'][$menuDetails->id]['dish_count'] += $list['dish_count'];
                        $orderArr['order_items'][$menuDetails->id]['dish_addOns'][] = $menuAddOnArr;
                    }
                    else {
                        array_push($list['dish_addOns'], $menuAddOnArr);
                        $orderArr['order_items'][$menuDetails->id] = $list;
                    }
                }

                $orderArr['order_items'] = array_values($orderArr['order_items']);                             
            }

            $success = $orderArr??[];

            $orderArr['order_items'] = ($inputs['order_type'] == "history")?:[];
            $this->defaultController->device_token($inputs, $tokenDetails->user_id, 1);

            $status_code = 1;
            return $this->baseController->sendFamilyMemberResponse($status_code, $success, 'success', 200, $messageArr, $additionalArr);

        } catch (Exception $e) { 
            $messageArr = [];           
            return $this->baseController->sendFamilyMemberResponse(0, [], $e->getMessage(), 200, $messageArr);
        }
    }

}
