<?php

namespace Modules\Order\Repositories;

use Illuminate\Http\Request;
use Mcamara\LaravelLocalization\Facades\LaravelLocalization;
use Modules\Order\Interfaces\OrderRepositoryInterface;
use Modules\Order\Models\Order;
use Modules\Order\Models\OrderProduct;
use Modules\Order\Services\CartService;
use Modules\Product\Models\ProductAttribute;
use Modules\User\Services\AccountService;

class OrderRepository implements OrderRepositoryInterface
{
    private CartService $cartService;
    private AccountService $accountService;

    public function __construct(CartService $cartService , AccountService $accountService)
    {
        $this->cartService = $cartService;
        $this->accountService = $accountService;
    }

    public function get(Request $request)
    {
        $query = Order::orderBy('id', 'DESC');
        if ($request->id)
        {
            $query->where('id',$request->id);
        }
        if ($request->type)
        {
            $query->where('status',$request->type);
        }
        if ($request->user)
        {
            $query->where(function ($queryData) use ($request){
                $queryData->whereHas('user', function ($q) use ($request){
                    $q->where('name','LIKE', '%'.$request->user.'%');
                });
            })->orWhere(function ($queryData) use ($request){
                $queryData->whereHas('visitor', function ($q) use ($request){
                    $q->where('name','LIKE', '%'.$request->user.'%');
                });
            });
        }
        if ($request->branch)
        {
            $query->whereHas('branch',function ($q) use ($request){
                $q->where('name', $request->branch);
            });
        }
        if ($request->store)
        {
            $query->whereHas('store',function ($q) use ($request){
                $q->where('name', $request->store);
            });
        }
        if($request->ids)
        {
            $query->whereIn('orders.id',$request->ids);
        }
        if ($request->user_id)
        {
            $query->where('user_id',$request->user_id);
        }
        if ($request->user_status)
        {
            $query->where('user_status',$request->user_status);
        }
        if ($request->date_from) {
            $query->whereDate('orders.created_at', '>=', $request->date_from);
        }

        if ($request->date_to) {
            $query->whereDate('orders.created_at', '<=', $request->date_to);
        }


        if ( !is_null($request->status) && $request->status == 0) {
            $query->onlyTrashed();
        }

        if ($request->paginate ?? null) {
            $orders= $query->paginate(50);
        }else{
            $orders=$query->cursor();
        }

        return $orders;
    }

    public function getItem(Order $order)
    {
        return $order ;
    }

    //
    public function create(Request $request): Order
    {
        $data= $request->all();
        unset($data['id']);// for security reasons
        $order = Order::create($data);
        $this->saveData( $request, $order->id );
        return $order;
    }
    public function update(Request $request,Order $order): Order
    {
        $order->update($request->all());
        return $order;
    }

    private function saveData(Request $request, int $order_id ) :void
    {
        $account = $this->accountService->getAccount();
        $request->merge(['status'=>$account['status'],'user_id'=>$account['user']->id]);
        $carts = $this->cartService->get($request);
        foreach ($carts as $row) {
            $data=[
                'count'=> $row->count,
                'product_id'=> $row->product_id,
                'product_cost'=>$row->product->price,
                'total'=> $row->product->price * $row->count,
                'main_attribute_id'=>$row->main_attribute_id ?? null,
                'sub_attribute_id'=>$row->sub_attribute_id ?? null,
                'order_id'=> $order_id,
            ];
            OrderProduct::create($data);
        }
    }

    /**
     * Remove the specified client from storage.
     * @param Request $request
     * @param int $id
     * @return array
     * @throws Exception
     */
    public function destroy(Request $request, int $id) :array
    {
        $city= Order::withTrashed()->find($id);
        if ($city) {
            if ($city->deleted_at) {
                $city->forceDelete();
            } else {
                $city->delete();
            }
            return [ ['message'=> __('dashboard.deletedDone')]];
        } else{
            return [ ['message'=> __('dashboard.noResult')], 400];
        }
    }

    /**
     * Remove several clients by IDs.
     *
     * @param Request $request
     * @return array
     */
    public function destroyAll(Request $request) :array
    {
        $ids= $request->ids;
        $query= Order::whereIn('id', $ids);
        if ($request->force) {
            $deleted= $query->onlyTrashed()->forceDelete();
        } else {
            $deleted= $query->delete();
        }
        if($deleted){
            return [['message'=> __('dashboard.deletedDone')]];
        }
        return [ ['message'=> __('dashboard.noResult')], 400];
    }

    /**
     * Restore the specified client from storage.
     *
     * @param Request $request
     * @param int $id
     * @return array
     */
    public function restore(Request $request, int $id) :array
    {
        $city= Order::withTrashed()->find($id);
        if ($city) {
            $city->restore();
            return [['message'=> __('dashboard.saveDone')]];
        }
        return [['message'=> __('dashboard.noResult')], 400];

    }

    /**
     * Restore several clients by IDs.
     *
     * @param Request $request
     * @return array
     */
    public function restoreAll(Request $request) :array
    {
        $ids= $request->ids;
        Order::whereIn('id', $ids)->onlyTrashed()->restore();
        return [['message'=> __('dashboard.saveDone')]];
    }

    public function getItemByToken(string $token)
    {
        $order = Order::onlyTrashed()->where('token',$token)->first();
        return $order;
    }
    public function orderProductCount(Order $order)
    {
        $products = OrderProduct::where('order_id',$order->id)->cursor();
        foreach ($products as $row)
        {
            if ($row->sub_attribute_id)
            {
                $attr = ProductAttribute::where('product_id',$row->product_id)->where('attribute_id',$row->sub_attribute_id)->where('main_attribute_id','!=',null)->first();
                $attr->update([
                    'count'=>($attr->count - $row->count)
                ]);
            }
            else
            {
                $row->product->update([
                    'count'=>($row->product->count - $row->count)
                ]);
            }
        }
    }
}
