<?php

namespace App\Http\Livewire\Frontend\Checkout;

use App\Models\OrderManagement\Coupon;
use App\Models\PaymentManagement\PaymentMethod;
use App\Models\OrderManagement\ShippingCompany;
use App\Models\LocalizationManagement\Address;
use App\Services\InteractWithCart;
use App\Services\OrderService;
use Gloudemans\Shoppingcart\Facades\Cart;
use Jantinnerezo\LivewireAlert\LivewireAlert;
use Livewire\Component;

class CheckoutComponent extends Component{
    use LivewireAlert, InteractWithCart;

    public $cartSubTotal;
    public $cartTax;
    public $cartTotal;
    public $cartCoupon;
    public $couponCode;
    public $cartShipping;
    public $cartDiscount;
    public $addresses;
    public $userAddressId = 0;
    public $shippingCompanies;
    public $shippingCompanyId = 0;
    public $paymentMethods;
    public $paymentMethodId = -1;
    public $paymentMethodCode;
    public $selectedPaymentMethod = null;
    public $paymentIsRequired = true;
    public $paymentMethodFounded = true;
    public $netPayable = 0;
    public $productsIsAvailable = false;



    protected $listeners = [
        'update_cart' => 'mount'
    ];

    public function mount(){
        $this->addresses = auth(activeGuard())->user()->addresses;
        $this->userAddressId = session()->has('saved_user_address_id') ? session()->get('saved_user_address_id') : '';
        $this->shippingCompanyId = session()->has('saved_shipping_company_id') ? session()->get('saved_shipping_company_id') : '';
        $this->paymentMethodId = session()->has('saved_payment_method_id') ? session()->get('saved_payment_method_id') : '';
        $this->cartSubTotal = getNumbersOfCart()->get('subtotal');
        $this->cartTax = getNumbersOfCart()->get('productTaxes');
        $this->cartDiscount = getNumbersOfCart()->get('discount');
        $this->cartShipping = getNumbersOfCart()->get('shipping');
        $this->cartTotal = getNumbersOfCart()->get('total');

        if ($this->paymentMethodId > 0){
            $this->selectedPaymentMethod = PaymentMethod::find($this->paymentMethodId);
        }

        if ($this->userAddressId == '') {
            $this->shippingCompanies = collect([]);
        } else {
            $this->getShippingCompanies();
        }
        $this->paymentMethods = PaymentMethod::active()->get();

       // dd(auth(activeGuard())->user()->balance,$this->cartTotal);
        $this->paymentIsRequired = (auth(activeGuard())->user()->balance < $this->cartTotal);

        $this->setNetPayable();

        $this->checkStockProducts();

        //dd($this->paymentMethodId);
    }

    public function applyDiscount(){
        if (getNumbersOfCart()) {
            $coupon = Coupon::whereCode($this->couponCode)->active()->first();
            if (!$coupon) {
                $this->couponCode = '';
                $this->alert('error', 'Coupon is invalid');
            }

            if ($coupon->greater_than > getNumbersOfCart()->get('subtotal')) {
                $this->couponCode = '';
                $this->alert('warning', __('Subtotal must greater than :price',['price' => format_amount($coupon->greater_than,true)]));
            }

            $couponValue = $coupon->discount($this->cartSubTotal);
            if ($couponValue < 0) {
                $this->alert('error', 'product coupon is invalid');
            }

            session()->put('coupon', [
                'code' => $coupon->code,
                'value' => $coupon->value,
                'discount' => $couponValue
            ]);

            $this->couponCode = session()->get('coupon')['code'];
            $this->emit('update_cart');
            $this->alert('success', 'Coupon is applied successfully');
        }

        $this->couponCode = '';
        //   $this->alert('error', 'No products available in your cart');
    }

    public function applyDiscountV1(){
        if (getNumbersOfCart()) {
            $coupon = Coupon::whereCode($this->couponCode)->active()->first();
            if (!$coupon) {
                $this->couponCode = '';
                $this->alert('error', 'Coupon is invalid');
            }

            if ($coupon->greater_than > getNumbersOfCart()->get('subtotal')) {
                $this->couponCode = '';
                $this->alert('warning', 'Subtotal must greater than $'. $coupon->greater_than);
            }

            $couponValue = $coupon->discount($this->cartSubTotal);
            if ($couponValue < 0) {
                $this->alert('error', 'product coupon is invalid');
            }

            session()->put('coupon', [
                'code' => $coupon->code,
                'value' => $coupon->value,
                'discount' => $couponValue
            ]);

            $this->couponCode = session()->get('coupon')['code'];
            $this->emit('update_cart');
            $this->alert('success', 'Coupon is applied successfully');
        }

        $this->couponCode = '';
        //$this->alert('error', 'No products available in your cart');
    }

    public function removeCoupon(){
        session()->remove('coupon');
        $this->couponCode = '';
        $this->emit('update_cart');
        $this->alert('success', 'remove coupon successfully');
    }

    public function setNetPayable(){
        $balance = auth(activeGuard())->user()->balance;
        $cartTotal = $this->cartTotal;
        $this->netPayable = $cartTotal;
        if ($balance <= $cartTotal){
            $this->netPayable = $cartTotal -$balance;
        }elseif ( $balance > $cartTotal){
            $this->netPayable = 0;
        }
    }

    public function getShippingCompanies(){
        $addressCountry = Address::whereId($this->userAddressId)->first();

        $this->shippingCompanies = ShippingCompany::whereHas('countries',
                                                      fn ($query) => $query->where('country_id', $addressCountry->country_id)
                                                    )
                                                   ->get();
    }

    // Lifecycle Hooks updating (UserAddressId)
    public function updatingUserAddressId(){
        session()->forget('saved_user_address_id');
        session()->forget('saved_shipping_company_id');
        session()->forget('shipping');
        session()->put('saved_user_address_id', $this->userAddressId);
        $this->userAddressId = session()->has('saved_user_address_id') ? session()->get('saved_user_address_id') : '';
        $this->shippingCompanyId = session()->has('saved_shipping_company_id') ? session()->get('saved_shipping_company_id') : '';
        $this->paymentMethodId = session()->has('saved_payment_method_id') ? session()->get('saved_payment_method_id') : '';
        $this->emit('update_cart');
    }

    // Lifecycle Hooks updated (UserAddressId)
    public function updatedUserAddressId(){
        session()->forget('saved_user_address_id');
        session()->forget('saved_shipping_company_id');
        session()->forget('shipping');
        session()->put('saved_user_address_id', $this->userAddressId);

        $this->userAddressId = session()->has('saved_user_address_id') ? session()->get('saved_user_address_id') : '';
        $this->shippingCompanyId = session()->has('saved_shipping_company_id') ? session()->get('saved_shipping_company_id') : '';
        $this->paymentMethodId = session()->has('saved_payment_method_id') ? session()->get('saved_payment_method_id') : '';

     //   $this->checkStockProducts();
        $this->emit('update_cart');
    }

    public function storeShippingCost(){
        $shippingCompany = ShippingCompany::whereId($this->shippingCompanyId)->first();

        session()->put('shipping', [
            'code' => $shippingCompany->code,
            'cost' => $shippingCompany->cost
        ]);

        $this->emit('update_cart');
        $this->alert('success', __('Shipping cost is applied successfully'));
    }

    // Lifecycle Hooks updating (ShippingCompanyId)
    public function updatingShippingCompanyId(){
        session()->forget('saved_shipping_company_id');
        session()->put('saved_shipping_company_id', $this->shippingCompanyId);
        $this->userAddressId = session()->has('saved_user_address_id') ? session()->get('saved_user_address_id') : '';
        $this->shippingCompanyId = session()->has('saved_shipping_company_id') ? session()->get('saved_shipping_company_id') : '';
        $this->emit('update_cart');
    }

    // Lifecycle Hooks updated (ShippingCompanyId)
    public function updatedShippingCompanyId(){
        session()->forget('saved_shipping_company_id');
        session()->put('saved_shipping_company_id', $this->shippingCompanyId);
        $this->userAddressId = session()->has('saved_user_address_id') ? session()->get('saved_user_address_id') : '';
        $this->shippingCompanyId = session()->has('saved_shipping_company_id') ? session()->get('saved_shipping_company_id') : '';
        $this->emit('update_cart');
    }

    public function getPaymentMethod(){
        $paymentMethod = PaymentMethod::whereId($this->paymentMethodId)->first();
        $this->selectedPaymentMethod = $paymentMethod;
        $this->paymentMethodCode = $paymentMethod->code ?? "";
        $this->paymentMethodFounded = ($paymentMethod);
        $this->paymentMethodId = intval($this->paymentMethodId);

        if ($this->paymentMethodCode === "paypal-rest"){
           // $this->initPaypalButton();
        }

        session()->put('saved_payment_method_id', ($this->paymentMethodFounded) ? $this->paymentMethodId : null);
    }



    public function showPopupMakePayment(){
        $paymentMethod = $this->selectedPaymentMethod;
        $paymentMethodName = $paymentMethod->name ?? "";
        $paymentMethodCode = $paymentMethod->code ?? "";
        $amount = ceil($this->netPayable);

        $swalOptions = [
            "imageUrl" => $paymentMethod->image,
            "imageAlt" => $paymentMethodName,
        ];
        $amoun_details = format_amount($amount,true);
        if (in_array($paymentMethodCode,['orange-momo-cmr',"mtn-momo-cmr"])){
            $swalOptions["input"] = 'number';
            $swalOptions["inputLabel"] = __("Nº :method",["method" => $paymentMethodName]);
            $swalOptions["inputPlaceholder"] =  $swalOptions['inputLabel'];
        }
        //elseif (in_array($paymentMethodCode,['paypal-rest',])){
           // $amoun_details .= __("() :cu",["cu" => env("")]);
       // }

        $swalOptions['title'] = __("Pay :amount with :method",["method" => $paymentMethodName,"amount" => $amoun_details]);

        $this->dispatchBrowserEvent('show-popup-mobile-payment',
              [
                  'paymentMethodId' => $paymentMethod->id,
                  'paymentMethodCode' => $paymentMethodCode,
                  'swalOptions' => $swalOptions,
                  'amount' => $amount,
              ],
        );
    }

    public function initPaypalButton(){
        $paymentMethod = $this->selectedPaymentMethod;
        $paymentMethodName = $paymentMethod->name ?? "";
        $paymentMethodCode = $paymentMethod->code ?? "";
        $amount = ceil($this->netPayable);
        $this->dispatchBrowserEvent('init-paypal-button',
            [
                'paymentMethodId' => $paymentMethod->id,
                'paymentMethodCode' => $paymentMethodCode,
                'amount' => $amount,
            ],
        );
    }

    public function submitOrderWithoutPaymentMethod(){
        return $this->submitOrder(['use-payment' => false]);
    }

    public function submitOrder($options = []){
        $payer = auth(activeGuard())->user();
        $datas = [
              'items' => $this->items(), 'order' => $this->total(),
        ];
        //essaie d'enregistrer la commande
        $response = (new OrderService)->saveOrder($datas , $payer,$options);

        $type = 'error';
        $message =  __("Order was not sent yet.");
        $redirect = route("cart.index");
        $options = [
            "showConfirmButton" => true ,
            "toast" => false ,
            "timer" =>false ,
            "position" => "center" ,
            "title" => ""
        ];
        $message = $response['message'];
        if ($response['success']){
            $type = "success";
            //$redirect = route("shop.index");
            $redirect = route("user.orders");
            session()->forget([
                "saved_shipping_company_id",
                "saved_user_address_id",
                "saved_payment_method_id",
                "coupon",
                "shipping",
            ]);
            Cart::instance("default")->destroy();
        }

        $options['html'] = $message;
        $this->flash($type,$message,$options,$redirect);
       // return redirect()->to($redirect);
    }

    public function checkStockProducts(){
        $userAddress = Address::find($this->userAddressId);
        $warehouse = $userAddress->city?->warehouse ?? null; // App\Models\StockManagement\Warehouse
        $errors_msg = "";
        $redirect = false;

        if (getSettingsOf("check_stock_when_ordering_frontend")){

            if ($warehouse){
                $orderService = (new OrderService);
                $cart = Cart::instance("default")->content();
                $orderItems = $orderService->formatCart($cart);
                $checking = $orderService->productsIsAvailable($warehouse,$orderItems);

                $this->productsIsAvailable = (!$checking['errors']) ;

                //  dd($this->productsIsAvailable,$checking);

                if (!$this->productsIsAvailable){
                    $errors_msg = implode("<br>",$checking['errors']);
                    $redirect = true;
                }
            }else{
                $errors_msg = __("Point of Sale not configured");
            }
        }

        if (filled($errors_msg)){
            $this->dispatchBrowserEvent('display-stock-availabity-messages',
                        [
                            'message' => $errors_msg,
                            'redirect' => $redirect,
                        ],
                );
        }
    }

    public function render(){
        return view('livewire.frontend.checkout.checkout-component');
    }
}
