<?php

namespace KupShop\ElninoBundle\Wrapper;

use KupShop\ElninoBundle\Translations\AbraScentsTranslation;
use Query\Operator;
use Query\Translation;

class ProductWrapper extends \KupShop\FeedsBundle\Wrapper\ProductWrapper
{
    protected $perfumesSections;
    protected $isPerfume;

    /**
     * Sleva.
     *
     * Zobrazená cena u produktu. Je to součet discount (z administrace eshopu) + display_discount (z Abry pohybem ceny produktu) + falešná globální sleva v nastavení eshopu.
     */
    public function field_discount()
    {
        $dbcfg = \Settings::getDefault();
        $displayDiscount = ($this->object->display_discount ?? \DecimalConstants::zero())
            ->add(toDecimal($dbcfg['increase_discount']));
        if ($displayDiscount->isPositive()) {
            if ($this->object->discount->isPositive()) {
                // secteni discount a display_discount
                /** @var \Decimal $discount */
                $discount = $displayDiscount;
                $multiplier = toDecimal(1)->sub($this->object->discount->div(\DecimalConstants::hundred()));
                $discount = $discount->mul($multiplier)->add($this->object->discount);

                $totalDiscount = $discount->asFloat();
            } else {
                $totalDiscount = $displayDiscount->asFloat();
            }
        } else {
            $totalDiscount = $this->object->discount->asFloat();
        }

        return $totalDiscount >= 3 ? $totalDiscount : 0.0;
    }

    /** Dodatečné obrázky */
    public function field_photos()
    {
        $this->photosWrapper->setObject($this->object->photos);

        return $this->photosWrapper;
    }

    /** CPD Velikost s jednotkou */
    public function field_size()
    {
        return $this->object->size;
    }

    /**
     * CPD Model.
     *
     * id - Abra ID modelu
     * description - popis modelu
     * complement_name - Doplněk názvu modelu
     * model_name - složený název modelu: Výrobce + řada + doplněk názvu modelu
     * old_kupshop_id - id použité v odkazu na detail modelu na eshopu.
     */
    public function field_model()
    {
        $this->products->fetchSections();
        $model = $this->object->model;
        $section = $this->object->sections[0] ?? false;

        return [
            'id' => $model['id_abra'],
            'description' => $model['description'] ?? '',
            'model_name' => $model['short_title'] ?? '',
            'complement_name' => $model['complement_model_name'] ?? '',
            'old_kupshop_id' => $model['old_kupshop_id'],
            'url' => createScriptURL([
                's' => 'product',
                'IDmodel' => $model['old_kupshop_id'],
                'TITLE' => ($section ? ($section->getName().' ') : '').$model['short_title'],
                'absolute' => true,
            ]),
        ];
    }

    /** Seznam elementů vůní.
     *
     * Možné elementy: HEAD, HEART, BASE, TYPE, FRAGRANCE, POPULARITY, SEASON, DAYTIME, LASTING, INTENSITY.
     * Element v sobě dále obsahuje jednotlivé složky vůní s jejich zastoupením (part).
     */
    public function field_model_scent_elements()
    {
        if (!isset($this->products->_cpd_scents)) {
            $modelIDs = [];
            foreach ($this->products as $product) {
                if (isset($product->model['id_abra'])) {
                    $modelIDs[$product->model['id_abra']] = $product->model['id_abra'];
                }
            }
            $qb = sqlQueryBuilder()->select('aps.id_model, aps.id_scent, aps.element, aps.part')
                ->from('abra_products_scents', 'aps')
                ->innerJoin('aps', 'abra_scents', 'as1', "as1.id_abra=aps.id_scent AND as1.name IS NOT NULL AND as1.name != ''")
                ->where(Operator::inIntArray($modelIDs, 'aps.id_model'))
                ->andWhere(Translation::coalesceTranslatedFields(
                    AbraScentsTranslation::class,
                    ['name']
                ))
                ->groupBy('aps.id_model, aps.id_scent, aps.element, aps.part')
                ->orderBy('aps.id_model, aps.element, aps.part DESC, as1.name');

            $elementsMap = [
                1 => 'HEAD',
                2 => 'HEART',
                3 => 'BASE',
                4 => 'TYPE',
                5 => 'FRAGRANCE',
                6 => 'POPULARITY',
                7 => 'SEASON',
                8 => 'DAYTIME',
                9 => 'LASTING',
                10 => 'INTENSITY',
            ];
            $scentsByModelID = [];
            foreach ($qb->execute() as $row) {
                $element = $elementsMap[$row['element']] ?? $row['element'];
                $scentsByModelID[$row['id_model']][$element][] = [
                    'id' => $row['id_scent'],
                    'name' => $row['name'],
                    'element' => $element,
                    'part' => $row['part'],
                ];
            }
            $this->products->_cpd_scents = $scentsByModelID;
        }

        return $this->products->_cpd_scents[$this->object->model['id_abra'] ?? false] ?? [];
    }

    /** URL adresa detailu produktu */
    public function field_url()
    {
        $this->products->fetchSections();
        $model = $this->object->model;
        $section = $this->object->sections[0] ?? false;

        return createScriptURL([
            's' => 'product',
            'IDproduct' => $this->object->id,
            'IDmodel' => $model['old_kupshop_id'],
            'TITLE' => ($section ? ($section->getName().' ') : '').$model['short_title'],
            'absolute' => true,
        ]);
    }

    /**
     * CPD Řada.
     *
     * id - Abra ID řady
     * description - popis řady
     * name - název řady.
     */
    public function field_serie()
    {
        $serie = $this->object->serie;

        return ['id' => $serie['id_abra'], 'description' => $serie['description'], 'name' => $serie['name']];
    }

    /** CPD Odstín */
    public function field_shade()
    {
        return $this->object->shade;
    }

    /**
     * CPD Pohlaví.
     *
     * Jeden z M/W/U/K/B
     * Man, Woman, Unisex, Kids, Bezpohlavní.
     */
    public function field_sex()
    {
        return $this->object->sex;
    }

    /** CPD Doplněk typu produktu */
    public function field_complement_type_name()
    {
        return $this->object->id_complement_type;
    }

    /** CPD - poškození */
    public function field_damage()
    {
        return $this->object->damage;
    }

    /** CPD - Složení setu */
    public function field_set()
    {
        return $this->object->set;
    }

    /** CPD - Doplněk názvu produktu */
    public function field_name2()
    {
        return $this->object->name2;
    }

    /**
     * Pole aktivních kampaní u produktu. Indexované podle kódu kampaně.
     *
     * T - Tester
     * S - Set
     * V - Vzorek
     * O - Odstřik
     */
    public function field_campaigns()
    {
        return parent::field_campaigns();
    }

    /**
     * CPD Velikost.
     *
     * value - velikost
     * unit - jednotka
     * unitBaseMeasure - Základní jednotkové množství.
     */
    public function field_size_unit()
    {
        if (!preg_match('/^([0-9]+[.,]?[0-9]*)\s*(ml|g)$/', $this->object->size, $match)) {
            return null;
        } else {
            $value = $match[1];
            $unit = $match[2];
            if ($value <= 20) {
                $unitBaseMeasure = '10 '.$unit;
            } else {
                $unitBaseMeasure = '100 '.$unit;
            }
        }

        return [
            'value' => floatval(str_replace(',', '.', $value)),
            'unit' => $unit,
            'unitBaseMeasure' => $unitBaseMeasure,
        ];
    }

    /**
     * Zda se jedná o parfém.
     *
     * Pokud je produkt parfém, hodnota je true. Pokud je kosmetika, hodnota je false.
     */
    public function field_is_perfume()
    {
        $this->products->fetchSections();
        if (!$this->perfumesSections) {
            $this->perfumesSections = sqlFetchAll(sqlQueryBuilder()
                ->select('id_section')
                ->from('abra_sections')
                ->where(Operator::equals(['id_abra' => '1100000101']))
                ->execute(), 'id_section');
        }

        $parentsSections = $this->object->sections[0]['parents'] ?? [];

        if (array_intersect(array_keys($parentsSections), array_keys($this->perfumesSections))) {
            return $this->isPerfume = true;
        }

        return $this->isPerfume = false;
    }

    /**
     * Zkrácený název.
     *
     * Kompletní název produktu prohnaný zkračovačem na 150 znaků.
     */
    public function field_short_title()
    {
        $this->products->fetchSections();
        $title = [];

        if (!empty($this->object->producer['name'])) {
            $title['producer'] = $this->object->producer['name'];
        }

        if (!empty($this->object->serie['name'])) {
            $title['serie'] = $this->object->serie['name'];
        }

        if (!empty($this->object->model['complement_model_name'])) {
            $title['complement_model'] = $this->object->model['complement_model_name'];
        }

        if (!empty($this->object->sections[0]['title'])
            && !isset($this->object->campaign_codes['S'])) {
            $title['section'] = $this->object->sections[0]['title'];
        }

        if (!empty($this->object->size) && !isset($this->object->campaign_codes['S'])) {
            $title['size'] = $this->object->size;
        }

        if (!empty($this->object->set)) {
            $title['set'] = $this->object->set;
        }

        if (!empty($this->object->campaign_codes['T'])) {
            $title['tester'] = 'Tester';
        }

        if (!empty($this->object->id_complement_type)) {
            $title['complement_type_name'] = $this->object->id_complement_type;
        }

        if (!empty($this->object->sex)) {
            $title['gender'] = $this->object->sex;
            switch ($this->object->sex) {
                case 'W':
                    $title['gender'] = 'für Frauen';
                    break;
                case 'M':
                    $title['gender'] = 'für Männer';
                    break;
                case 'U':
                    $title['gender'] = 'Unisex';
                    break;
                case 'K':
                    $title['gender'] = 'für Kinder';
                    break;
            }
        }

        if (!empty($this->object->damage)) {
            $title['damage'] = $this->object->damage;
        }

        if (!empty($this->object->shade)) {
            $title['shade'] = 'Farbton '.$this->object->shade;
        }

        if (mb_strlen(implode(' ', $title)) > 150) {
            if (isset($title['set'])) {
                $title['set'] = 'geschenkbox';
            }

            if (mb_strlen(implode(' ', $title)) > 150 && !empty($product['gender'])) {
                switch ($this->object->sex) {
                    case 'Female':
                        $title['gender'] = 'W';
                        break;
                    case 'Male':
                        $title['gender'] = 'M';
                        break;
                    case 'Unisex':
                        $title['gender'] = 'U';
                        break;
                    default:
                        unset($title['gender']);
                }
            }

            if (mb_strlen(implode(' ', $title)) > 150) {
                unset($title['complement_type_name']);
                unset($title['damage']);
            }

            // while(mb_strlen(implode(' ', $title)) > 150 && count($titleParams[$ID][$IDv]) > 0) {
            //    if (count($titleParams[$ID][$IDv]) == 1) {
            //        unset($titleParams[$ID][$IDv]);
            //        unset($title['params']);
            //    } else {
            //        array_pop($titleParams[$ID][$IDv]);
            //        $title['params'] = implode(';', $titleParams[$ID][$IDv]);
            //    }
            // }
        }

        $title = implode(' ', $title);

        return $title;
    }

    /** CPD - Číslo skladu.
     *
     * Pokud u produktu není číslo aktivního skladu určeno, pole nabývá hodnoty <code>null</code>.
     */
    public function field_store(): ?int
    {
        return $this->object->getData()['elnino_store'] ?? null;
    }
}
