<?php
    
    namespace frontend\widgets;
    
    use artbox\core\models\Alias;
    use artbox\core\models\Language;
    use yii\base\Widget;
    use yii\bootstrap\Html;
    use yii\helpers\Url;
    use yii\log\Logger;
    
    class LangLink extends Widget
    {
        public $languageIds = [];
        public $links = [];
        
        public function init()
        {
            if (empty($this->languageIds)) {
                $this->languageIds = Language::find()
                                             ->select(
                                                 [
                                                     'url',
                                                     'id',
                                                 ]
                                             )
                                             ->where([ 'status' => true ])
                                             ->asArray()
                                             ->indexBy('id')
                                             ->column();
            }
            if (count($this->languageIds) < 2) {
                return;
            }
            foreach ($this->languageIds as $languageId => $url) {
                if (Language::getCurrent()->id !== $languageId) {
                    if (\Yii::$app->requestedRoute == 'category/view') {
                        $aliasValues = [ \Yii::$app->request->get('category') ];
                        $filter = \Yii::$app->request->get('filter');
                        if (!empty($filter)) {
                            $aliasValues = array_merge($aliasValues, explode('_', $filter));
                        }
                        if (!empty($aliasValues)) {
                            $aliases = Alias::find()
                                            ->where(
                                                [
                                                    'route' => Alias::find()
                                                                    ->select('route')
                                                                    ->where([ 'value' => $aliasValues ]),
                                                ]
                                            )
                                            ->andWhere(
                                                [
                                                    'language_id' => [
                                                        $languageId,
                                                        Language::getCurrent()->id,
                                                    ],
                                                ]
                                            )
                                            ->asArray()
                                            ->all();
                            $map = $this->mapAliases($aliases);
                            $params = $this->replaceParams($map);
                            $this->links[ $languageId ] = Html::a(
                                $url,
                                Url::to(
                                    [ \Yii::$app->requestedRoute ] + $params + [ 'language_id' => $languageId ],
                                    true
                                )
                            );
                        } else {
                            $this->links[ $languageId ] = $url;
                        }
                    } elseif (\Yii::$app->requestedRoute == 'special/category') {
                        $aliasValue = \Yii::$app->request->get('category');
                        if (!empty($aliasValue)) {
                            $aliases = Alias::find()
                                            ->where(
                                                [
                                                    'route' => Alias::find()
                                                                    ->select('route')
                                                                    ->where([ 'value' => $aliasValue ]),
                                                ]
                                            )
                                            ->andWhere(
                                                [
                                                    'language_id' => [
                                                        $languageId,
                                                        Language::getCurrent()->id,
                                                    ],
                                                ]
                                            )
                                            ->asArray()
                                            ->all();
                            $map = $this->mapAliases($aliases);
                            $params = $this->replaceParams($map);
                            $this->links[ $languageId ] = Html::a(
                                $url,
                                Url::to(
                                    [ \Yii::$app->requestedRoute ] + $params + [ 'language_id' => $languageId ],
                                    true
                                )
                            );
                        } else {
                            $this->links[ $languageId ] = $url;
                        }
                    } else {
                        $this->links[ $languageId ] = Html::a(
                            $url,
                            Url::to(
                                [ \Yii::$app->requestedRoute ] + \Yii::$app->request->get(
                                ) + [ 'language_id' => $languageId ],
                                true
                            )
                        );
                    }
                } else {
                    $this->links[ $languageId ] = $url;
                }
            }
        }
        
        public function run()
        {
            return $this->render('_langLink');
        }
        
        protected function mapAliases(array $aliases): array
        {
            $map = [];
            $result = [];
            $currentLanguageId = Language::getCurrent()->id;
            foreach ($aliases as $alias) {
                if ($alias[ 'language_id' ] === $currentLanguageId) {
                    $map[ $alias[ 'route' ] ][ 0 ] = $alias[ 'value' ];
                } else {
                    $map[ $alias[ 'route' ] ][ 1 ] = $alias[ 'value' ];
                }
            }
            foreach ($map as $route => $alias) {
                if (!empty($alias[ 0 ]) && !empty($alias[ 1 ])) {
                    $result[ $alias[ 0 ] ] = $alias[ 1 ];
                } else {
                    \Yii::getLogger()
                        ->log("Missing alias for route $route.", Logger::LEVEL_ERROR);
                }
            }
            return $result;
        }
        
        protected function replaceParams(array $map): array
        {
            $params = \Yii::$app->request->get();
            if (isset($params[ 'filter' ])) {
                $filter = explode('_', $params[ 'filter' ]);
            }
            if (array_key_exists($params[ 'category' ], $map)) {
                $params[ 'category' ] = $map[ $params[ 'category' ] ];
            }
            if (!empty($filter)) {
                foreach ($filter as $index => $item) {
                    if (array_key_exists($item, $map)) {
                        $filter[ $index ] = $map[ $item ];
                    }
                }
                $params[ 'filter' ] = implode('_', $filter);
            }
            return $params;
        }
    }