<?php

namespace Shop\Models\Product;

use Shop\Models\Position\Position;
use Shop\Models\Product\Base\Product as BaseProduct;
use Propel\Runtime\ActiveQuery\Criteria;
use Shop\Models\Position\PositionQuery;
use Propel\Runtime\Connection\ConnectionInterface;

/**
 * Skeleton subclass for representing a row from the 'shop_products' table.
 *
 *
 *
 * You should add additional methods to this class to meet the
 * application requirements.  This class will only be generated as
 * long as it does not already exist in the output directory.
 *
 */
class Product extends BaseProduct
{

    const FAKE_PERCENT = 20;

    protected $salePriceDiff;
    protected $isFavorite = false;

    /**
     * @return bool
     */
    public function isFavorite(): bool
    {
        return $this->isFavorite;
    }

    /**
     * @param bool $isFavorite
     * @return Product
     */
    public function setIsFavorite(bool $isFavorite): Product
    {
        $this->isFavorite = $isFavorite;
        return $this;
    }


    public function getSalePriceDiff(){
        return $this->salePriceDiff;
    }

    public function getOldPrice()
    {
        return ceil((self::FAKE_PERCENT / 100 + 1) * $this->getPrice());
    }
    
    /**
     * @todo пофиксить выход из цикла
     * Получние цен товара
     * @return array
     */
    public function getPrices(\Shop\Contracts\CustomerComplexInterface $customer): array
    {

        $positions = $this->getPositions(new Criteria());
     
        $prices = [
            $this->getPrice()
        ];
         
        foreach ($positions as $position) {
            /**
             * @var Position $position
             */
            if(!in_array($position->getPricelistSheetId(),$customer->getAccessPriceListScheetIds())
                    || (int)$position->getRemain() == 0
                    ){
                continue;
            }
            $prices[] = $position->getPriceFinal();
        }
        asort($prices);
          
        return $prices;
    }
    
    /**
     * @todo пофиксить выход из цикла
     * @param type $complex_rate
     * @return array
     */
    public function getPricesOld(\Shop\Contracts\CustomerComplexInterface $customer): array
    {
        
        $positions = $this->getPositions();
        
        $price = (int)$this->getOldPrice();
        
        foreach ($positions as $position) {
            if(!in_array($position->getPricelistSheetId(),$customer->getAccessPriceListScheetIds())
                    || (int)$position->getRemain() == 0
                    ){
                continue;
            } 
            $price = $position->getPriceOldFinal() > $price ? $position->getPriceOldFinal():$price;
        }
        
        $max = $this->getPricePositionsDiff($customer);
        
        return $max > 0 ? [$price] : [];
    }    

    /**
     * Получение позиций с ценами и колвом на равным 0
     * @return type
     */
    public function getCurrentPositions(\Shop\Contracts\CustomerComplexInterface $customer)
    {
        $pos = $this->getPositions();
        foreach($pos as $position){
 
            if(!in_array($position->getPricelistSheetId(),$customer->getAccessPriceListScheetIds())
                    || (int)$position->getRemain() == 0
                    ){
                $pos->removeObject($position);
            } 
            
        }
        
        return $pos;
    }
    
    /**
     * 
     * @param type $type
     * @return type
     */
    public function getSalePositions($type, \Shop\Contracts\CustomerComplexInterface $customer)
    {
        $criteria = new Criteria;
        $criteria->add("remain", 0, Criteria::GREATER_THAN);
       // $criteria->add("price", 0, Criteria::GREATER_THAN);
        $criteria->add("sale_id", $type, (is_array($type) ? Criteria::IN : Criteria::EQUAL));
        $criteria->add("pricelist_sheet_id",implode(",",$customer->getAccessPriceListScheetIds()));
        $criteria->setLimit(1);

        $pos = $this->getPositions($criteria);

        return $pos;
    }    
    
    
    /**
     * 
     * @param type $type
     * @return type
     */
    public function getSalePositionsDiff($type,\Shop\Contracts\CustomerComplexInterface $customer):int
    {

        if($this->salePriceDiff !== null){
            return $this->salePriceDiff;
        }

        $pos = $this->getSalePositions($type, $customer);
        $m = [];
        foreach ($pos as $p){
            $m []=  round($p->getPriceOld() - $p->getPrice());
        }

        $this->salePriceDiff = count($m) ? max($m) : 0;

        return $this->salePriceDiff;
    }  
    
    /**
     * 
     * @param type $type
     * @return type
     */
    public function getPricePositionsDiff(\Shop\Contracts\CustomerComplexInterface $customer):int
    {

        $pos = $this->getPositions();
        $m = [];
        foreach ($pos as $p){
            if(!in_array($p->getPricelistSheetId(),$customer->getAccessPriceListScheetIds())
                    || (int)$p->getRemain() == 0
                    ){
                continue;
            }  
            $m []=  round($p->getPriceOldFinal($customer) - $p->getPriceFinal($customer));
        }

        return count($m) ? max($m) : 0;
    }        
    
    /**
     * является ли товар новинкой
     * @param type $days
     * @return type
     */
    public function isNewDate($days)
    {
        $date = date_create();
        date_sub($date, date_interval_create_from_date_string(sprintf('%s days', $days )));
        
        return $this->getDateCreate()->getTimestamp() >= $date->getTimestamp() ;
    }
    
    /**
     * 
     * @return type
     */
    public function getGroupListArray()
    {
        $list = [];
        foreach($this->getProductGroups() as $group){
            $list []= $group->getname();
        }
        return $list;
    }

    /**
     * 
     * @param Criteria $criteria
     * @param \Shop\Models\Product\ConnectionInterface $con
     * @return type
     */
    public function getPositions(Criteria $criteria = null, ConnectionInterface $con = null)
    {
        $partial = $this->collPositionsPartial && !$this->isNew();
        if (null === $this->collPositions || null !== $criteria  || $partial) {
            if ($this->isNew() && null === $this->collPositions) {
                // return empty collection
                $this->initPositions();
            } else {
                $collPositions = PositionQuery::create(null, $criteria)
                    ->withComplexRate()
                    ->filterByProduct($this)
                    ->find($con);

                if (null !== $criteria) {
                    if (false !== $this->collPositionsPartial && count($collPositions)) {
                        $this->initPositions(false);

                        foreach ($collPositions as $obj) {
                            if (false == $this->collPositions->contains($obj)) {
                                $this->collPositions->append($obj);
                            }
                        }

                        $this->collPositionsPartial = true;
                    }

                    return $collPositions;
                }

                if ($partial && $this->collPositions) {
                    foreach ($this->collPositions as $obj) {
                        if ($obj->isNew()) {
                            $collPositions[] = $obj;
                        }
                    }
                }

                $this->collPositions = $collPositions;
                $this->collPositionsPartial = false;
            }
        }

        return $this->collPositions;
    }
    
    
    public function getTitleWithArticleBrand()
    {
        return sprintf("%s [%s %s]", $this->getTitle(), $this->getArticle(), $this->getBrand()->getName());
    }

}