<?php
namespace App\Services;




use App\Models\Homeparty;
use App\Models\Product;
use App\Models\ShippingCountry;

class HomepartyCart
{
    /*private $shipping_price = 0;
    private $shipping_price_net = 0;
    private $shipping_tax_rate = 0;
    private $shipping_tax = 0;
    private $shipping_country_id = 0; //default de
    private $shipping_is_for;
    private $num_comp;
    private $ysession;
    private $yinstance;
    private $shopping_data = [];*/


    public static $points = 0;
    public static $price = 0;
    public static $price_net = 0;
    public static $ek_price = 0;
    public static $income_price = 0;

    private static $shipping_total = 0;
    private static $shipping_net_total = 0;

    private static $homeparty;
    private static $userCarts = [];

    public static $user_host_id;

    public static $is_bonus = false;
    public static $is_bonus_coupon = false;


    private static $bonus_coupon = 0;
    private static $bonus_value = 30;

    private static $voucher_price = 0;
    public static $voucher_name = "";


    private static $bonus_diff = 0;
    private static $bonus_points_diff = 0;
    private static $bonus_coupon_fault = 0;
    private static $bonus_coupon_next_step = 0;
    private static $bonus_coupon_next_value = 0;
    private static $bonus_start = 200;
    private static $bonusTable = [
        250 => 15,
        300 => 20,
        400 => 30,
        500 => 35,
        600 => 40,
        700 => 50,
    ];
    public static function calculateHomeparty(Homeparty $homeparty){

        self::$homeparty = $homeparty;
        foreach ($homeparty->homeparty_users as $homeparty_user){
            if($homeparty_user->is_host){
                self::$user_host_id = $homeparty_user->id;
            }
            self::$userCarts[$homeparty_user->id] = new HomepartyUserCart($homeparty_user);
            self::addCart(self::$userCarts[$homeparty_user->id]);

        }
        self::caluclateShipping();
        self::caluclateBonus();
        self::calculateBonusHost();
    }

    public static function addCart(HomepartyUserCart $homepartyUserCart){
            self::$points += $homepartyUserCart->points;
            self::$price += $homepartyUserCart->price;
            self::$price_net += $homepartyUserCart->price_net;
            self::$ek_price += $homepartyUserCart->ek_price;
            self::$income_price += $homepartyUserCart->income_price;
    }

    public static function getUserCart($id){
        return isset(self::$userCarts[$id]) ? self::$userCarts[$id] : null;
    }


    private static function caluclateBonus(){

      if(self::$price >= 200){
          self::$is_bonus = true;
          $proportional_voucher = Product::whereIdentifier('proportional_voucher')->first();
          self::$voucher_price = $proportional_voucher->price;
          self::$voucher_name = $proportional_voucher->getLang('name');

          self::$price +=  self::$voucher_price;
          self::$price_net += $proportional_voucher->getPriceWith(true, false);

          $bonus_tmp = self::$price - self::$bonus_value;

          //look up for coupon in table
          foreach (self::$bonusTable as $val=>$coupon){
              if($bonus_tmp >= $val){
                  self::$is_bonus_coupon = true;
                  self::$bonus_coupon = $coupon;
              }else{
                  if(self::$bonus_coupon_fault === 0){
                      self::$bonus_coupon_fault = $val - $bonus_tmp;
                      self::$bonus_coupon_next_step = $val;
                      self::$bonus_coupon_next_value = $coupon;
                  }
              }
          }
          $keys = array_keys(self::$bonusTable);
          $step = $keys[count($keys)-1];
          if($bonus_tmp > $step){
              self::$bonus_coupon_next_step = $step;
              self::$bonus_coupon_next_value =self::$bonusTable[$step];
          }

      }else{
          self::$bonus_diff = 200 - self::$price;
      }

    }

    private static function calculateBonusHost(){
        if(self::$is_bonus){
            $bonus_total = self::$bonus_value + self::$bonus_coupon;
            $user_cart = self::getUserCart(self::$user_host_id);
            //cart lower the bonus
            if($user_cart->price <= $bonus_total){
                self::$bonus_points_diff = $user_cart->points;
                $user_cart->points = 0;
                $user_cart->price = 0;
                return;
            }

            $bonus_percent = (100/$user_cart->price*$bonus_total);
            self::$bonus_points_diff = round($user_cart->points/100*$bonus_percent);
            $user_cart->points -= self::$bonus_points_diff;

           $user_cart->price -= $bonus_total;
            $user_cart->price_net  -=  ($bonus_total / config('app.main_tax'));
            self::$price -= $bonus_total;
            self::$price_net -=  ($bonus_total / config('app.main_tax'));



        }
    }

    private static function caluclateShipping(){

        //weight to the orders
        //first host
        $host_user_cart = self::getUserCart(self::$user_host_id);
        $host_user_cart->shipping_weight = $host_user_cart->weight;

        foreach (self::$homeparty->homeparty_users as $homeparty_user){
            if(!$homeparty_user->is_host){
                $user_cart = self::$userCarts[$homeparty_user->id];
                if($homeparty_user->getDelivery() === 'direct'){
                    $user_cart->shipping_weight += $user_cart->weight;
                }else{
                    $host_user_cart->shipping_weight += $user_cart->weight;
                }
            }
        }

        self::calculateShippingPrice();

    }

    private static function calculateShippingPrice(){

        foreach (self::$homeparty->homeparty_users as $homeparty_user) {
            $shipping = $homeparty_user->getShipping();
            $user_cart = self::$userCarts[$homeparty_user->id];
            if(!$shipping){
                return;
            }
            if($user_cart->shipping_weight === 0){
                $shipping_price = $shipping->shipping_prices->first();
                $shipping_price->price = 0;
                $shipping_price->shipping_price_net = 0;
            }else{
                //sec by weight
                $shipping_price = self::shippingPriceByWeight($shipping->shipping_prices, $user_cart->shipping_weight);

                //default
                if(!$shipping_price){
                    $shipping_price = $shipping->shipping_prices->first();
                }
            }

            if($shipping_price){
                $price = $shipping_price->price;
                $user_cart->shipping_price = $price;
                $user_cart->shipping_tax_rate = $shipping_price->tax_rate;
                $user_cart->shipping_price_net = round($price / ((100+$shipping_price->tax_rate) / 100), 2);
                $user_cart->shipping_tax = round($price / (100+$shipping_price->tax_rate) * 100, 2);
            }

            //on the end, add prices for porto
            $user_cart->price += $user_cart->shipping_price;
            $user_cart->price_net += $user_cart->shipping_price_net;
            self::$price += $user_cart->shipping_price;
            self::$price_net += $user_cart->shipping_price_net;

            self::$shipping_total += $user_cart->shipping_price;
            self::$shipping_net_total += $user_cart->shipping_price_net;

        }
    }

    private static function shippingPriceByWeight($prices, $weight){
        foreach ($prices as $price){
            if($price->weight_from > 0 && $price->weight_to > 0){
                if($weight >= $price->weight_from && $weight <= $price->weight_to){
                    return $price;
                }
            }
        }
        return false;
    }


    public static function store($identifier, $date){

        $data = [
            'date' => $date,
            'identifier' => $identifier,
            'points' => self::$points,
            'price' => round(self::$price, 2),
            'price_net' => round(self::$price_net, 2),
            'ek_price' => round(self::$ek_price, 2),
            'income_price' => round(self::$income_price, 2),
            'user_host_id' => self::$user_host_id,
            'is_bonus' => self::$is_bonus,
            'is_bonus_coupon' => self::$is_bonus_coupon,
            'bonus_value' => self::$bonus_value,
            'bonus_coupon' => self::$bonus_coupon,
            'bonus_total' => self::$bonus_value + self::$bonus_coupon,
            'shipping_price' => self::$shipping_total,
            'shipping_price_net' => self::$shipping_net_total,
            'bonus_points_diff' => self::$bonus_points_diff,
            'voucher_price' => self::$voucher_price,
            'voucher_name' => self::$voucher_name,
        ];
        $user_data = [];
        foreach (self::$homeparty->homeparty_users as $homeparty_user){

            $user_cart = self::$userCarts[$homeparty_user->id];
            $user_data[$homeparty_user->id] = [
                'is_host' => $homeparty_user->is_host,
                'points' => $user_cart->points,
                'price' => round($user_cart->price, 2),
                'price_net' => round($user_cart->price_net, 2),
                'ek_price' => round($user_cart->ek_price, 2),
                'income_price' => round($user_cart->income_price, 2),
                'weight' => $user_cart->weight,
                'shipping_weight' => $user_cart->shipping_weight,
                'shipping_price' => round($user_cart->shipping_price, 2),
                'shipping_tax_rate' => round($user_cart->shipping_tax_rate, 2),
                'shipping_price_net' => round($user_cart->shipping_price_net, 2),
                'shipping_tax' => $user_cart->shipping_tax,
            ];
        }
        $data['user_carts'] = $user_data;
        self::$homeparty->order = $data;
        self::$homeparty->save();

    }

    public static function getUserCartHost(){
        return self::getUserCart(self::$user_host_id);
    }

    public static function getFormattedPoints()
    {
        return formatNumber(self::$points, 0);
    }

    public static function getFormattedPrice()
    {
        return formatNumber(self::$price);
    }

    public static function getFormattedPriceNet()
    {
        return formatNumber(self::$price_net);
    }

    public static function getFormattedEkPrice()
    {
        return formatNumber(self::$ek_price);
    }

    public static function getFormattedIncomePrice()
    {
        return formatNumber(self::$income_price);
    }

    public static function getFormattedPriceTax(){
        return formatNumber(self::$price - self::$price_net);
    }
    public static function getFormattedBonusPrice()
    {
        return formatNumber(self::$voucher_price);
    }
    public static function getFormattedBonusStart(){
        return formatNumber(self::$bonus_start);
    }
    public static function getFormattedBonusValue(){
        return formatNumber(self::$bonus_value);
    }

    public static function getFormattedBonusDiff(){
        return formatNumber(self::$bonus_diff);
    }

    public static function getFormattedBonusCoupon(){
        return formatNumber(self::$bonus_coupon);
    }

    public static function getFormattedBonusCouponFault(){
        return formatNumber(self::$bonus_coupon_fault);
    }

    public static function getFormattedBonusCouponNextStep(){
        return formatNumber(self::$bonus_coupon_next_step);
    }
    public static function getFormattedBonusCouponNextValue(){
        return formatNumber(self::$bonus_coupon_next_value);
    }

    public static function getFormattedBonusTotal(){
        if(self::$is_bonus){
            return formatNumber(self::$bonus_value + self::$bonus_coupon);
        }
        return formatNumber(0);
    }

    public static function getFormattedBonusPointsDiff(){
        return formatNumber( self::$bonus_points_diff, 0 );

    }

    protected function numberFormat($value, $decimals, $decimalPoint, $thousandSeperator)
    {
        if(is_null($decimals)){
            $decimals = is_null(config('cart.format.decimals')) ? 2 : config('cart.format.decimals');
        }
        if(is_null($decimalPoint)){
            $decimalPoint = is_null(config('cart.format.decimal_point')) ? '.' : config('cart.format.decimal_point');
        }
        if(is_null($thousandSeperator)){
            $thousandSeperator = is_null(config('cart.format.thousand_seperator')) ? ',' : config('cart.format.thousand_seperator');
        }

        return number_format($value, $decimals, $decimalPoint, $thousandSeperator);
    }
}