<?php

declare(strict_types=1);

Product::$definition['fields']['net_weight'] = [
    'type' => ObjectModel::TYPE_FLOAT,
    'required' => false,
    'validate' => 'isUnsignedFloat',
];

class Product extends ProductCore
{
    /**
     * @var float|null
     */
    public $net_weight;

    /**
     * @param int $id_product
     * @param int $id_product_attribute
     *
     * @return float|string
     */
    public static function computeTarifNormal($id_product, $id_product_attribute = 0)
    {
        $cache = \Cache::getInstance();
        $context = \Context::getContext();

        \assert(null !== $context);
        \assert(null !== $context->currency);

        $cache_key = 'Product::computeTarifNormal-' . $id_product
            . '-' . $id_product_attribute
            . '-' . $context->customer->id_default_group;

        if (!$cache->exists($cache_key)) {
            $group = new \Group($context->customer->id_default_group);
            $id_shop = (int) $context->shop->id;
            $id_country = (int) $context->country->id;
            $id_state = 0;
            $zipcode = '';
            $id_currency = (int) $context->currency->id;
            // Groupe = Visiteur
            $id_group = 1;
            $quantity = 1;
            $use_tax = !(1 == $group->price_display_method);
            $decimals = 2;
            $only_reduc = false;
            $use_reduc = true;
            $with_ecotax = true;
            $use_group_reduction = true;
            $specific_price = null;

            $tarifNormal = (float) \Product::priceCalculation(
                $id_shop, $id_product, $id_product_attribute, $id_country,
                $id_state, $zipcode, $id_currency,
                $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc,
                $with_ecotax, $specific_price, $use_group_reduction
            );

            $cache->set($cache_key, $tarifNormal, 3600);

            return $tarifNormal;
        } else {
            $tarifNormal = $cache->get($cache_key);

            \assert(\is_string($tarifNormal) || \is_float($tarifNormal));
        }

        return $tarifNormal;
    }

    /**
     * @param int $id_product
     *
     * @return float|string
     */
    public static function computeTarifNormalMinimum($id_product)
    {
        $id_product_attribute = \Db::getInstance(false)->executeS(
            'SELECT id_product_attribute FROM ps_product_attribute WHERE id_product = ' . (int) $id_product . ' ORDER BY wholesale_price ASC LIMIT 1'
        );

        if (!\is_array($id_product_attribute)) {
            $id_product_attribute = [];
        }

        if (0 == \count($id_product_attribute)) {
            $id_product_attribute = ['id_product_attribute' => 0];
        }

        return self::computeTarifNormal($id_product, $id_product_attribute[0]['id_product_attribute']);
    }

    /**
     * @param int $id_product
     * @param int $id_product_attribute
     *
     * @return float|string
     */
    public static function computeTarifPrivilege($id_product, $id_product_attribute = 0)
    {
        $cache = \Cache::getInstance();
        $context = \Context::getContext();

        \assert(null !== $context);
        \assert(null !== $context->currency);

        $cache_key = 'Product::computeTarifPrivilege-' . $id_product
            . '-' . $id_product_attribute
            . '-' . $context->customer->id_default_group;

        if (!$cache->exists($cache_key)) {
            $idDefaultGroup = $context->customer->id_default_group;
            if ($idDefaultGroup <= 3) {
                // TODO : A améliorer
                $idDefaultGroup = 4;
            }

            $group = new Group($context->customer->id_default_group);

            $id_shop = (int) $context->shop->id;
            $id_country = (int) $context->country->id;
            $id_state = 0;
            $zipcode = '';
            $id_currency = (int) $context->currency->id;
            $id_group = $idDefaultGroup;
            $quantity = 1;
            $use_tax = !(1 == $group->price_display_method);
            $decimals = 2;
            $only_reduc = false;
            $use_reduc = true;
            $with_ecotax = true;
            $use_group_reduction = true;
            $specific_price = null;

            $tarifPrivilege = (float) \Product::priceCalculation(
                $id_shop, $id_product, $id_product_attribute, $id_country,
                $id_state, $zipcode, $id_currency,
                $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc,
                $with_ecotax, $specific_price, $use_group_reduction
            );

            $cache->set($cache_key, $tarifPrivilege, 3600);
        } else {
            $tarifPrivilege = $cache->get($cache_key);

            \assert(\is_string($tarifPrivilege) || \is_float($tarifPrivilege));
        }

        return $tarifPrivilege;
    }

    /**
     * @param int $id_product
     * @param int $id_product_attribute
     *
     * @return float|string
     */
    public static function computeTarifFardelage($id_product, $id_product_attribute = 0)
    {
        $cache = \Cache::getInstance();
        $context = \Context::getContext();

        \assert(null !== $context);
        \assert(null !== $context->currency);

        $cache_key = 'Product::computeTarifFardelage-' . $id_product . '-' . $id_product_attribute . $context->customer->id_default_group;

        if (!$cache->exists($cache_key)) {
            $group = new \Group($context->customer->id_default_group);

            $id_shop = (int) $context->shop->id;
            $id_country = (int) $context->country->id;
            $id_state = 0;
            $zipcode = '';
            $id_currency = (int) $context->currency->id;
            $id_group = (int) $context->customer->id_default_group;
            $quantity = 2;
            $use_tax = !(1 == $group->price_display_method);
            $decimals = 2;
            $only_reduc = false;
            $use_reduc = true;
            $with_ecotax = true;
            $use_group_reduction = true;
            $specific_price = null;

            $tarifPrivilege = (float) \Product::priceCalculation(
                $id_shop, $id_product, $id_product_attribute, $id_country,
                $id_state, $zipcode, $id_currency,
                $id_group, $quantity, $use_tax, $decimals, $only_reduc, $use_reduc,
                $with_ecotax, $specific_price, $use_group_reduction
            );
            $cache->set($cache_key, $tarifPrivilege, 3600);

            return $tarifPrivilege;
        } else {
            $tarifPrivilege = $cache->get($cache_key);

            \assert(\is_string($tarifPrivilege) || \is_float($tarifPrivilege));
        }

        return $tarifPrivilege;
    }

    /**
     * @param int $id_product
     *
     * @return float|string
     */
    public static function computeTarifPrivilegeMinimum($id_product)
    {
        $id_product_attribute = \Db::getInstance(false)->executeS(
            'SELECT id_product_attribute FROM ps_product_attribute WHERE id_product = ' . (int) $id_product . ' ORDER BY wholesale_price ASC LIMIT 1'
        );

        if (!\is_array($id_product_attribute)) {
            $id_product_attribute = [];
        }

        if (0 == \count($id_product_attribute)) {
            $id_product_attribute = ['id_product_attribute' => 0];
        }

        return self::computeTarifPrivilege($id_product, $id_product_attribute[0]['id_product_attribute']);
    }

    /**
     * @return numeric-string|float
     */
    public function getReductionPrivilege()
    {
        return \GroupReduction::getValueForProduct($this->id, 4);
    }

    /**
     * @param int $id_product
     *
     * @return float|string|null
     */
    public static function getMinNetWeight($id_product)
    {
        $cache = \Cache::getInstance();
        $context = \Context::getContext();

        \assert(null !== $context);

        $cache_key = 'Product::getMinWeight-' . $id_product;
        if (!$cache->exists($cache_key)) {
            $min_net_weight = null;

            $product = new Product($id_product, true, $context->language->id, $context->shop->id);

            if ($product->hasCombinations()) {
                $combinations = $product->getAttributeCombinations($context->language->id);

                // Trouve la combination la plus légère
                if (\is_array($combinations) && \count($combinations)) {
                    foreach ($combinations as $combination) {
                        $combination = new \Combination((int) $combination['id_product_attribute']);

                        \assert(\property_exists($combination, 'net_weight'));

                        if (null === $min_net_weight || \floatval($combination->net_weight) < $min_net_weight) {
                            $min_net_weight = \floatval($combination->net_weight);
                        }
                    }
                }
            } else {
                \assert(\property_exists($product, 'net_weight'));

                $min_net_weight = \floatval($product->net_weight);
            }

            $cache->set($cache_key, $min_net_weight, 3600);
        } else {
            $min_net_weight = $cache->get($cache_key);

            \assert(\is_string($min_net_weight) || \is_float($min_net_weight));
        }

        return $min_net_weight;
    }
}
