<?php

namespace common\modules\relation\controllers;

use common\modules\rubrication\models\TaxOption;
use yii\base\Exception;
use yii\db\ActiveQuery;
use yii\helpers\ArrayHelper;
use yii\web\Response;
use yii\data\ActiveDataProvider;
use yii\db\ActiveRecord;
use yii\filters\ContentNegotiator;
use yii\web\Controller;
use Yii;
use common\modules\relation\relationHelper;
use common\modules\relation\models\Relation;
use common\modules\relation\models\RelationSearch;
use yii\web\NotFoundHttpException;

/**
 * Default controller for the `relation` module
 */
class ManageController extends Controller
{
    public function behaviors()
    {
        return [
            /*'bootstrap' => [
                'class' => ContentNegotiator::className(),
                'only' => ['autocomplete'],
                'formats' => [ 'application/json' => Response::FORMAT_JSON],
                'languages' => [
                    'ru',
                ],
            ],*/
        ];
    }

    /**
     * Renders the relations view
     * @return string
     */
    public function actionIndex()
    {
        $relations = relationHelper::getRelations();
        $list = [];
        foreach ($relations as $key => $relation) {
            $list[] = [
                'key' => $key,
                'name' => $relation['name'],
                'entity1_label' => $relation['entity1']['label'],
                'entity1_model' => $relation['entity1']['model'],
                'entity2_label' => $relation['entity2']['label'],
                'entity2_model' => $relation['entity2']['model'],
            ];
        }
        return $this->render('relations', [
            'relations' => $list
        ]);
    }
    /**
     * Renders the pars view for
     * @return string
     */
    public function actionPars($relation)
    {
        $relation_key = strtolower($relation);
        $relation = relationHelper::getRelation($relation_key);

        $dataProvider = new ActiveDataProvider([
            'query' => $relation['via']['model']::find(),
        ]);

        return $this->render('pars', [
            'dataProvider' => $dataProvider,
            'relation_key' => $relation_key,
            'relation' => $relation,
        ]);
    }

    public function actionCreate($relation) {
        $relation_key = strtolower($relation);
        $relation = relationHelper::getRelation($relation_key);

        $model = new $relation['via']['model'];

        if ($model->load(Yii::$app->request->post())) {
            $model->save();
            return $this->redirect(['pars', 'relation' => $relation_key]);
//            return $this->redirect(['update', 'id' => $model->{$relation['entity1']['linked_key']}. ':' .$model->{$relation['entity2']['linked_key']}]);
        } else {
            return $this->render('create', [
                'model' => $model,
//                'items1' => $query1->limit(100)->all(),
//                'items2' => $query2->asArray()->all(),
                'relation_key' => $relation_key,
                'relation' => $relation,
            ]);
        }
    }

    /**
     * Updates an existing TaxGroup model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($relation, $id) {
        $relation_key = strtolower($relation);
        $relation = relationHelper::getRelation($relation_key);

        list($id1, $id2) = explode(':', $id);

        $model = $this->findModel($relation_key, $id1, $id2);

        if ($model->load(Yii::$app->request->post())) {
            $connection = Yii::$app->getDb();
            $transaction = $connection->beginTransaction();
            try {
                // Delete links from viaTable
                $connection->createCommand()
                    ->update
                    (
                        $relation['linked_table'],
                        [
                            $relation['entity1']['linked_key'] => $model->getAttribute($relation['entity1']['linked_key']),
                            $relation['entity2']['linked_key'] => $model->getAttribute($relation['entity2']['linked_key'])
                        ],
                        $this->getWhere($relation_key, $id1, $id2)
                    )
                    ->execute();
                $transaction->commit();
            } catch (Exception $ex) {
                $transaction->rollback();
                throw $ex;
            }

            return $this->redirect(['pars', 'relation' => $relation_key]);
        } else {
            return $this->render('update', [
                'model' => $model,
                'value1' => $model->entity1->getAttribute($relation['entity1']['listField']),
                'value2' => $model->entity2->getAttribute($relation['entity2']['listField']),
                'relation_key' => $relation_key,
                'relation' => $relation,
            ]);
        }
    }

    /**
     * Deletes an existing TaxGroup model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     */
    public function actionDelete($relation, $id)
    {
        $relation_key = strtolower($relation);
        $relation = relationHelper::getRelation($relation_key);

        list($id1, $id2) = explode(':', $id);

        $connection = Yii::$app->getDb();
        $transaction = $connection->beginTransaction();
        try {
            // Delete links from viaTable
            $connection->createCommand()
                ->delete
                (
                    $relation['linked_table'],
                    $this->getWhere($relation_key, $id1, $id2)
                )
                ->execute();
            $transaction->commit();
        } catch (Exception $ex) {
            $transaction->rollback();
            throw $ex;
        }

        return $this->redirect(['pars', 'relation' => $relation_key]);
    }

    public function actionAutocomplete() {
        $relation_key = Yii::$app->request->get('relation_key');
        $entity = Yii::$app->request->get('entity');
        $term = Yii::$app->request->get('term');
        $relation_key = strtolower($relation_key);
        $relation = relationHelper::getRelation($relation_key);

        /** @var ActiveQuery $query */
        $query = $relation[$entity]['model']::find();

        if (!empty($relation[$entity]['searchJoin'])) {
            $query->innerJoinWith($relation[$entity]['searchJoin']);
        }
        if (!empty($relation[$entity]['where'])) {
            $query->where($relation[$entity]['where']);
        }
        $query->where(['ilike', $relation[$entity]['searchField'], $term]);

        print json_encode(ArrayHelper::map($query->limit(50)->all(), $relation[$entity]['key'], $relation[$entity]['listField']));
        exit;
    }

    /**
     * Finds the based model for relation on its primaries keys value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param string $relation
     * @param integer $id1
     * @param integer $id2
     * @return ActiveRecord the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($relation, $id1, $id2)
    {
        $relation_key = strtolower($relation);
        $relation = relationHelper::getRelation($relation_key);
        if (($model = $relation['via']['model']::findOne($this->getWhere($relation_key, $id1, $id2))) !== null) {
            return $model;
        } else {
            throw new NotFoundHttpException('The requested page does not exist.');
        }
    }

    protected function getWhere($relation_key, $id1, $id2) {
        $relation = relationHelper::getRelation($relation_key);
        // @todo Just think - if you need to search keys in the reverse order
        $where = [
            $relation['entity1']['linked_key'] => $id1,
            $relation['entity2']['linked_key'] => $id2,
        ];
        if (!empty($relation['alias'])) {
            $where[$relation['alias']] = $relation_key;
        }
        return $where;
    }

}
