<?php

namespace App\Http\Controllers;

use App\DataTables\CancelOrderDataTable;
use App\DataTables\CompleteOrderDataTable;
use App\DataTables\InProgressOrderDataTable;
use App\DataTables\OrderDataTable;
use App\DataTables\PeddingOrderDataTable;
use App\DataTables\StoreOrderDataTable;
use App\DataTables\StoreOwnerOrderDataTable;
use App\DataTables\TodayOrderDataTable;
use Illuminate\Http\Request;
use App\Models\Order;
use App\Models\AppSetting;
use App\Models\Vehicle;
use App\Http\Requests\orderRequest;
use App\Models\Notification;
use App\Models\Payment;
use App\Models\Setting;
use App\Models\StaticData;
use App\Models\User;
use App\Models\City;
use App\Models\Country;
use App\Models\OrderItemMapping;
use App\Models\Document;
use App\Models\Store;
use App\Models\StoreItem;
use Barryvdh\DomPDF\Facade\Pdf;
use App\Traits\OrderTrait;
use App\Traits\PaymentTrait;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class OrderController extends Controller
{
    use OrderTrait, PaymentTrait;
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(OrderDataTable $dataTable)
    {
        $pageTitle = __('message.list_form_title', ['form' => __('message.order')]);
        $auth_user = authSession();
        $assets = ['datatable'];
        $params = null;
        $params = [
            'status' => request('status') ?? null,
            'from_date' => request('from_date') ?? null,
            'to_date' => request('to_date') ?? null,
            'created_at' => request('created_at') ?? null,
            'city_id' => request('city_id') ?? null,
            'country_id' => request('country_id') ?? null,
        ];

        $reset_file_button = '<a href="' . route('order.index') . '" class=" mr-1 mt-0 mb-1 btn btn-sm btn-info text-dark mt-1 pt-1 pb-1"><i class="ri-repeat-line" style="font-size:12px"></i> ' . __('message.reset_filter') . '</a>';
        $filter_file_button = '<a href="' . route('filter.order.data', $params) . '" class="float-right mr-1 mt-1 btn btn-sm btn-success  text-dark loadRemoteModel"><i class="fas fa-filter"></i> ' . __('message.filter') . '</a>';
        $multi_checkbox_delete = $auth_user->can('order-delete') ? '<button id="deleteSelectedBtn" checked-title = "order-checked " class="float-left btn btn-sm ">' . __('message.delete_selected') . '</button>' : '';

        return $dataTable->render('global.order-filter', compact('pageTitle', 'auth_user', 'multi_checkbox_delete', 'params', 'reset_file_button', 'filter_file_button'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        $staticData = StaticData::get();
        $pageTitle = __('message.add_form_title', ['form' => __('message.order')]);
        $assets = ['phone', 'contact_nbr','location'];

        return view('order.form', compact('pageTitle', 'assets', 'staticData'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */

    public function store(Request $request)
    {
        $data = $request->all();

        $orderItems = $data['order_item'] ?? null;
        unset($data['order_item']);
        $data['date'] = now();

        if ($request->has('vehicle_id') && $request->input('vehicle_id') != null) {
            $data['vehicle_data'] = Vehicle::where('id', $request->input('vehicle_id'))->first() ?? null;
        }
        if (!$request->is('api/*')) {
            $extraCharges = $request->input('extra_charges');
            if ($extraCharges) {
                $extraCharges = json_decode($extraCharges, true);
                if (is_array($extraCharges)) {
                    $formattedCharges = [];
                    foreach ($extraCharges as $charge) {
                        if (isset($charge['title'], $charge['charges'], $charge['charges_type'])) {
                            $chargeEntry = [
                                'key' => $charge['title'],
                                'value' => $charge['charges'],
                                'value_type' => $charge['charges_type']
                            ];
                            $formattedCharges[] = $chargeEntry;
                        }
                    }
                    $data['extra_charges'] =$formattedCharges;
                }
            }
        }

        $result = Order::updateOrCreate(['id' => $request->id], $data);
        if ($orderItems !== null && is_array($orderItems)) {
            $result->storeItem()->delete();

            foreach ($orderItems as $item) {
                $orderItem = [
                    'order_id'      => $result->id,
                    'amount'        => $item['amount'],
                    'product_id'    => $item['product_id'],
                    'quantity'      => $item['quantity'],
                    'total_amount'  => $item['quantity'] * $item['amount'],
                ];
                $result->storeItem()->create($orderItem);
            }
        }

        $ordersmapp = [
            'id' => null,
            'order_id' => $result->id,
            'product_id' => json_encode($request->product_id),
            'city_id' => $request->city_id,
            'product_price' => $request->product_price,
            'total_price' => $request->total_price,
            'discount_price' => $request->discount_price,
            'extra_charges' => json_encode($request->extra_charges, true),
        ];
        OrderItemMapping::create($ordersmapp);

        $message = __('message.update_form', ['form' => __('message.order')]);
        if ($result->wasRecentlyCreated) {
            $message = __('message.save_form', ['form' => __('message.order')]);
        }

        if ($request->has('save_user_address') && $request->save_user_address == 1) {
            $user_pickup_address_data = $result->pickup_point;
            $user_pickup_address_data['user_id'] = $result->client_id;
            $user_pickup_address_data['country_id'] = $result->country_id;
            $user_pickup_address_data['city_id'] = $result->city_id;

            $result->saveUserAddress()->create($user_pickup_address_data);

            $user_delivery_address_data = $result->delivery_point;
            $user_delivery_address_data['user_id'] = $result->client_id;
            $user_delivery_address_data['country_id'] = $result->country_id;
            $user_delivery_address_data['city_id'] = $result->city_id;

            $result->saveUserAddress()->create($user_delivery_address_data);
        }
        if($result->parent_order_id != null){
            $history_data = [
                'history_type' => 'return',
                'parent_order_id' =>$result->parent_order_id,
                'order_id' =>$result->parent_order_id,
                'order' => $result,
            ];
                saveOrderHistory($history_data);
            }

            $history_data = [
                'history_type' => $result->status,
                'order_id' => $result->id,
                'order' => $result,
            ];
            saveOrderHistory($history_data);

        if ($result->status == 'create') {
            $app_setting = AppSetting::first();
            if (isset($app_setting) && $app_setting->auto_assign == 1) {
                $this->autoAssignOrder($result, $request->all());
            }
            if ($result->pickup_point['contact_number'] != null) {
                $this->sendTwilioSMS($result);
            }
        }
        if ($request->is('api/*')) {
            $response = [
                'order_id' => $result->id,
                'message' => $message
            ];
            return json_custom_response($response);
        }
        return redirect()->route('order.index')->withSuccess($message);
    }


    public function autoAssignCancelOrder(Request $request)
    {
        $order_data = Order::find($request->id);

        $result = $this->autoAssignOrder($order_data, $request->all());

        $message = __('message.updated');
        if ($result->delivery_man_id == null) {
            $message = __('message.save_form', ['form' => __('message.order')]);
        }
        if ($request->is('api/*')) {
            $response = [
                'order_id' => $result->id,
                'message' => $message
            ];
            return json_custom_response($response);
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $pageTitle = __('message.add_form_title', ['form' => __('message.order')]);
        $data = order::withTrashed()->findOrFail($id);
        $complate_data = order::withTrashed()->where('parent_order_id',$data->id)->first();
        $storeorder = StoreItem::where('order_id',$id)->with('product')->get();

        return view('order.show', compact('data','storeorder','complate_data'));
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $assets = ['phone', 'contact_nbr','location'];
        $staticData = StaticData::get();
        $pageTitle = __('message.update_form_title', ['form' => __('message.order')]);
        $data = order::findOrFail($id);

        return view('order.form', compact('data', 'pageTitle', 'id', 'staticData', 'assets'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        $order = Order::findOrFail($id);

        $old_status = $order->status;

        try {
            DB::beginTransaction();

            $order->fill($request->all())->update();

            $payment = Payment::where('order_id', $id)->first();
            // dd($payment);

            if ($payment != null && $payment->payment_status == 'paid' && $order->status == 'completed') {
                $this->walletTransactionCompleted($order->id);
            }
            if ($order->status == 'cancelled') {
                $this->walletTransactionCancelled($order->id);
            }
            DB::commit();
        } catch (\Exception $e) {
            DB::rollBack();
            // \Log::info('error-'.$e);
            return json_custom_response($e);
        }

        uploadMediaFile($order, $request->pickup_time_signature, 'pickup_time_signature');
        uploadMediaFile($order, $request->delivery_time_signature, 'delivery_time_signature');
        $message = __('message.update_form', ['form' => __('message.order')]);


        if (in_array(request('status'), ['delayed', 'cancelled', 'failed'])) {
            $history_data = [
                'history_type' => request('status'),
                'order_id' => $id,
                'order' => $order,
            ];

            saveOrderHistory($history_data);
        }

        if (in_array(request('status'), ['courier_picked_up', 'courier_arrived', 'completed', 'courier_departed'])) {
            $history_data = [
                'history_type' => request('status'),
                'order_id' => $id,
                'order' => $order,
            ];

            saveOrderHistory($history_data);
        }

        if ($request->is('api/*')) {
            return json_message_response($message);
        }
        return redirect()->route('draft-order')->with($message);
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        if(env('APP_DEMO')){
            $message = __('message.demo_permission_denied');
            if(request()->ajax()) {
                return response()->json(['status' => false, 'message' => $message, 'event' => 'validation']);
            }
            return redirect()->route('order.index')->withErrors($message);
        }
        $order = order::find($id);
        $status = 'error';
        $message = __('message.not_found_entry', ['name' => __('message.order')]);

        if ($order != '') {
            $order->delete();
            $status = 'success';
            $message = __('message.delete_form', ['form' => __('message.order')]);
        }

        if (request()->is('api/*')) {
            return response()->json(['status' => true, 'message' => $message]);
        }
        if (request()->ajax()) {
            return response()->json(['status' => true, 'message' => $message]);
        }

        return redirect()->back()->with($status, $message);
    }

    public function action(Request $request)
    {
        $id = $request->id;
        $order = Order::withTrashed()->where('id', $id)->first();

        $message = __('message.not_found_entry', ['name' => __('message.order')]);
        if ($request->type === 'restore') {
            $order->restore();
            $message = __('message.msg_restored', ['name' => __('message.order')]);
        }

        if ($request->type === 'forcedelete') {
            $order->forceDelete();
            $search = "id" . '":' . $id;
            Notification::where('data', 'like', "%{$search}%")->delete();
            $message = __('message.msg_forcedelete', ['name' => __('message.order')]);
        }

        if ($request->type == 'courier_assigned') {
            if ($order->delivery_man_id != null) {
                $message = __('message.couriertransfer');
                $history_type = 'courier_transfer';
                $data['assign_datetime'] = now();
            } else {
                $message = __('message.courierassigned');
                $history_type = 'courier_assigned';
                $data['assign_datetime'] = now();
            }

            $assignorder = Order::updateOrCreate(['id' => $request->id], $data);
            $order->update(['delivery_man_id' => $request->delivery_man_id, 'status' => $request->status]);
            $history_data = [
                'history_type' => $history_type,
                'order_id' => $id,
                'order' => $order,
            ];

            saveOrderHistory($history_data);
        }

        if ($request->type == 'courier_departed') {
            $order->update(['status' => $request->status]);
            $history_data = [
                'history_type' => 'courier_departed',
                'order_id' => $id,
                'order' => $order,
            ];

            saveOrderHistory($history_data);
        }

        if ($request->type == 'completed') {
            $order->update(['status' => $request->type]);
            $history_data = [
                'history_type' => 'completed',
                'order_id' => $id,
                'order' => $order,
            ];

            saveOrderHistory($history_data);
        }

        if (request()->is('api/*')) {
            return response()->json(['status' => true, 'message' => $message]);
        }

        if($order->store_detail_id == null){
            return redirect()->route('order.index')->withSuccess($message);
        }else{
            return redirect()->route('store-order-list')->withSuccess($message);
        }
    }

    public function InvoicePdf($id)
    {
        $order = Order::find($id);
        $today = Carbon::now()->format('d/m/Y');

        $companyName = Setting::where('type', 'order_invoice')->where('key', 'company_name')->first();
        $companynumber = Setting::where('type', 'order_invoice')->where('key', 'company_contact_number')->first();
        $companyAddress = Setting::where('type', 'order_invoice')->where('key', 'company_address')->first();
        $invoice = Setting::where('type', 'order_invoice')->where('key', 'company_logo')->first();
        $pdf = Pdf::loadView('order.invoice', compact('invoice','companyName', 'companyAddress', 'companynumber', 'order', 'today'), [
        ]);
        return $pdf->download('invoice_' . $order->id . '.pdf');
    }

    public function ApiInvoicePdf($id)
    {
        $order = Order::find($id);
        $today = Carbon::now()->format('d/m/Y');

        $companyName = Setting::where('type', 'order_invoice')->where('key', 'company_name')->first();
        $companynumber = Setting::where('type', 'order_invoice')->where('key', 'company_contact_number')->first();
        $companyAddress = Setting::where('type', 'order_invoice')->where('key', 'company_address')->first();
        $invoice = Setting::where('type', 'order_invoice')->where('key', 'company_logo')->first();
        $pdf = Pdf::loadView('order.invoice', compact('invoice','companyName', 'companyAddress', 'companynumber', 'order', 'today'), [
        ]);
        return $pdf->stream('invoice_' . $order->id . '.pdf');
    }

    public function assign($id)
    {
        $order = Order::find($id);
            $deliveryMenQuery = User::where('city_id', $order->city_id)
            ->where('status', 1)
            ->where('user_type', 'delivery_man')
            ->where(function ($query) {
                $query->whereNotNull('email_verified_at')
                    ->whereNotNull('otp_verify_at')
                    ->whereNotNull('document_verified_at');
            });
            $deliveryMen = $deliveryMenQuery->get();

        $pageTitle = __('message.assign_order');
        return view('order.assgin', compact('pageTitle', 'deliveryMen', 'id', 'order'));
    }
    public function filterOrder()
    {
        $pageTitle = __('message.order_filter');
        $params = null;

        $params = [
            'status' => request('status') ?? null,
            'from_date' => request('from_date') ?? null,
            'to_date' => request('to_date') ?? null,
            'created_at' => request('created_at') ?? null,
            'city_id' => request('city_id') ?? null,
            'country_id' => request('country_id') ?? null,
        ];
        if (!isset($params['city_id'])) {
            $params['city_id'] = null;
        }
        if (!isset($params['country_id'])) {
            $params['country_id'] = null;
        }
        $selectedCityId = request('city_id');
        $cities = City::pluck('name', 'id')->prepend(__('message.select_name', ['select' => __('message.city')]), '')->toArray();
        $selectedCountryId = request('country_id');
        $country = Country::pluck('name', 'id')->prepend(__('message.select_name', ['select' => __('message.country')]), '')->toArray();

        return view('global.order-datatable', compact('pageTitle', 'params', 'selectedCityId', 'cities', 'selectedCountryId', 'country'));
    }
    public function storeorderfilterOrder()
    {
        $pageTitle = __('message.order_filter');
        $params = null;

        $params = [
            'status' => request('status') ?? null,
            'from_date' => request('from_date') ?? null,
            'to_date' => request('to_date') ?? null,
            'created_at' => request('created_at') ?? null,
            'city_id' => request('city_id') ?? null,
            'country_id' => request('country_id') ?? null,
        ];
        if (!isset($params['city_id'])) {
            $params['city_id'] = null;
        }
        if (!isset($params['country_id'])) {
            $params['country_id'] = null;
        }
        $selectedCityId = request('city_id');
        $cities = City::pluck('name', 'id')->prepend(__('message.select_name', ['select' => __('message.city')]), '')->toArray();
        $selectedCountryId = request('country_id');
        $country = Country::pluck('name', 'id')->prepend(__('message.select_name', ['select' => __('message.country')]), '')->toArray();

        return view('global.storeorder-datatable', compact('pageTitle', 'params', 'selectedCityId', 'cities', 'selectedCountryId', 'country'));
    }

    public function draftOrder(Request $request)
    {
        $pageTitle = __('message.add_form_title', ['form' => __('message.order')]);

        $client = Auth::user();

        $orderquery = Order::where('client_id', $client->id)
            ->where(function ($query) use ($client, $request) {
                $query->where('city_id', $client->city_id)
                    ->orWhere('city_id', $request->city_id);
            })
            ->where(function ($query) use ($client, $request) {
                $query->where('country_id', $client->country_id)
                    ->orWhere('country_id', $request->country_id);
            })
            ->where('status', 'draft')->orderBy('created_at', 'asc');

        if ($request->filled('city_id')) {
            $orderquery->whereHas('city', function ($query) use ($request) {
                $query->where('id', $request->input('city_id'));
            });
        }

        if ($request->filled('country_id')) {
            $orderquery->whereHas('country', function ($query) use ($request) {
                $query->where('id', $request->input('country_id'));
            });
        }

        // $orderquery->orderBy('created_at', 'desc');
        $orders = $orderquery->get();

        $cityId = $client->city_id;
        $countryId = $client->country_id;

        if ($request->filled('city_id')) {
            $cityId = $request->input('city_id');
        }

        if ($request->filled('country_id')) {
            $countryId = $request->input('country_id');
        }
        if ($cityId != null && $countryId != null) {
            $selectedCity = City::where('id', $cityId)->pluck('name', 'id');
            $selectedCountry = Country::where('id', $countryId)->pluck('name', 'id');
        } else {
            $selectedCity = City::pluck('name', 'id')->prepend('Select City', '');
            $selectedCountry = Country::pluck('name', 'id')->prepend('Select Country', '');
        }

        return view('clientside.draftorder', compact('pageTitle', 'orders', 'selectedCity', 'selectedCountry'));
    }

    public function storeOwnerOrder(Request $request)
    {
        $pageTitle = __('message.add_form_title', ['form' => __('message.order')]);

        $storeOwner = Auth::user();

        $orderquery = Order::where('store_detail_id',$storeOwner->store_detail_id);

        if ($request->filled('city_id')) {
            $orderquery->where('city_id', $request->input('city_id'));
        } else {
            $orderquery->where(function ($query) use ($storeOwner) {
                $query->where('city_id', $storeOwner->city_id)
                    ->orWhereNull('city_id');
            });
        }

        if ($request->filled('country_id')) {
            $orderquery->where('country_id', $request->input('country_id'));
        } else {
            $orderquery->where(function ($query) use ($storeOwner) {
                $query->where('country_id', $storeOwner->country_id)
                    ->orWhereNull('country_id');
            });
        }

        $orders = $orderquery->orderBy('created_at', 'desc')->get();

        $cityId = $storeOwner->city_id;
        $countryId = $storeOwner->country_id;
        if ($cityId != null && $countryId != null) {
            $selectedCity = City::where('id', $cityId)->pluck('name', 'id');
            $selectedCountry = Country::where('id', $countryId)->pluck('name', 'id');
        } else {
            $selectedCity = City::pluck('name', 'id')->prepend('Select City', '');
            $selectedCountry = Country::pluck('name', 'id')->prepend('Select Country', '');
        }

        return view('storeowner-order.form', compact('pageTitle', 'orders', 'selectedCity', 'selectedCountry'));
    }

    public function storeownerOrderlist(StoreOwnerOrderDataTable $dataTable)
    {
        $pageTitle = __('message.list_form_title', ['form' => __('message.order')]);
        $auth_user = authSession();
        $assets = ['datatable'];
        return $dataTable->render('global.orderlistdatatable', compact('pageTitle','auth_user','assets'));
    }

    public function storeorderindex(StoreOrderDataTable $dataTable)
    {
        $pageTitle = __('message.list_form_title', ['form' => __('message.store-order')]);
        $auth_user = authSession();
        $assets = ['datatable'];
        $params = null;
        $params = [
            'status' => request('status') ?? null,
            'from_date' => request('from_date') ?? null,
            'to_date' => request('to_date') ?? null,
            'created_at' => request('created_at') ?? null,
            'city_id' => request('city_id') ?? null,
            'country_id' => request('country_id') ?? null,
        ];

        $reset_file_button = '<a href="' . route('store-order-list') . '" class=" mr-1 mt-0 mb-1 btn btn-sm btn-info text-dark mt-1 pt-1 pb-1"><i class="ri-repeat-line" style="font-size:12px"></i> ' . __('message.reset_filter') . '</a>';
        $filter_file_button = '<a href="' . route('filter.storeorder.data', $params) . '" class="float-right mr-1 mt-1 btn btn-sm btn-success  text-dark loadRemoteModel"><i class="fas fa-filter"></i> ' . __('message.filter') . '</a>';
        $multi_checkbox_delete = $auth_user->can('order-delete') ? '<button id="deleteSelectedBtn" checked-title = "order-checked " class="float-left btn btn-sm ">' . __('message.delete_selected') . '</button>' : '';

        return $dataTable->render('global.order-filter', compact('pageTitle', 'auth_user', 'multi_checkbox_delete', 'params', 'reset_file_button', 'filter_file_button'));
    }
}
