<?php

class exchangeOffersTask extends exchangeImportTask
{
    protected $productCollect = null;
    protected $propList = null;
    /**@var Doctrine_Collection $PPVCollect collection of ProductPropValue */
    protected $PPVCollect = null;
    protected $report = array(
        'offer' => array('updated' => 0, 'created' => 0),
        'product' => array('updated' => 0,),
        'error' => array(),
    );

    protected function configure()
    {
        // // add your own arguments here
        $this->addArguments(array(
            new sfCommandArgument('file_path', sfCommandArgument::OPTIONAL, 'file path', 'offers.xml'),
        ));

        $this->addOptions(array(
            new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'www'),
            new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'arm'),
            new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'),
            // add your own options here
        ));

        $this->namespace = 'exchange';
        $this->name = 'offers';
        $this->briefDescription = '';
        $this->detailedDescription = <<<EOF
The [exchange:import|INFO] task does things.
Call it with:

  [php symfony exchange:import|INFO]
EOF;
    }


    /**
     * @param array $arguments
     * @param array $options
     * @throws Exception
     */
    protected function execute($arguments = array(), $options = array())
    {
        $task_time_start = date('Y-m-d H:i:s');

        $databaseManager = new sfDatabaseManager($this->configuration);
        $connection = $databaseManager->getDatabase($options['connection'])->getConnection();

        $instance = sfContext::createInstance($this->configuration);

        $file_path = $arguments['file_path'];
        //$file_path = 'offers.xml';
        $fullPath = sfConfig::get('sf_data_dir') . '/exchange/' . $file_path;
        if (file_exists($fullPath) && is_file($fullPath)) {
            $file = simplexml_load_file($fullPath, 'SimpleXMLIterator');
        } else {
            throw new Exception('File not exists');
        }

        /*
        $time_start = microtime(true);
        $property_data = $file->Классификатор->Свойства->Свойство;
        $property_report = $this->property($property_data);
        $this->log('property import done: [' . round((microtime(true) - $time_start) * 1000) . ' ms]');
        unset($property_data);
        */

        $time_start = microtime(true);
        $offers_data = $file->ПакетПредложений->Предложения->Предложение;
        $products = $this->getProductCollect();
        $offers_not_delete = array();
        foreach ($offers_data as $xmlItem) {
            $exp = explode('#', trim($xmlItem->{'Ид'}));
            $productInnerId = $exp[0];
            if (!isset($products[$productInnerId])) {
                $this->report['error'][] = 'Product with `inner_id` = ' . $productInnerId . ' not exist';
                continue;
            }
            if(count($exp) == 2){
                $offerInnerId = $exp[1];
            }else{
                $offerInnerId = $productInnerId;
            }
            $offerId = $this->offerItemCreateOrUpdate($xmlItem);
            $this->offerItemSetProp(
                $offerId,
                $products[$productInnerId]['id'],
                $xmlItem->{'ЗначенияСвойств'}->{'ЗначенияСвойства'}
            );
            if(!isset($xmlItem['Статус']) || $xmlItem['Статус'] != 'Удален'){
                $offers_not_delete[] = $offerInnerId;
            }
        }
        if(isset($file->ПакетПредложений['СодержитТолькоИзменения']) && $file->ПакетПредложений['СодержитТолькоИзменения'] == 'false'){
            $offers_delete_q = Doctrine_Query::create()
                ->update("Offer")
                ->set("is_delete", true)
                ->where("inner_id IS NOT NULL");
            if(count($offers_not_delete) > 0){
                $offers_delete_q->whereNotIn("inner_id", $offers_not_delete);
            }
            $offers_delete_q->execute();
        }
        $this->log(
            'offers import done: [' . round((microtime(true) - $time_start) * 1000) . ' ms] ' . "\n" .
            '  created: ' . $this->report['offer']['created'] . "\n" .
            '  updated: ' . $this->report['offer']['updated']
        );
    }

    protected function offerItemSetProp($offerId, $productId, $data)
    {
        if($offerId){
            return;
        }
        $propList = $this->getPropList();
        $PPVCollect = $this->getPPVCollect();
        if(count($data) > 0){
            foreach ($data as $xmlProp) {
                $propInnerId = trim($xmlProp->{'ИД'});
                $valueInnerId = trim($xmlProp->{'Значение'});
                if (isset($propList[$valueInnerId])) {
                    $arrayFields = array(
                        'product_id' => $productId,
                        'prop_id' => $propList[$valueInnerId]['prop_id'],
                        'value' => $propList[$valueInnerId]['value_id']
                    );
                    $index_key = $offerId . '_' . $propList[$valueInnerId]['prop_id'];
                    $productPropValue = isset($PPVCollect[$index_key]) ? $PPVCollect[$index_key] : new ProductPropValue();
                    $productPropValue->fromArray($arrayFields);
                    $productPropValue->save();
                }
            }
        }
    }

    protected function offerItemCreateOrUpdate($xmlItem)
    {
        $products = $this->getProductCollect();
        $exp = explode('#', trim($xmlItem->{'Ид'}));
        if(count($exp) == 2){
            list($productInnerId, $offerInnerId) = $exp;
        }else{
            $productInnerId = $exp[0];
            $offerInnerId = $productInnerId;
        }
        $product_id = $products[$productInnerId]['id'];
        $offer = Doctrine::getTable("Offer")->findOneByInnerIdAndProductId($offerInnerId, $product_id);
        if(!$offer){
            $offer = new Offer();
            $offer['inner_id'] = $offerInnerId;
            $offer['product_id'] = $product_id;
            $offer['img'] = '';
        }else{
            $this->imgRemove($offer['img']);
        }
        $offer['is_wholesale'] = 0;
        $offer['price'] = trim($xmlItem->{'Цены'}->{'Цена'}->{'ЦенаЗаЕдиницу'});
        $offer['Translation']['ru']['title'] = trim($xmlItem->{'Наименование'});
        if (stristr($offer['Translation']['ru']['title'], ')', true))
        {
            $title = stristr($offer['Translation']['ru']['title'], ')', true) . ')';
            $end = stristr($offer['Translation']['ru']['title'], ')');
            if (strlen($end) > 3 && $end != false)
            {
                $end = str_replace('(', '', $end);
                $end = str_replace(')', '', $end);
                $offer['Translation']['ru']['title'] = $title . ', ' . $end;
            }else
            {
                $offer['Translation']['ru']['title'] = $title;
            }

        }

        $offer['Translation']['en']['title'] = trim($xmlItem->{'Наименование'});
        if (stristr($offer['Translation']['en']['title'], ')', true))
        {
            $title = stristr($offer['Translation']['en']['title'], ')', true) . ')';
            $end = stristr($offer['Translation']['en']['title'], ')');
            if (strlen($end) > 3 && $end != false)
            {
                $end = str_replace('(', '', $end);
                $end = str_replace(')', '', $end);
                $offer['Translation']['en']['title'] = $title . ', ' . $end;
            }else
            {
                $offer['Translation']['en']['title'] = $title;
            }

        }
        $offer['Translation']['ru']['quantity_type'] = trim($xmlItem->{'БазоваяЕдиница'}->attributes()->{'НаименованиеПолное'});
        if (mb_strtolower(trim($offer['Translation']['ru']['quantity_type'])) == 'штука')
        {
            $offer['Translation']['ru']['quantity_type'] = 'ШТ';
        }
        $offer['Translation']['en']['quantity_type'] = trim($xmlItem->{'БазоваяЕдиница'}->attributes()->{'НаименованиеПолное'});
        $offer['is_delete'] = (isset($xmlItem['Статус']) && $xmlItem['Статус'] == 'Удален');
        if (strlen($xmlItem->{'Картинка'}) > 0) {

            file_put_contents(sfConfig::get('sf_log_dir') . '/rusOffersImage', print_r([trim($xmlItem->{'Картинка'})], true) . "\n", FILE_APPEND);

            $offer['img'] = $this->imgUploader([trim($xmlItem->{'Картинка'})], 'product');

            file_put_contents(sfConfig::get('sf_log_dir') . '/rusOffersImage', $offer['img'] . "____\n", FILE_APPEND);

        }
        if (!$offer->isNew() && $offer->isModified(true)) {
            $this->report['offer']['updated']++;
        } elseif ($offer->isNew()) {
            $this->report['offer']['created']++;
        }
        $offer->save();
        return $offer->getId();
    }
    protected function getPPVCollect()
    {
        if (is_null($this->PPVCollect)) {
            $this->PPVCollect = Doctrine_Query::create()
                ->select('*, ppv.prop_id')
                ->from('ProductPropValue ppv INDEXBY ppv.prop_id')
                ->where('ppv.prop_id is not null')
                ->groupBy("ppv.prop_id")
                ->execute();
        }

        return $this->PPVCollect;
    }

    protected function getPropList()
    {
        if (is_null($this->propList)) {
            $this->propList = Doctrine_Query::create()
                ->select('ppl.id as value_id, pp.id as prop_id, ppl.inner_id')
                ->from('ProductPropList ppl INDEXBY ppl.inner_id')
                ->leftJoin('ppl.ProductProp pp')
                ->where('ppl.inner_id is not null')
                ->groupBy("ppl.inner_id")
                ->fetchArray();
        }
        return $this->propList;
    }

    protected function getProductCollect()
    {
        if (is_null($this->productCollect)) {
            $this->productCollect = Doctrine_Query::create()
                ->select("p.id, p.inner_id")
                ->from("Product p INDEXBY p.inner_id")
                ->where("p.inner_id IS NOT NULL AND CHAR_LENGTH(p.inner_id) > 0")
                ->groupBy("p.inner_id")
                ->fetchArray();
        }
        return $this->productCollect;
    }
}
