<?php

namespace App\Repositories;

use Yard;
use App\Services\Shop;
use App\Services\Util;
use App\Models\UserShop;
use App\Models\ShoppingUser;
use App\Models\PromotionUser;
use App\Models\ShoppingOrder;
use App\Models\ShoppingOrderItem;
use App\Services\CustomerPriority;
use Illuminate\Support\Collection;
use App\Models\ShoppingOrderMargin;
use Illuminate\Session\SessionManager;
use App\Http\Controllers\Pay\PayController;

class CheckoutRepository {

    private $payment_for;
    private $PromotionUser;
    private $UserShop;

    private $is_for;
    private $session;
    private $instance;
    private $shopping_user;
    private $shopping_order;
    private $identifier;
    private $data;


    public function __construct()
    {
        $this->session = app(SessionManager::class);;
        $this->instance = sprintf('%s.%s', 'cart', 'payments');
    }

    public function setPromotion($payment_for, PromotionUser $PromotionUser)
    {
        $this->payment_for = $payment_for;
        $this->PromotionUser = $PromotionUser;
        $this->is_for = 'pr';
    }

    public function setUserShop($payment_for, UserShop $UserShop)
    {
        $this->payment_for = $payment_for;
        $this->UserShop = $UserShop;
        $this->is_for = 'shop';
    }

    public function init($identifier, $data)
    {
        $this->identifier = $identifier;
        $this->data = $data;
        if($this->getPayments('identifier') !== $identifier){
            $this->destroy();
            $this->putPayments('identifier', $identifier);
        }

        $shopping_data = Yard::instance('shopping')->getYardExtra('shopping_data');
        $this->data['is_from'] = isset($shopping_data['is_from']) ? $shopping_data['is_from'] : 'shopping'; //shopping
        $this->data['is_for'] = isset($shopping_data['is_for']) ? $shopping_data['is_for'] : 'pr'; //promotion //us shop

        $this->shopping_user = $this->makeShoppingUser($data);
        $this->shopping_order =  $this->makeShoppingOrder($this->shopping_user);

         //CustomerPriority
         if($this->shopping_user->is_from === 'shopping'){
            CustomerPriority::checkOne(ShoppingUser::find($this->shopping_user->id), true);
        }
        Util::setUserHistoryValue(['status'=>2, 'shopping_order_id'=>$this->shopping_order->id], $this->identifier);

    }

    public function makePayment()
    {
        //check credi   t Card
        if(!isset($this->data['payment_method'])){
            $this->data['payment_method'] = 'non';
        }
            $ret = [];
            //Rechnungskauf ohne PAYONE
            if($this->data['payment_method'] === 'fnc#MIV'){

            }
            if($this->data['payment_method'] === 'pp'){

            }
            //other
            $pay = new PayController();
            $pay->init($this->shopping_user, $this->shopping_order);
            $amount = Yard::instance('shopping')->totalWithShipping(2, '.', '') * 100;
            $reference = $pay->setPrePayment($this->data['payment_method'], $amount, 'EUR', $ret);
            $this->putPayments('payment_reference', $reference);
            $pay->setPersonalData();
            return $pay->ResponseData($this->identifier, $this->payment_for);
    }


    private function makeShoppingUser($data){
        $data['same_as_billing'] = isset($data['same_as_billing']) ? false : true; //reinvert
        $data['accepted_data'] = isset($data['accepted_data']) ? true : false;
        $data['billing_country_id'] = Shop::getShippingCountryCountryId($data['billing_state']);
        $data['shipping_country_id'] = $data['billing_country_id'];
        $data['member_id'] = $this->is_for === 'shop' ? $this->UserShop->user_id : $this->PromotionUser->user_id; //pr

        if(isset($data['shipping_state'])){
            $data['shipping_country_id'] = Shop::getShippingCountryCountryId($data['shipping_state']);
        }
        $shopping_user = false;
        if($this->getPayments('shopping_user_id')){
            $shopping_user = ShoppingUser::find($this->getPayments('shopping_user_id'));
            if($shopping_user){
                $shopping_user->fill($data);
                $shopping_user->mode = null;
                $shopping_user->save();
            }
        }
        if(!$shopping_user){
            $shopping_user = ShoppingUser::create($data);
        }
        $this->putPayments('shopping_user_id', $shopping_user->id);
        return $shopping_user;
    }

    private function makeShoppingOrder($shopping_user){
        $data = [
            'shopping_user_id' => $shopping_user->id,
            'auth_user_id' => $shopping_user->auth_user_id,
            'promotion_user_id' => $this->is_for === 'pr' ? $this->PromotionUser->id : null,
            'user_shop_id' => $this->is_for === 'shop' ? $this->UserShop->id : null,
            'country_id' => Yard::instance('shopping')->getShippingCountryId(),
            'payment_for' => $this->payment_for,
            'total' => Yard::instance('shopping')->total(2, '.', ''),
            'subtotal_full' => Yard::instance('shopping')->subtotal(2, '.', '', false),
            'discount' => 0,
            'subtotal' => Yard::instance('shopping')->subtotal(2, '.', ''),
            'shipping' => Yard::instance('shopping')->shipping(2, '.', ','),
            'shipping_net' => Yard::instance('shopping')->shippingNet(2, '.', ''),
            'subtotal_shipping' => Yard::instance('shopping')->subtotalWithShipping(2, '.', ''),
            'tax' => Yard::instance('shopping')->taxWithShipping(2, '.', ''),
            'total_without_credit' => Yard::instance('shopping')->totalWithShippingWithoutCredit(2, '.', ''),
            'payment_credit' => Yard::instance('shopping')->totalfromCredit(2, '.', ''),
            'total_shipping' => Yard::instance('shopping')->totalWithShipping(2, '.', ''),
            'points' => Yard::instance('shopping')->points(),
            'weight' => Yard::instance('shopping')->weight(),
            'txaction' => 'prev',
            'shipping_option' => Yard::instance('shopping')->getShippingOption(),
            'shipped' => Yard::instance('shopping')->getShippingOption() === 'pick_up' ? 4 : 0,
            'mode' => Util::getUserShoppingMode(),
        ];

        $shopping_order= false;
        if($this->getPayments('shopping_order_id')){
            $shopping_order = ShoppingOrder::find($this->getPayments('shopping_order_id'));
            if($shopping_order){
                $shopping_order->fill($data);
                $shopping_order->save();
            }
        }
        if(!$shopping_order){
            $shopping_order = ShoppingOrder::create($data);
        }
        $this->makeOrderMargin($shopping_order);

        $this->putPayments('shopping_order_id', $shopping_order->id);
         $items = Yard::instance('shopping')->getContentByOrder();
         $shopping_order->shopping_order_items()->each(function($model) use ($items, $shopping_order, $shopping_user) {
             foreach ($items as $item) {
                    if ($model->row_id === $item->rowId) {
                        $data = [
                            'shopping_order_id' => $shopping_order->id,
                            'row_id' =>  $item->rowId,
                            'product_id' => $item->id,
                            'free_product_id' => $item->options->free_product_id, //promotion_user_product_id
                            'qty' => $item->qty,
                            'price' => $item->price,
                            'price_net' => Yard::instance('shopping')->rowPriceNet($item, 3, '.', ''),
                            'tax_rate' => $item->taxRate,
                            'slug' => $item->options->slug,
                        ];
                        $model->fill($data)->save();
                        return false;
                    }
                }
                return $model->delete();
        });


        foreach ($items as $item) {
            if (!ShoppingOrderItem::where('shopping_order_id', $shopping_order->id)->where('row_id', $item->rowId)->count()){
                $data = [
                    'shopping_order_id' => $shopping_order->id,
                    'row_id' =>  $item->rowId,
                    'product_id' => $item->id,
                    'free_product_id' => $item->options->free_product_id, //promotion_user_product_id
                    'qty' => $item->qty,
                    'price' => $item->price,
                    'price_net' => Yard::instance('shopping')->rowPriceNet($item, 3, '.', ''),
                    'tax_rate' => $item->taxRate,
                    'slug' => $item->options->slug
                ];
                $shopping_order_item = ShoppingOrderItem::create($data);
            }
        }
        return $shopping_order;
    }

    private function makeOrderMargin(ShoppingOrder $shopping_order)
    {
        if ($this->is_for  === 'pr' || $this->is_for === 'shop' ) {

            $userMargin = Shop::calculateUserShopMargins($this->UserShop, $this->PromotionUser);
            $data = [
                'shopping_order_id' => $shopping_order->id,
                'user_id' => $shopping_order->shopping_user->member_id,
                'net_price' => $userMargin->yard_margin->net_price,
                'net_discount' => $userMargin->yard_margin->net_discount,
                'net_amount' => $userMargin->yard_margin->net_amount,
                'from_payment_credit' =>0,
                'from' => now(),
                'status' => $this->payment_for, //7 => 'from promotion', 8 => 'from shop',
                'content' => serialize($userMargin->yard_margin->toArray())
            ];
            if($userMargin->yard_margin->net_partner_commission > 0){
                if(isset($shopping_order->auth_user->m_sponsor)){
                    if($shopping_order->auth_user->user_sponsor && $shopping_order->auth_user->user_sponsor->isActiveAccount())
                    $data['m_sponsor_id'] = $shopping_order->auth_user->m_sponsor;
                    $data['net_partner_commission'] = $userMargin->yard_margin->net_partner_commission;
                } 
            }
            $shopping_order_margin = false;
            if ($this->getPayments('shopping_order_margin_id')) {
                $shopping_order_margin = ShoppingOrderMargin::find($this->getPayments('shopping_order_margin_id'));
                if ($shopping_order_margin) {
                    $shopping_order_margin->fill($data);
                    $shopping_order_margin->save();}
            }
            if (!$shopping_order_margin) {
                $shopping_order_margin = ShoppingOrderMargin::create($data);
            }
            $this->putPayments('shopping_order_margin_id', $shopping_order_margin->id);
        }
    }

    private function putPayments($key, $value){
        $content = $this->getContent();
        $content->put($key, $value);
        $this->session->put($this->instance, $content);

    }

    private function getPayments($key){
        $content = $this->getContent();
        if ($content->has($key)){
            return $content->get($key);
        }
        return false;
    }

    private function getContent()
    {
        if (is_null($this->session->get($this->instance))) {
            return new Collection([]);
        }
        return $this->session->get($this->instance);
    }

    public function destroy()
    {
        $this->session->remove($this->instance);
    }
}