<?php
    
    namespace common\modules\product\models;
    
    use common\behaviors\SaveImgBehavior;
    use common\components\artboxtree\ArtboxTreeBehavior;
    use common\modules\language\behaviors\LanguageBehavior;
    use common\modules\rubrication\models\TaxGroup;
    use Yii;
    use yii\db\ActiveQuery;
    use yii\db\ActiveRecord;
    use yii\db\Query;
    use yii\web\Request;
    
    /**
     * This is the model class for table "category".
     * @todo Write doc for ArtboxTreeBehavior
     * @property integer           $category_id
     * @property integer           $remote_id
     * @property integer           $parent_id
     * @property string            $path
     * @property integer           $depth
     * @property string            $image
     * @property integer           $product_unit_id
     * @property Brand[]           $activeBrands
     * * From language behavior *
     * @property CategoryLang      $lang
     * @property CategoryLang[]    $langs
     * @property CategoryLang      $object_lang
     * @property string            $ownerKey
     * @property string            $langKey
     * @property CategoryLang[]    $model_langs
     * @property bool              $transactionStatus
     * @method string           getOwnerKey()
     * @method void             setOwnerKey( string $value )
     * @method string           getLangKey()
     * @method void             setLangKey( string $value )
     * @method ActiveQuery      getLangs()
     * @method ActiveQuery      getLang( integer $language_id )
     * @method CategoryLang[]    generateLangs()
     * @method void             loadLangs( Request $request )
     * @method bool             linkLangs()
     * @method bool             saveLangs()
     * @method bool             getTransactionStatus()
     * * End language behavior *
     * @property Product[]         $products
     * @property ProductUnit       $productUnit
     * @property ProductCategory[] $productCategories
     */
    class Category extends ActiveRecord
    {
        
        public function behaviors()
        {
            return [
                'artboxtree' => [
                    'class'        => ArtboxTreeBehavior::className(),
                    'keyNameGroup' => NULL,
                    'keyNamePath'  => 'path',
                ],
                'language'   => [
                    'class' => LanguageBehavior::className(),
                ],
                [
                    'class'  => SaveImgBehavior::className(),
                    'fields' => [
                        [
                            'name'      => 'image',
                            'directory' => 'categories',
                        ],
                    ],
                ],
            ];
        }
        
        /**
         * @inheritdoc
         */
        public static function tableName()
        {
            return 'category';
        }
        
        /**
         * @inheritdoc
         */
        public function rules()
        {
            return [
                [
                    [
                        'parent_id',
                        'depth',
                        'product_unit_id',
                    ],
                    'integer',
                ],
                [
                    [
                        'path',
                    ],
                    'string',
                ],
            ];
        }
        
        /**
         * @inheritdoc
         */
        public function attributeLabels()
        {
            return [
                'category_id'     => Yii::t('product', 'Category ID'),
                'parent_id'       => Yii::t('product', 'Parent ID'),
                'path'            => Yii::t('product', 'Path'),
                'depth'           => Yii::t('product', 'Depth'),
                'image'           => Yii::t('product', 'Image'),
                'imageUrl'        => Yii::t('product', 'Image'),
                'product_unit_id' => Yii::t('product', 'Product Unit ID'),
                'remote_id'       => Yii::t('product', 'Remote ID'),
            ];
        }
        
        public static function find()
        {
            return new CategoryQuery(get_called_class());
        }
        
        /**
         * @return \yii\db\ActiveQuery
         */
        public function getProductUnit()
        {
            return $this->hasOne(ProductUnit::className(), [ 'product_unit_id' => 'product_unit_id' ]);
        }
        
        public function getProducts()
        {
            return $this->hasMany(Product::className(), [ 'product_id' => 'product_id' ])
                        ->viaTable('product_category', [ 'category_id' => 'category_id' ]);
        }
        
        /**
         * @return \yii\db\ActiveQuery
         */
        public function getProductCategories()
        {
            return $this->hasMany(ProductCategory::className(), [ 'category_id' => 'category_id' ]);
        }
        
        public function getBrands()
        {
            return $this->getProducts()
                        ->select('brand.*')
                        ->joinWith('brand')
                        ->groupBy('brand.brand_id');
        }
        
        /**
         * Improved getBrands()
         * @return ActiveQuery
         */
        public function getActiveBrands()
        {
            return $this->hasMany(Brand::className(), [ 'brand_id' => 'brand_id' ])
                        ->via('products');
        }
        
        public function getTaxGroupsByLevel($level)
        {
            return $this->hasMany(TaxGroup::className(), [ 'tax_group_id' => 'tax_group_id' ])
                        ->viaTable('tax_group_to_category', [ 'category_id' => 'category_id' ])
                        ->andWhere([ 'level' => $level ]);
        }
        
        public function beforeSave($insert)
        {
            if(parent::beforeSave($insert)) {
                
                if(empty( $this->parent_id )) {
                    $this->parent_id = 0;
                }
                
                return true;
            }
            return false;
        }
        
        public function getActiveFilters()
        {
            $query1 = ( new Query() )->distinct()
                                     ->select([
                                         'option_id',
                                     ])
                                     ->from('tax_option')
                                     ->innerJoin('product_variant_option', 'tax_option.tax_option_id = product_variant_option.option_id')
                                     ->innerJoin('tax_group', 'tax_group.tax_group_id = tax_option.tax_group_id')
                                     ->innerJoin('product_variant', 'product_variant.product_variant_id = product_variant_option.product_variant_id')
                                     ->innerJoin('product', 'product.product_id = product_variant.product_id')
                                     ->innerJoin('product_category', 'product_category.product_id = product.product_id')
                                     ->where([
                                         'product_category.category_id' => $this->category_id,
                                         'tax_group.is_filter'          => true,
                                     ])
                                     ->andWhere([
                                         '!=',
                                         'product_variant.stock',
                                         0,
                                     ]);
            
            $query2 = ( new Query() )->distinct()
                                     ->select([
                                         'option_id',
                                     ])
                                     ->from('tax_option')
                                     ->innerJoin('product_option', 'tax_option.tax_option_id = product_option.option_id')
                                     ->innerJoin('tax_group', 'tax_group.tax_group_id = tax_option.tax_group_id')
                                     ->innerJoin('product', 'product.product_id = product_option.product_id')
                                     ->innerJoin('product_category', 'product_category.product_id = product.product_id')
                                     ->innerJoin('product_variant', 'product_variant.product_id = product.product_id')
                                     ->where([
                                         'product_category.category_id' => $this->category_id,
                                         'tax_group.is_filter'          => true,
                                     ])
                                     ->andWhere([
                                         '!=',
                                         'product_variant.stock',
                                         0,
                                     ]);
            $query3 = ( new Query() )->select([
                'tax_option.*',
                'tax_group.*',
                'tax_option.alias as option_alias',
                'tax_group.alias as group_alias',
                'tax_option.value as value',
                'tax_option.sort AS tax_option_sort',
                'tax_group.sort AS tax_group_sort',
            ])
                                     ->from([ 'tax_option' ])
                                     ->where([ 'tax_option.tax_option_id' => $query1->union($query2) ])
                                     ->innerJoin('tax_group', 'tax_group.tax_group_id = tax_option.tax_group_id')
                                     ->orderBy('tax_option.sort, tax_group.sort');
            return $query3;
        }
        
        public function getTaxGroupsForMenu()
        {
            $connection = Yii::$app->getDb();
            $command = $connection->createCommand('
                SELECT ton.alias AS option_alias, *
                FROM tax_option AS ton
                RIGHT JOIN tax_group ON ton.tax_group_id = tax_group.tax_group_id
                RIGHT JOIN tax_group_to_category ON tax_group.tax_group_id = tax_group_to_category.tax_group_id
                WHERE  ton.tax_option_id IN (
                SELECT po.option_id FROM product_option AS po
                WHERE po.product_id IN (
                        SELECT product_id FROM product_category WHERE category_id = :category_id
                    )
                )
                AND tax_group.is_menu = TRUE AND tax_group_to_category.category_id = :category_id', [
                ':category_id' => $this->category_id,
            
            ]);
            return $command->queryAll();
        }
        
        /**
         * @todo Write doc
         *
         * @param $value
         *
         * @return mixed
         */
        public function setTaxGroup($value)
        {
            return $this->tax_group = $value;
        }
        
        public function getTaxGroup()
        {
            return $this->hasMany(TaxGroup::className(), [ 'tax_group_id' => 'tax_group_id' ])
                        ->viaTable('tax_group_to_category', [ 'category_id' => 'category_id' ]);
        }
    }
