<?php

namespace App\Http\Controllers\Web;

use App\Http\Requests\Web\LocationOrderRequest;
use App\Http\Requests\Web\OrderCheckOutMethodRequest;
use App\Models\Country;
use App\Models\Address;
use App\Models\Cobon;
use App\Models\ShippingCity;
use App\Models\Way;
use App\Models\Installment;
use App\Models\Order;
use App\Models\OrderAddress;
use App\Models\OrderPayment;
use App\Models\OrderProduct;
use App\Models\OrderShipping;
use App\Models\Product;
use App\Models\ProductAttributeChoice;
use App\Models\Shipping;
use App\Services\Currency\CurrencyService;
use App\Services\Auth\User\AccountService;
use App\Services\Notification\NotificationService;
use App\Services\Product\Cart\CartService;
use App\Services\Product\Order\OrderService;
use App\Services\Product\Tax\TaxService;
use App\Services\Response\ResponseService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use Illuminate\View\View;

use App\Http\Controllers\Controller;

class OrderController extends Controller
{
    private $view = 'web.pages.orders.';

    public function orderDetails($token)
    {
        $title = __('web.order_details');
        $order = Order::where('token',$token)->firstOrFail();
        $products = OrderProduct::where('order_id',$order->id)->cursor();
        return view($this->view.'order_details', get_defined_vars());
    }

    public function checkoutLocation()
    {
        $cart_check = (new CartService())->checkAvailable();
        if($cart_check)
        {
            session()->flash('error',$cart_check);
            return redirect()->back();
        }

        $title = __('web.checkout_location');
        $carts = (new CartService())->carts()['data'];

        if(count($carts) == 0)
        {
            session()->flash('error',__('web.cart_empty'));
            return redirect()->route('product.carts');
        }
        $user = (new AccountService())->getAccount();
        $status = $user['status'];
        $user = $user['user'];
        $countries = Country::withDescription()->cursor();
        $locations = Address::where('status',$status)->where('user_id',$user->id)->cursor();
        return view($this->view.'checkout_locations', get_defined_vars());
    }

    public function checkoutingLocation(LocationOrderRequest $request)
    {
        $cart_check = (new CartService())->checkAvailable();
        if($cart_check)
        {
            return ResponseService::responseFail([$cart_check]);
        }
        $user = (new AccountService())->getAccount();
        $status = $user['status'];
        $user = $user['user'];

        if($request->status == 'new')
        {
            if($status == 'visitor')
            {
                $user->update([
                    'name' => $request->name,
                    'email' => $request->email,
                    'phone' => $request->phone,
                ]);
            }
            $address = Address::create([
                'country_id'=>$request->country_id,
                'city_id'=>$request->city_id,
                'status'=>$status,
                'address'=>$request->address,
                'user_id'=>$user->id,
            ]);
            $location_id = $address->id;
        }
        else
        {
            $location_id = $request->location_id;
        }

        Session::put(['location_id'=>$location_id]);
        $response =
            [
                'status' => 200,
                'message' => __('web.success'),
                'data' => route('checkout.method'),
            ];
        return ResponseService::response($response);
    }

    public function checkoutMethod()
    {
        $cart_check = (new CartService())->checkAvailable();
        if($cart_check)
        {
            session()->flash('error',$cart_check);
            return redirect()->back();
        }
        $user = (new AccountService())->getAccount();

        $status = $user['status'];
        $user = $user['user'];
        if($user->role != 'company')
        {
            $location_id = Session::get('location_id');
            if(!$location_id)
            {
                return redirect()->route('checkout.location');
            }
        }
        else
        {
            if($user->active_account != 'active')
            {
                session()->flash('error',__('web.wait_management_order'));
                return redirect()->back();
            }
        }
        $title = __('web.checkout_method');
        if($user->role == 'company')
        {
            $back_action = route('product.carts');
        }
        else
        {
            $back_action = route('checkout.location');
        }
        $user = (new AccountService())->getAccount();
        $status = $user['status'];
        $user = $user['user'];

        $shippings = Shipping::withDescription()->cursor();
        $ways = Way::withDescription()->find([4,5,6]);
        $installments = Way::withDescription()->find([1,3]);
        return view($this->view.'checkout_methods', get_defined_vars());
    }

    public function checkoutingMethod(OrderCheckOutMethodRequest $request)
    {
        $cart_check = (new CartService())->checkAvailable();
        if($cart_check)
        {
            return ResponseService::responseFail([$cart_check]);
        }
        Session::put(
            [
                'order_shipping_status' => $request->status,
                'installment_id' => $request->installment_id,
                'shipping_status' => $request->shipping_status,
                'shipping_id' => $request->shipping_id,
                'policy_number' => $request->policy_number,
                'representative_name' => $request->representative_name,
            ]);

        $response =
            [
                'status' => 200,
                'message' => __('web.success'),
                'data' => route('checkout.payment'),
            ];
        return ResponseService::response($response);
    }

    public function checkoutPayment()
    {
        $user = (new AccountService())->getAccount();
        $status = $user['status'];
        $user = $user['user'];
        
        $location_id = Session::get('location_id');
        $order_shipping_status = Session::get('order_shipping_status');
        if($user->role != 'company')
        {
            
            if(!$location_id)
            {
                return redirect()->route('checkout.location');
                
            }
        }

        if(!$order_shipping_status)
        {
            return redirect()->route('checkout.method');
        }

        $title = __('web.checkout_payment');

        $user = (new AccountService())->getAccount();
        $status = $user['status'];
        $user = $user['user'];


        $date = date('Y ');
        $date .= __('web.'.date('F'));
        $date .= date(' d ');

        
        if($user->role == 'company')
        {
            $shipping_method = __('web.'.Session::get('shipping_status'));
        }
        else
        {
            $location = Address::find($location_id);
            $shipping_id = Session::get('shipping_id');
            $shipping_method = Shipping::withDescription($shipping_id)->first()->name;
            $shipping_city = ShippingCity::where('shipping_id',$shipping_id)->where('city_id',$location->city_id)->first();
            $location = $location->address;
        }
        $cart = new CartService();
        $carts = $cart->carts()['data']['carts'];
        $total = $cart->totalCart();
        $tax = TaxService::tax($total);

        return view($this->view.'checkout_payment', get_defined_vars());
    }

    public function calculate(Request $request)
    {
        $order = new OrderService();
        $requestContent = $request->all();
        $response = $order->calculate($requestContent);
        return $response;
    }
    public function checkoutingPayment(Request $request)
    {
        $cart_check = (new CartService())->checkAvailable();
        if($cart_check)
        {
            return ResponseService::responseFail([$cart_check]);
        }
        $user = (new AccountService())->getAccount();
        $currency = (new CurrencyService())->getCurrency();
        $status = $user['status'];
        $user = $user['user'];
        $token =str_replace(str_split('%\\/:*?"<>|.'), '', bcrypt(rand(11111,99999).time()));

        $order = new OrderService();
        $requestContent = $request->all();
        $calculate_order = $order->calculate($requestContent);
        $location_id = Session::get('location_id');
        $order_shipping_status = Session::get('order_shipping_status');
        $installment_id = Session::get('installment_id');
        $shipping_status = Session::get('shipping_status');
        $shipping_id = Session::get('shipping_id');
        $policy_number = Session::get('policy_number');
        $representative_name = Session::get('representative_name');

        $order = Order::create([
            'user_id'=>$user->id,
            'user_status'=>$status,
            'status'=>'progress',
            'note'=>$request->note,
            'token'=>$token,
        ]);
        
        $payment = OrderPayment::create([
            'order_id' => $order->id,
            'user_status_paid' => $order_shipping_status == 'when_recieving'? 'not' : 'paid',
            'cobon_id' => $calculate_order['cobon_id'],
            'cobon_status' => $calculate_order['cobon_status'],
            'on_hand_payment' => $calculate_order['on_hand_payment'],
            'cobon_discount' => $calculate_order['cobon_total'] / $currency->currency,
            'total_products' => $calculate_order['product_total'] / $currency->currency,
            'total_product_tax' => $calculate_order['total_tax'] / $currency->currency,
            'shipping_cost' => $calculate_order['total_shipping'] / $currency->currency,
            'total' => $calculate_order['total_order'] / $currency->currency,
            'seller_commission' => $calculate_order['seller_commission'],
            'total_commission' => $calculate_order['total_commission'] / $currency->currency,
            'tax_cost' => $calculate_order['total_tax'] / $currency->currency,
            'installment_id' => $installment_id,
            'status' => $order_shipping_status,
        ]);
        if($payment->cobon_id)
        {
            $cobon = Cobon::find($payment->cobon_id);
            $cobon->update(['count'=>$cobon->count - 1]);
        }
            OrderShipping::create([
                'shipping_status'=>$shipping_status,
                'policy_number'=>$policy_number,
                'representative_name'=>$representative_name,
                'order_id'=>$order->id,
                'shipping_id'=>$shipping_id ?? null,
            ]);

        if($location_id)
        {
            OrderAddress::create([
                'order_id'=>$order->id,
                'address_id'=>$location_id
            ]);
        }
        $products = $calculate_order['products'];
        foreach ($products as $product)
        {
            OrderProduct::create([
                'order_id'=>$order->id,
                'count'=>$product['count'],
                'total'=>$product['product_total'] / $currency->currency,
                'product_cost'=>( $product['product_total'] - $product['tax'] - $product['discount'] ) / $currency->currency,
                'tax'=>$product['tax'] / $currency->currency,
                'product_id'=>$product['product_id'],
                'choice_id'=>$product['choice_id'],
                'seller_commission' => $product['seller_commission'] ?? 0,
                'total_commission' => $product['total_commission'] ? $product['total_commission'] / $currency->currency : 0,
            ]);
        }
        Session::forget('location_id');
        Session::forget('order_shipping_status');
        Session::forget('installment_id');
        Session::forget('shipping_status');
        Session::forget('shipping_id');
        Session::forget('policy_number');
        Session::forget('representative_name');
        (new CartService())->deleteAllCarts();
        $response = [
            'status'=>200,
            'message'=>__('web.success'),
            'data'=> 
            [
                'url' => Auth::user() ? route('profile') : route('home'),
                'order_id' => $order->id
            ],
        ];
        $order_products = OrderProduct::where('order_id',$order->id)->get();
        foreach ($order_products as $product)
        {
            if($product->choice_id)
            {
                $choice = ProductAttributeChoice::find($product->choice_id);
                $choice->update(['count'=>($choice->count - $product->count)]);
            }
            else
            {
                $choice = Product::find($product->product_id);
                $choice->update(['count'=>($choice->count - $product->count)]);
            }
        }
        // if($status != 'visitor')
        // {
        //     (new NotificationService)->sendNotification($order->status,$order->user_id,$order->id);
        // }
        return ResponseService::response($response);
    }

}
