<?php
namespace Domain\Basket;

class BasketCalculator
{
    public static function summaryWp($basket)
    {
        $wp = 0;
        if (is_array($basket)) {
            foreach ($basket as $product) {
                $wp += $product['wp'] * $product['quantity'];
            }
        }
        return $wp;
    }

    public static function countProductsText($count)
    {
        $count = (int)$count;
        if ($count === 1) {
            return $count . ' produkt';
        }
        if ($count >= 2 && $count <= 4) {
            return $count . ' produkty';
        }
        return $count . ' produktów';
    }

    /**
     * @param string|null $langId  Language ID (falls back to global $lang_id if null)
     * @param \Domain\Product\ProductRepository|null $productRepo  (falls back to $GLOBALS['mdb'] if null)
     */
    public static function summaryPrice($basket, $coupon = null, $langId = null, $productRepo = null)
    {
        if ($langId === null) {
            global $lang_id;
            $langId = $lang_id;
        }
        if ($productRepo === null) {
            $productRepo = new \Domain\Product\ProductRepository($GLOBALS['mdb']);
        }

        $summary = 0;

        if (is_array($basket)) {
            foreach ($basket as $position) {
                $product = $productRepo->findCached((int)$position['product-id'], $langId);

                $product_price_tmp = self::calculateBasketProductPrice(
                    (float)($product['price_brutto_promo'] ?? 0),
                    (float)($product['price_brutto'] ?? 0),
                    $coupon,
                    $position,
                    $productRepo
                );
                $summary += $product_price_tmp['price_new'] * $position['quantity'];
            }
        }

        return \Shared\Helpers\Helpers::normalize_decimal($summary);
    }

    public static function countProducts($basket)
    {
        $count = 0;
        if (is_array($basket)) {
            foreach ($basket as $product) {
                $count += $product['quantity'];
            }
        }
        return $count;
    }

    public static function validateBasket($basket)
    {
        if ( !is_array( $basket ) )
            return array();

        return $basket;
    }

    public static function checkProductQuantityInStock($basket, bool $message = false)
    {
        if ( !is_array( $basket ) || empty( $basket ) )
            return false;

        $result = false;
        $productRepo = new \Domain\Product\ProductRepository($GLOBALS['mdb']);

        foreach ( $basket as $key => $val )
        {
            $permutation = null;

            if ( isset( $val['parent_id'] ) and (int)$val['parent_id'] and isset( $val['product-id'] ) )
                $permutation = $productRepo->getProductPermutationHash( (int)$val['product-id'] );

            if ( !$permutation and isset( $val['attributes'] ) and is_array( $val['attributes'] ) and count( $val['attributes'] ) ) {
                $attrs = $val['attributes'];
                usort( $attrs, function ( $a, $b ) {
                    return (int) explode( '-', $a )[0] - (int) explode( '-', $b )[0];
                } );
                $permutation = implode( '|', $attrs );
            }

            $quantity_options = $productRepo->getProductPermutationQuantityOptions(
                $val['parent_id'] ? $val['parent_id'] : $val['product-id'],
                $permutation
            );

            if (
                (int)$basket[ $key ][ 'quantity' ] < 1
                and ( (int)$quantity_options['quantity'] > 0 or (int)$quantity_options['stock_0_buy'] === 1 )
            )
            {
                $basket[ $key ][ 'quantity' ] = 1;
                $result = true;
            }

            if ( ( $val[ 'quantity' ] > $quantity_options['quantity'] ) and !$quantity_options['stock_0_buy'] )
            {
                $basket[ $key ][ 'quantity' ] = $quantity_options['quantity'];
                if ( $message )
                    \Shared\Helpers\Helpers::error( 'Ilość jednego lub więcej produktów została zmniejszona z powodu niestarczających stanów magazynowych. Sprawdź proszę koszyk.' );
                $result = true;
            }
        }
        \Shared\Helpers\Helpers::set_session( 'basket', $basket );

        return $result;
    }

    /**
     * Calculate product price in basket (with coupon + promotion discounts).
     * Migrated from \shop\Product::calculate_basket_product_price()
     */
    /**
     * @param \Domain\Product\ProductRepository|null $productRepo  (falls back to $GLOBALS['mdb'] if null)
     */
    public static function calculateBasketProductPrice( float $price_brutto_promo, float $price_brutto, $coupon, $basket_position, $productRepo = null )
    {
        if ($productRepo === null) {
            $productRepo = new \Domain\Product\ProductRepository($GLOBALS['mdb']);
        }

        // Produkty przecenione
        if ( $price_brutto_promo )
        {
            $price['price'] = $price_brutto;
            $price['price_new'] = $price_brutto_promo;

            $coupon_type = is_array($coupon) ? ($coupon['type'] ?? null) : (is_object($coupon) ? $coupon->type : null);
            $coupon_include_discounted = is_array($coupon) ? ($coupon['include_discounted_product'] ?? null) : (is_object($coupon) ? $coupon->include_discounted_product : null);
            $coupon_categories = is_array($coupon) ? ($coupon['categories'] ?? null) : (is_object($coupon) ? $coupon->categories : null);
            $coupon_amount = is_array($coupon) ? ($coupon['amount'] ?? 0) : (is_object($coupon) ? $coupon->amount : 0);

            if ( $coupon_type && $coupon_include_discounted )
            {
                if ( $coupon_categories != null )
                {
                    $cats = is_string($coupon_categories) ? json_decode($coupon_categories) : $coupon_categories;
                    $product_categories = $productRepo->productCategories( (int)$basket_position['parent_id'] ? (int)$basket_position['parent_id'] : (int)$basket_position['product-id'] );
                    if ( is_array( $cats ) ) foreach ( $cats as $category_tmp )
                    {
                        if ( in_array( $category_tmp, $product_categories ) )
                        {
                            $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal( $price['price_new'] - $price['price_new'] * $coupon_amount / 100 );
                            break;
                        }
                    }
                }
                else
                    $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal( $price['price_new'] - $price['price_new'] * $coupon_amount / 100 );

                if ( $basket_position['discount_amount'] && $basket_position['discount_include_coupon'] && $basket_position['include_product_promo'] )
                {
                    if ( $basket_position['discount_type'] == 3 )
                        $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal( $basket_position['discount_amount'] );
                    if ( $basket_position['discount_type'] == 1 )
                        $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal($price['price_new'] - $price['price_new'] * $basket_position['discount_amount'] / 100 );
                }
            }
            else
            {
                if ( $basket_position['discount_amount'] && $basket_position['include_product_promo'] )
                {
                    if ( $basket_position['discount_type'] == 3 )
                        $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal( $basket_position['discount_amount'] );
                    if ( $basket_position['discount_type'] == 1 )
                        $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal($price['price_new'] - $price['price_new'] * $basket_position['discount_amount'] / 100 );
                }
            }
        }
        // Produkt nieprzeceniony
        else
        {
            $price['price'] = $price_brutto;
            $price['price_new'] = $price_brutto;

            $coupon_type = is_array($coupon) ? ($coupon['type'] ?? null) : (is_object($coupon) ? $coupon->type : null);
            $coupon_categories = is_array($coupon) ? ($coupon['categories'] ?? null) : (is_object($coupon) ? $coupon->categories : null);
            $coupon_amount = is_array($coupon) ? ($coupon['amount'] ?? 0) : (is_object($coupon) ? $coupon->amount : 0);

            if ( $coupon_type )
            {
                if ( $coupon_categories != null )
                {
                    $cats = is_string($coupon_categories) ? json_decode($coupon_categories) : $coupon_categories;
                    $product_categories = $productRepo->productCategories( $basket_position['parent_id'] ? $basket_position['parent_id'] : $basket_position['product-id'] );
                    if ( is_array( $cats ) ) foreach ( $cats as $category_tmp )
                    {
                        if ( in_array( $category_tmp, $product_categories ) )
                        {
                            $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal( $price['price_new'] - $price['price_new'] * $coupon_amount / 100 );
                            break;
                        }
                    }
                }
                else
                    $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal($price['price'] - $price['price'] * $coupon_amount / 100 );

                if ( $basket_position['discount_amount'] && $basket_position['discount_include_coupon'] && $basket_position['include_product_promo'] )
                {
                    if ( $basket_position['discount_type'] == 3 )
                        $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal( $basket_position['discount_amount'] );
                    if ( $basket_position['discount_type'] == 1 )
                        $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal($price['price'] - $price['price'] * $basket_position['discount_amount'] / 100 );
                }
            }
            else
            {
                if ( $basket_position['discount_amount'] )
                {
                    if ( $basket_position['discount_type'] == 3 )
                        $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal( $basket_position['discount_amount'] );
                    if ( $basket_position['discount_type'] == 1 )
                        $price['price_new'] = \Shared\Helpers\Helpers::normalize_decimal($price['price'] - $price['price'] * $basket_position['discount_amount'] / 100 );
                }
            }
        }

        return $price;
    }
}
