<?php
    
    namespace frontend\controllers;
    
    use common\models\CategoryToPurpose;
    use common\modules\product\models\Brand;
    use common\modules\product\models\Category;
    use common\modules\product\models\ProductSearch;
    use common\modules\rubrication\models\TaxOption;
    use yii\db\ActiveQuery;
    use yii\web\Controller;
    use yii\web\NotFoundHttpException;
    
    /**
     * Filter controller
     */
    class FilterController extends Controller
    {
        
        public function actionIndex($category_id, $purpose_id)
        {
            $category = $this->findCategory($category_id);
            $purpose = $this->findPurpose($purpose_id);
            $brands = Brand::find()
                           ->joinWith('lang', true, 'INNER JOIN')
                           ->joinWith('products.lang')
                           ->joinWith('products.categories.lang')
                           ->joinWith('products.options.lang')
                           ->where(
                               [
                                   'category.category_id'     => $category->category_id,
                                   'tax_option.tax_option_id' => $purpose->tax_option_id,
                               ]
                           )
                           ->all();
            $image = CategoryToPurpose::find()
                                      ->where(
                                          [
                                              'category_id' => $category_id,
                                              'purpose_id'  => $purpose_id,
                                          ]
                                      )
                                      ->andWhere(
                                          [
                                              'not',
                                              [ 'image' => null ],
                                          ]
                                      )
                                      ->one();
            return $this->render(
                'index',
                [
                    'category' => $category,
                    'purpose'  => $purpose,
                    'brands'   => $brands,
                    'image'    => $image,
                ]
            );
        }
        
        /**
         * Filter by type.
         *
         * @return string
         */
        public function actionCategory($id)
        {
            $category = $this->findCategory($id);
            $brandsAll = $category->activeBrands;
            $purposes = TaxOption::find()
                                 ->joinWith('lang', true, 'INNER JOIN')
                                 ->joinWith(
                                     [
                                         'products' => function ($query) use ($category) {
                                             $query->joinWith(
                                                 [
                                                     'categories' => function ($query) use ($category) {
                                                         $query->andWhere(
                                                             [ 'category.category_id' => $category->category_id ]
                                                         );
                                                     },
                                                 ]
                                             );
                                         },
                                     ]
                                 )
                                 ->joinWith('products.categories.lang')
                                 ->joinWith('products.lang')
                                 ->joinWith('products.brand.lang')
                                 ->joinWith('taxGroup')
                                 ->where(
                                     [
                                         'category.category_id'   => $category->category_id,
                                         'tax_group.tax_group_id' => 5,
                                     ]
                                 )
                                 ->all();
            $brands = [];
            foreach ($purposes as $purpose) {
                /**
                 * @var TaxOption $purpose
                 */
                $brands[ $purpose->tax_option_id ] = [];
                foreach ($purpose->products as $product) {
                    /**
                     * @var Brand $brand
                     */
                    $brand = $product->brand;
                    if (!empty( $brand )) {
                        $brands[ $purpose->tax_option_id ][ $brand->brand_id ] = $brand;
                    }
                }
            }
            return $this->render(
                'category',
                [
                    'category'  => $category,
                    'purposes'  => $purposes,
                    'brands'    => $brands,
                    'brandsAll' => $brandsAll,
                ]
            );
        }
        
        /**
         * Filter by purpose.
         *
         * @return string
         */
        public function actionPurpose($id)
        {
            $purpose = $this->findPurpose($id);
            $categories = Category::find()
                                  ->joinWith('products.lang')
                                  ->joinWith('products.brand.lang')
                                  ->joinWith(
                                      [
                                          'products' => function ($query) use ($purpose) {
                                              $query->joinWith(
                                                  [
                                                      'options' => function ($query) use ($purpose) {
                                                          $query->andWhere(
                                                              [ 'tax_option.tax_option_id' => $purpose->tax_option_id ]
                                                          );
                                                      },
                                                  ]
                                              );
                                          },
                                      ]
                                  )
                                  ->joinWith('products.options.lang')
                                  ->where([ 'tax_option.tax_option_id' => $purpose->tax_option_id ])
                                  ->all();
            $brands = [];
            foreach ($categories as $category) {
                $brands[ $category->category_id ] = [];
                foreach ($category->products as $product) {
                    /**
                     * @var Brand $brand
                     */
                    $brand = $product->brand;
                    if (!empty( $brand )) {
                        $brands[ $category->category_id ][ $brand->brand_id ] = $brand;
                    }
                }
            }
            return $this->render(
                'purpose',
                [
                    'purpose'    => $purpose,
                    'categories' => $categories,
                    'brands'     => $brands,
                ]
            );
        }
        
        public function actionBrand($category_id, $purpose_id, $brand_id)
        {
            $category = $this->findCategory($category_id);
            $purpose = $this->findPurpose($purpose_id);
            $brand = $this->findBrand($brand_id);
            $searchModel = new ProductSearch();
            $dataProvider = $searchModel->search(\Yii::$app->request->queryParams);
            $dataProvider->pagination = false;
            /**
             * @var ActiveQuery $query
             */
            $query = $dataProvider->query;
            $query->with('variants.lang')
                  ->joinWith('brand.lang')
                  ->joinWith('options.lang')
                  ->joinWith('categories.lang')
                  ->andWhere(
                      [
                          'category.category_id'     => $category->category_id,
                          'tax_option.tax_option_id' => $purpose->tax_option_id,
                          'brand.brand_id'           => $brand->brand_id,
                      ]
                  );
            return $this->render(
                'brand',
                [
                    'category'     => $category,
                    'purpose'      => $purpose,
                    'brand'        => $brand,
                    'searchModel'  => $searchModel,
                    'dataProvider' => $dataProvider,
                ]
            );
        }
        
        public function actionCategoryBrand($category_id, $brand_id)
        {
            $category = $this->findCategory($category_id);
            $brand = $this->findBrand($brand_id);
            $searchModel = new ProductSearch();
            $dataProvider = $searchModel->search(\Yii::$app->request->queryParams);
            $dataProvider->pagination = false;
            /**
             * @var ActiveQuery $query
             */
            $query = $dataProvider->query;
            $query->with('variants.lang')
                  ->joinWith('brand.lang')
                  ->joinWith('categories.lang')
                  ->andWhere(
                      [
                          'category.category_id' => $category->category_id,
                          'brand.brand_id'       => $brand->brand_id,
                      ]
                  );
            return $this->render(
                'category-brand',
                [
                    'category'     => $category,
                    'brand'        => $brand,
                    'searchModel'  => $searchModel,
                    'dataProvider' => $dataProvider,
                ]
            );
        }
        
        public function actionCategoryBrands($category_id)
        {
            $category = $this->findCategory($category_id);
            $brands = $category->activeBrands;
            return $this->render(
                'category-brands',
                [
                    'category' => $category,
                    'brands'   => $brands,
                ]
            );
        }
        
        /**
         * @param $id
         *
         * @return TaxOption
         * @throws NotFoundHttpException
         */
        private function findPurpose($id)
        {
            $model = TaxOption::find()
                              ->joinWith('taxGroup')
                              ->where(
                                  [
                                      'tax_option.tax_option_id' => $id,
                                      'tax_group.tax_group_id'   => 5,
                                  ]
                              )
                              ->one();
            if (empty( $model )) {
                throw new NotFoundHttpException();
            }
            return $model;
        }
        
        /**
         * @param $id
         *
         * @return Category
         * @throws NotFoundHttpException
         */
        private function findCategory($id)
        {
            $model = Category::find()
                             ->where(
                                 [
                                     'category.category_id' => $id,
                                 ]
                             )
                             ->one();
            if (empty( $model )) {
                throw new NotFoundHttpException();
            }
            return $model;
        }
        
        /**
         * @param $id
         *
         * @return Brand
         * @throws NotFoundHttpException
         */
        private function findBrand($id)
        {
            /**
             * @var Brand $model
             */
            $model = Brand::find()
                          ->where(
                              [
                                  'brand.brand_id' => $id,
                              ]
                          )
                          ->one();
            if (empty( $model )) {
                throw new NotFoundHttpException();
            }
            return $model;
        }
    }
