<?php
namespace App\Services;

use Yard;
use App\User;
use stdClass;
use App\Models\ShoppingUser;
use App\Services\Yard\Margin;
use App\Models\ShippingCountry;
use App\Services\Yard\Commission;
use Gloudemans\Shoppingcart\CartItem;


class Shop
{

    public static $user_country;
    public static $shipping_country;
    public static $user_tax_free;
    public static $shipping_free;
    public static $user_reverse_charge = false;


    public static function userOrders() {
        $shopping_users = ShoppingUser::whereHas('shopping_order', function($q) {
            $q->where('txaction', 'paid')->OrWhere('txaction', 'appointed')->OrWhere('txaction', 'extern')->OrWhere('txaction', 'invoice_open')->OrWhere('txaction', 'invoice_paid');
        })->where('orders', '=', NULL)->get();
        foreach ($shopping_users as $shopping_user) {
            if ($shopping_user->number) {
                $orders = ShoppingUser::where('number', '=', $shopping_user->number)->max('orders');
                $orders = $orders + 1;
            } else {
                $orders = ShoppingUser::where('billing_email', '=', $shopping_user->billing_email)->max('orders');
                $orders = $orders + 1;
            }
            $shopping_user->orders = $orders;
            $shopping_user->save();
        }
    }

    public static function newUserOrder($number){
        if($number > 0){
            $shopping_users = ShoppingUser::where('number', '=', $number)->get();
            $orders = 1;
            foreach ($shopping_users as $shopping_user) {
                if($shopping_user->shopping_order && ($shopping_user->shopping_order->txaction === 'paid' || $shopping_user->shopping_order->txaction === 'appointed' || $shopping_user->shopping_order->txaction === 'extern')){
                    $shopping_user->orders = $orders++;

                }else{
                    $shopping_user->orders = NULL;
                }
                $shopping_user->save();

            }
        }
    }

    public static function getShippingCountryCountryId($shipping_country_id){
        $shippingCountry = ShippingCountry::find($shipping_country_id);
        if($shippingCountry && $shippingCountry->country){
            return $shippingCountry->country->id;
        }
        return 1; //default DE
    }

    public static function getCountryShippingCountryId($country_id){
        $shippingCountry = ShippingCountry::whereCountryId($country_id)->first();
        if($shippingCountry){
            return $shippingCountry->id;
        }
        return ShippingCountry::all()->first()->id;
    }

    public static function initUserShopLang($country){
        Yard::instance('shopping')->destroy();
        \Session::put('user_shop_lang', strtolower($country->code));
        //init Yard
        self::initUserShopYard($country);

    }

    public static function initUserShopYard($country){
        //Lieferadresse im Drittland?
        self::$user_tax_free = $country->supply_country ? true : false;
        $ShippingCountry = ShippingCountry::whereCountryId($country->id)->first();
        self::$shipping_free = $ShippingCountry->shipping->free;
        self::$shipping_country = $ShippingCountry;
        self::$user_country = $country;

        Yard::instance('shopping')->setShippingCountryWithPrice($ShippingCountry->id);
        Yard::instance('shopping')->setUserPriceInfos(Shop::getShopYardInfo());
    }

    
    public static function getShopYardInfo(){
        return [
            'user_tax_free' => self::$user_tax_free,
            'shipping_free' =>  self::$shipping_free,
            'user_reverse_charge' => self::$user_reverse_charge,
            'user_country_id' => self::$user_country->id,
            'shipping_country_id' =>  self::$shipping_country->id,
        ];
    }

    public static function checkShoppingUser($id, $user){
        if($id === null){
            abort(403, 'Error: Keine User ID');
        }
        $shopping_user = ShoppingUser::findOrFail($id);
        if($shopping_user->member_id !== $user->id){
            abort(403, 'Error: Falsche User ID');
        }
        $shopping_user = ShoppingUser::findOrFail($id);
        if($shopping_user->is_like){
            abort(403, 'Error: Kunde in Prüfung');
        }
        return $shopping_user;
    }

    public static function checkShoppingCountry($for, $id=null){
        $country_id = null;
        if($for === 'me' || $for === 'mp' || $for === 'cr'){
            $user = User::find(\Auth::user()->id);
            if($user->account->same_as_billing){
                $country_id = $user->account->country_id;
            }else{
                $country_id = $user->account->shipping_country_id;
            }
        }
        if(strpos($for, 'ot') !== false && $id){
            $shopping_user = ShoppingUser::findOrFail($id);
            if($shopping_user->same_as_billing){
                $country_id = $shopping_user->billing_country->id;
            }else{
                $country_id = $shopping_user->shipping_country->id;
            }
        }
        if($country_id){
            if($shipping_country = ShippingCountry::whereCountryId($country_id)->first()){
                if($shipping_country->shipping && $shipping_country->shipping->active){
                    return $shipping_country->id;
                }
                
            }
        }
        return false;
    }

    public static function getShippingPriceByShippingCountryId($shipping_country_id, $shipping_weight){
        $shippingCountry = ShippingCountry::find($shipping_country_id);
        if(!$shippingCountry){
            abort(403, 'Fehler: Versandland nicht gefunden');
        }
        if(!isset($shippingCountry->shipping) && count($shippingCountry->shipping->shipping_prices) === 0){
            abort(403, 'Fehler: Kein Preise für das Versandland angelegt');
        }
        $shipping_price = $shippingCountry->shipping->shipping_prices->first();
        if(!$shipping_price){
            abort(403, 'Fehler: Preis vom Versandland nicht gefunden');
        }

        /*if(!$shipping_weight){
            abort(403, 'Fehler: Kein Versandgewicht');
        }*/

        if($shipping_weight == 0){
            $shipping_price->price = 0;
            $shipping_price->price_comp = 0;
            return $shipping_price;
        }

        if($shipping_weight > 0){
            /*
             if($this->shipping_free && $this->total(2, '.', '') >= $this->shipping_free){
                if($this->weightByFreeShipping() == 0){
                    $shipping_price->price = 0;
                    $shipping_price->price_comp = 0;
                }else{
                    $shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weightByFreeShipping());
                }
          
            }else{
                */

            return self::shippingPriceByWeight($shippingCountry->shipping->shipping_prices, $shipping_weight);
        }
        /*if($this->weight() == 0){
            
        }else{
           
                $shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weight());
                //first by price
                //$shipping_price = $this->shippingPriceByTotal($shipping->shipping_prices, $this->total(2, '.', ''));
                //sec by weight
                //if(!$shipping_price){
                //}
            }
            //default
          
        }*/

    }

    public static function shippingPriceByWeight($shipping_prices, $shipping_weight){
        foreach ($shipping_prices as $price){
            if($price->weight_from == 0 && $price->weight_to == 0){
                return $price;
            }
            if($price->weight_from > 0 && $price->weight_to > 0){
                if($shipping_weight >= $price->weight_from && $shipping_weight <= $price->weight_to){
                    return $price;
                }
            }
        }
        abort(403, 'Fehler: Preis nach Gewicht im Versandland nicht gefunden');
    }

    public static function calculateUserShopMargins($userShop = null, $promotionUser = null){  //'shop' or 'prom'
        // return;
         if($userShop){
             $user = $userShop->user;
         }
         if($promotionUser){
             $user = $promotionUser->user;
         }
         if(!isset($user)){
             return;
         }
         Yard::setUser($user);
         //get user monthy amount
         $monthy_amount = UserMarign::getMontlyAmount($user);
         $content = Yard::getCartContent();
         /*single + partner Commissions */
         //get price net commission, add amount, partner (total) from products is single_commission
         $yard_commission = new Commission();
         $yard_commission = $content->reduce(function ($yard_commission, CartItem $cartItem) {
             $price_net = $cartItem->price / ((100 + $cartItem->taxRate) / 100);
             //nicht vom Staffelrabatt -> extra Rabatt / Provision
             if($cartItem->options->single_commission){
                 $value_commission =  $price_net / 100 * $cartItem->options->value_commission;
                 $partner_commission =  $price_net / 100 * $cartItem->options->partner_commission;
 
                 $price_net_commission = ($cartItem->qty * $price_net) - ($cartItem->qty * $value_commission);
                 $yard_commission->single_price_net += ($cartItem->qty * $price_net);
                 $yard_commission->single_value_commission += ($cartItem->qty * $value_commission);
                 if(Yard::sponsorHasCommisson()){
                     $yard_commission->single_partner_commission += ($cartItem->qty * $partner_commission);
                 }
                 $yard_commission->single_price_net_commission += $price_net_commission;
                 //
                 if($cartItem->options->amount_commission){
                     $yard_commission->single_amount_commission += $price_net_commission;
                 }
             }else{
                 $yard_commission->price_net = $yard_commission->price_net + ($cartItem->qty * $price_net);
             }
             return $yard_commission;
         }, $yard_commission);
         
         //dump($monthy_amount);
         //add to $monthy_amount für max level margins
         $start_monthy_amount = $monthy_amount + $yard_commission->single_amount_commission;
         $end_monthy_amount = $start_monthy_amount + $yard_commission->price_net;
 
         //dump($start_monthy_amount);
         //dump($end_monthy_amount);
 
         $margin = new Margin();
         $rest_amount = 0;
         $range = 0;
         $price_net = $yard_commission->price_net;
         if($yard_commission->price_net > 0 && $user && $user->user_level && $user->user_level->user_level_margins){
             foreach ($user->user_level->user_level_margins_re as $user_level_margin) {
                 //total split?
                 if ($end_monthy_amount >= $user_level_margin->price_from) {
                     if(!isset($balance)){
                         if($start_monthy_amount >= $user_level_margin->price_from){
                             $balance = $yard_commission->price_net;
                             $rest_amount = 0;
                         }else{
                             $balance = $end_monthy_amount - $user_level_margin->price_from;
                             $rest_amount = $end_monthy_amount - ($start_monthy_amount + $balance);
                         }
                     }else{
                         if(isset($last_limit)){
                             $range = $last_limit - $user_level_margin->price_from;
                             if($rest_amount >= $range){
                                 $balance = $range;
                             }else{
                                 $balance = $rest_amount;
                             }
                             $rest_amount = $rest_amount - $balance;
                         }
                     }
 
                     $last_limit = $user_level_margin->price_from;
                     if($balance != 0){
                         $commission = 0;
                         if($user->sponsorHasCommisson()){
                             $commission = $user_level_margin->commission;
                         }
                         $margin->add($user_level_margin->price_from, [
                             'price_net' => $price_net,
                             'range' => $range,
                             'rest_amount' => $rest_amount,
                             'balance' => $balance,
                             'trading_margin' => $user_level_margin->trading_margin,
                             'commission' => $commission,
                         ]);
                     }
                 }
             }
         }
 
         $margin->setCommission($yard_commission);
         $margin->calculate();
         //$this->yard_margin = $margin;
         $ret = new stdClass();
 
         $ret->yard_margin = $margin;
         $ret->yard_commission = $yard_commission;
         return $ret;
     }

}