<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\Cart;
use App\Models\Notification;
use App\Models\Order;
use App\Models\OrderCancelRequest;
use App\Models\OrderProduct;
use App\Models\OrderProductsDelivery;
use App\Models\ProductTranslation;
use App\Models\User;
use App\Models\UserAuthLogin;
use App\Models\UserPayment;
use App\Models\UserWallet;
use DB;
use Illuminate\Http\Request;

class OrdersAPIController extends Controller
{
    private $language;

    protected $num_per_page = '10';

    public function __construct(Request $request)
    {
        parent::__construct();
        $this->request = $request;
        $this->language = $request->header('lang-code') && $request->header('lang-code') != '' ? $request->header('lang-code') : 'en';
    }

    public function list(Request $request)
    {
        $user_id = 0;
        if ($request->userAuthData) {
            $user_id = $request->userAuthData->user_id;
        }
        $orders = Order::where('user_id', $user_id)->with('product_orders')->with('order_status')->with('cancel_request')->orderBy('id', 'DESC')->get();
        foreach ($orders as $row) {
            foreach ($row->product_orders as $prow) {
                if ($prow->product) {
                    $translated_data = ProductTranslation::where('lang_code', $this->language)->where('product_id', $prow->product_id)->first();
                    if ($translated_data) {
                        if ($translated_data->name != '') {
                            $prow->product->name = $translated_data->name;
                        }
                        if ($translated_data->description != '') {
                            $prow->product->description = $translated_data->description;
                        }
                    }
                }
            }
        }

        return response()->json($orders);
        // return $this->sendResponse($orders, 'Orders retrieved successfully');
    }

    public function pendingList($token)
    {
        $user_id = DB::table('user_auth_login')->where('api_token', $token)->first()->user_id;
        $data = [];

        $a = ['driver_id' => $user_id, 'order_status' => 'Order Received'];

        $orders = DB::table('order')->where($a)->get();

        foreach ($orders as $n_o) {
            $user_name = DB::table('users')->where('id', $n_o->user_id)->first()->name;
            $new_data = ['order_id' => $n_o->id,
                'no_of_bottles' => $n_o->no_of_bottles,
                'customer_id' => $n_o->user_id,
                'user_name' => $user_name];
            $data[] = $new_data;
        }

        return response()->json($data);
    }

     public function customerOrderList($token)
    {
        
        $user_id  = DB::table('user_auth_login')->where('api_token',$token)->first()->user_id;
        $data = [];
        if($user_id > 0)
        {

            try
            {

                $orders = DB::table('order')->where('user_id',$user_id)->get();

        foreach ($orders as $n_o) {
            $new_data = ['order_id' => $n_o->id,
                'no_of_bottles' => $n_o->no_of_bottles,
                'status' => $n_o->order_status];
            $data[] = $new_data;
        }

            return response()->json($data);
            }
            catch (\Exception $e) {
    
                Log::error('Exception: ' . $e->getMessage());
                return response()->json(['error' => 'error in fetching orders'], 500);
            }
            
        }
        else
        {
            return $this->sendResponse('Unauthorised Entry');
        }
    }

    public function historyList($token)
    {
        $user_id = DB::table('user_auth_login')->where('api_token', $token)->first()->user_id;
        $data = [];

        $a = ['driver_id' => $user_id, 'order_status' => 'Delivered'];

        $orders = DB::table('order')->where($a)->get();

        foreach ($orders as $n_o) {
            $user_name = DB::table('users')->where('id', $n_o->user_id)->first()->name;
            $new_data = ['order_id' => $n_o->id,
                'no_of_bottles' => $n_o->no_of_bottles,
                'customer_id' => $n_o->user_id,
                'user_name' => $user_name];
            $data[] = $new_data;
        }

        return response()->json($data);
    }

    public function statusUpdate($id, $token, $status, Request $request)
    {

        $driver = DB::table('user_auth_login')->where('api_token', $token)->get();
        if (count($driver) > 0) {

            DB::table('order')->where('id', $id)->update(['order_status' => $status]);
            $data = 'success,status updated';

            return response()->json($data);
        } else {
            $data = 'unauthorised user error';

            return response()->json($data);
        }

    }

     public function details($id, $token, Request $request)
    {

        $driver = DB::table('user_auth_login')->where('api_token', $token)->get();
        if (count($driver) > 0) {
            $data = $this->getOrderDetails($id);

            return response()->json($data);
        } else {
            $data = 'unauthorised user error';

            return response()->json($data);
        }

    }

     public function deliveryLocationUpdate(Request $request)
 {
       
        $token = $request->input('token');

       $user_id  = DB::table('user_auth_login')->where('api_token',$token)->first()->user_id;
        $data = [];
        if($user_id > 0)
        {

            try
            {
                $emirates = $request->input('emirates');
                $area     = $request->input('area');
                $building = $request->input('building');
                $flat_no  = $request->input('flat_no');

                $update = array('emirates' => $request->input('emirates'),
                               'area' => $request->input('area'),
                               'building' => $request->input('building'),
                               'flat_no' => $request->input('flat_no'),
                           );
                DB::table('users')->where('id',$user_id)->update($update);
              
              return response()->json(['success' => 'location updated successfully'], 200);

            }
            catch (\Exception $e) {
    
                Log::error('Exception: ' . $e->getMessage());
                return response()->json(['error' => 'error in location updation'], 500);
            }

            

        }
        else
        {
            return response()->json(['error' => 'Unauthorised user'], 500);
        }

    }




    public function customerOrderDetails(Request $request)
    {
        $orderId = $request->input('order_id');
        $token = $request->input('token');

       $user_id  = DB::table('user_auth_login')->where('api_token',$token)->first()->user_id;
        $data = [];
        if($user_id > 0)
        {

            try
            {
                $order = DB::table('order')->where('id',$orderId)->get();
            foreach($order as $or)
            {
                
                if($or->driver_id != 0)
                {
                    $driver = DB::table('users')->where('id',$or->driver_id)->first()->name;
                    $assigned_date = date('d-M-Y',$or->assigned_date);
                }
                else
                {
                    $driver = 'Not Assigned';
                    $assigned_date = 'Not Assigned';
                }
                if($or->delivered_date != null)
                {
                    $delivered_date = date('d-M-Y',$or->delivered_date);
                }
                else
                {
                    $delivered_date = 'Not Delivered';
                }

                
                $data = ['status' => $or->order_status,
                         'order_date' => date('d-M-Y',$or->order_date),
                         'no_of_bottles' => $or->no_of_bottles,
                         'payment_type' => $or->payment_type,
                         'driver' => $driver,
                         'assigned_date' => $assigned_date,
                         'delivered_date' => $delivered_date,
                         'order_id' => $or->id,

                     ];

                

                return response()->json($data);

            }

            }
            catch (\Exception $e) {
    
                return response()->json(['error' => 'error in fetching order details'], 500);
            }

            

        }
        else
        {
            return response()->json(['error' => 'Unauthorised user'], 500);
        }

    }

    private function getOrderDetails($id)
    {
        $order = DB::table('order')->where('id', $id)->get();

        foreach ($order as $o) {
            $user = DB::table('users')->where('id', $o->user_id)->get();
            foreach ($user as $u) {
                $user_name = $u->name;
                $phone = $u->phone;

                if ($u->area != null) {
                    $area = DB::table('areas')->where('id', $u->area)->first()->name;
                } else {
                    $area = 'not specified';
                }

                if ($u->emirates != null) {
                    $emirates = DB::table('emirates')->where('id', $u->emirates)->first()->name;
                } else {
                    $emirates = 'not specified';
                }

                $building = $u->building;
                $flat = $u->flat_no;
            }
            $data = ['order_id' => $o->id,
                'no_of_bottles' => $o->no_of_bottles,
                'order_date' => date('d-M-Y', $o->order_date),
                'order_date' => date('d-M-Y', $o->delivered_date),
                'order_status' => $o->order_status,
                'payment_type' => $o->payment_type,
                'assigned_date' => date('d-M-Y', $o->assigned_date),
                'customer_id' => $o->user_id,
                'user_name' => $user_name,
                'emirates' => $emirates,
                'area' => $area,
                'building' => $building,
                'flat' => $flat];
        }

        return $data;
    }

    public function placeOrder(Request $request)
    {
        $payment = $request->only('payment');
        if (isset($payment['payment']) && $payment['payment']['method']) {
            if ($payment['payment']['method'] == 'cash' || $payment['payment']['method'] == 'wallet') {
                return $this->cashPayment($request);
            } else {
                return $this->cashPayment($request);
            }
        }
    }

    private function cashPayment(Request $request)
    {
        $input = $request->all();
        $amount = 0;
        $user_id = 0;
        if ($request->userAuthData) {
            $user_id = $request->userAuthData->user_id;
        }
        if (! $user_id) {
            return $this->sendError('User not found', 401);
        }
        try {
            if ($input['payment']['method'] == 'wallet') {
                $total_wallet = UserWallet::getWalletbalance($user_id);
                if ($total_wallet < $input['final_amount']) {
                    return $this->sendError("You don't have sufficient wallet amount to purchase the order", 401);
                }
            }

            $orderPostData = $request->only('timeslot_id', 'order_status_id', 'tax', 'delivery_address_id', 'delivery_fee', 'is_coupon_applied', 'coupon_code', 'promotional_disount', 'subtotal', 'final_amount');
            $orderPostData['user_id'] = $user_id;
            $orderPostData['payment_method'] = $input['payment']['method'];
            $orderPostData['created_at'] = date('Y-m-d H:i:s');
            $orderId = Order::insertGetId($orderPostData);
            $amount = 0;
            $cartData = Cart::where('user_id', $user_id)->with('product')->get();
            foreach ($cartData as $cart) {
                if ($cart->product) {
                    $inject = [
                        'user_id' => $user_id,
                        'order_id' => $orderId,
                        'product_id' => $cart->product_id,
                        'quantity' => $cart->quantity,
                        'per_item_amount' => $cart->per_item_amount,
                        'per_delivery_amount' => $cart->per_delivery_amount,
                        'total_delivery_amount' => $cart->total_delivery_amount,
                        'no_of_delivery' => $cart->no_of_delivery,
                        'order_frequency' => $cart->order_frequency,
                        'start_date' => $cart->start_date,
                        'end_date' => $cart->end_date,
                        'days' => $cart->days,
                        'created_at' => date('Y-m-d H:i:s'),
                    ];
                    $orderitemId = OrderProduct::insertGetId($inject);
                    $delivery_dates = explode(',', $cart->delivery_dates);
                    foreach ($delivery_dates as $r) {
                        $delivery = [
                            'user_id' => $user_id,
                            'order_id' => $orderId,
                            'product_id' => $cart->product_id,
                            'product_order_id' => $orderitemId,
                            'delivery_date' => date('Y-m-d', strtotime($r)),
                            'order_status_id' => $orderPostData['order_status_id'],
                            'created_at' => date('Y-m-d H:i:s'),
                        ];
                        OrderProductsDelivery::insert($delivery);
                    }
                }
            }

            $paymentid = UserPayment::insertGetId([
                'user_id' => $orderPostData['user_id'],
                'description' => 'Waiting for Client',
                'price' => $orderPostData['final_amount'],
                'status' => 'Waiting for Client',
                'method' => $input['payment']['method'],
                'created_at' => date('Y-m-d H:i:s'),
            ]);

            Order::where('id', $orderId)->update(['payment_id' => $paymentid, 'updated_at' => date('Y-m-d H:i:s')]);

            if ($input['payment']['method'] == 'wallet') {
                $wallet = [
                    'user_id' => $user_id,
                    'order_id' => $orderId,
                    'type' => 'debit',
                    'amount' => -$input['final_amount'],
                    'description' => 'We have debit '.\Helpers::currency($input['final_amount']).' form your wallet for new purchase.',
                    'created_at' => date('Y-m-d H:i:s'),
                ];
                UserWallet::insertGetId($wallet);
            }
            Cart::where('user_id', $user_id)->delete();
            $order = $this->getOrderDetails($orderId, $user_id);

            $key = setting('fcm_key');

            $tokens = [];
            $users = UserAuthLogin::where('user_id', $user_id)->get();
            if (count($users) > 0) {
                foreach ($users as $row) {
                    if ($row->device_token != null) {
                        array_push($tokens, $row->device_token);
                    }
                }
            }
            \Helpers::sendNotification($tokens, 'Order Place successfully.', 'Order Placed', $key);

            $notificationPost = [
                'user_id' => $user_id,
                'lang_code' => 'en',
                'title' => 'Order Placed',
                'message' => 'Order Place successfully.',
                'created_at' => date('Y-m-d H:i:s'),
                'read_status' => 0,
            ];
            Notification::insert($notificationPost);

            //TODO Send Email to admin and Notification to the user if needed
        } catch (ValidatorException $e) {
            return $this->sendError($e->getMessage());
        }

        return $this->sendResponse($order, __('lang.saved_successfully', ['operator' => __('Order')]));
    }

    public function orderCancelRequest($id, Request $request)
    {
        $user_id = 0;
        if ($request->userAuthData) {
            $user_id = $request->userAuthData->user_id;
        }
        $orders = $this->getOrderDetails($id, $user_id);

        $postData = [
            'order_id' => $id,
            'user_id' => $user_id,
            'refund_amount' => 0,
            'refund_status' => 0,
            'status' => 0,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s'),
        ];

        $data = Order::find($id);
        if ($data->payment_method != 'cash') {
            $totalWalletAmount = 0;
            $productsDelivery = OrderProductsDelivery::where('order_status_id', '<', 5)->where('delivery_date', '>=', date('Y-m-d'))->where('order_id', $id)->with('product_orders')->get();
            foreach ($productsDelivery as $row) {
                if ($row->product_orders) {
                    $totalWalletAmount = $totalWalletAmount + $row->product_orders->per_delivery_amount;
                }
            }
            $postData['refund_amount'] = $totalWalletAmount;
        }

        OrderCancelRequest::insertGetId($postData);

        return $this->sendResponse([], __('lang.alert_cancel_order_request_submited'));
    }

    public function getDriverAssignedOrderList(Request $request)
    {
        $user_id = 0;
        if ($request->userAuthData) {
            $user_id = $request->userAuthData->user_id;
        }
        $input = $request->all();
        $this->num_per_page = (isset($post['perpage'])) ? $post['perpage'] : $this->num_per_page;

        if (isset($input['type']) && $input['type'] == 'past') {
            $productsDelivery = OrderProductsDelivery::where('order_status_id', 5)->where('driver_id', $user_id)->with('product_orders')->with('delivery_status')->with('user')->with('order')->paginate($this->num_per_page)->appends('perpage', $this->num_per_page);
        } else {
            $productsDelivery = OrderProductsDelivery::where('order_status_id', '<', 5)->where('driver_id', $user_id)->with('product_orders')->with('delivery_status')->with('user')->with('order')->paginate($this->num_per_page)->appends('perpage', $this->num_per_page);
        }

        return $this->sendResponse($productsDelivery, 'Record found successfully.');
    }

    public function getDriverAssignedOrderDetail($id, Request $request)
    {
        $user_id = 0;
        if ($request->userAuthData) {
            $user_id = $request->userAuthData->user_id;
        }
        $productsDelivery = OrderProductsDelivery::where('driver_id', $user_id)->where('id', $id)->with('product_orders')->with('delivery_status')->with('user')->with('order')->first();

        return $this->sendResponse($productsDelivery, 'Record found successfully.');
    }

    public function changeOrderStatus($id, Request $request)
    {
        $input = $request->all();
        $user_id = 0;
        if ($request->userAuthData) {
            $user_id = $request->userAuthData->user_id;
        }
        OrderProductsDelivery::where('id', $id)->update(['order_status_id' => $input['order_status_id']]);
        $productsDelivery = OrderProductsDelivery::where('driver_id', $user_id)->where('id', $id)->with('product_orders')->with('delivery_status')->with('user')->with('order')->first();

        return $this->sendResponse($productsDelivery, 'status change successfully.');
    }


    public function createOrder(Request $request)
    {
        $token = $request->input('token');
        $bottles = $request->input('no_of_bottles');
        $user_id  = DB::table('user_auth_login')->where('api_token',$token)->first()->user_id;
        
        if($user_id > 0)
        {

            try
            {
                $bottles = $request->input('no_of_bottles');
            $date = strtotime(date('Y-m-d H:i:s'));

            $data = array('user_id'=>$user_id,
                          'no_of_bottles'=>$bottles,
                          'order_date'=>$date);
            DB::table('order')->insert($data);

            return response()->json('Order Creation Successfull');
            }
            catch (\Exception $e) {
    
                Log::error('Exception: ' . $e->getMessage());
                return response()->json(['error' => 'Order Creation Failed'], 500);
            }
            
        }
        else
        {
            return $this->sendResponse('Unauthorised Entry');
        }


    }

    public function orderStatusList(Request $request)
    {
        $response = [];
        $response = DB::table('order_statuses')->get();

        return $this->sendResponse($response, 'Settings retrieved successfully');
    }
}
