<?php

/**
 * Copyright distrib (2018)
 *
 * contact@opendistrib.net
 *
 * Ce logiciel est un programme informatique servant à aider les producteurs
 * à distribuer leur production en circuits courts.
 *
 * Ce logiciel est régi par la licence CeCILL soumise au droit français et
 * respectant les principes de diffusion des logiciels libres. Vous pouvez
 * utiliser, modifier et/ou redistribuer ce programme sous les conditions
 * de la licence CeCILL telle que diffusée par le CEA, le CNRS et l'INRIA
 * sur le site "http://www.cecill.info".
 *
 * En contrepartie de l'accessibilité au code source et des droits de copie,
 * de modification et de redistribution accordés par cette licence, il n'est
 * offert aux utilisateurs qu'une garantie limitée.  Pour les mêmes raisons,
 * seule une responsabilité restreinte pèse sur l'auteur du programme,  le
 * titulaire des droits patrimoniaux et les concédants successifs.
 *
 * A cet égard  l'attention de l'utilisateur est attirée sur les risques
 * associés au chargement,  à l'utilisation,  à la modification et/ou au
 * développement et à la reproduction du logiciel par l'utilisateur étant
 * donné sa spécificité de logiciel libre, qui peut le rendre complexe à
 * manipuler et qui le réserve donc à des développeurs et des professionnels
 * avertis possédant  des  connaissances  informatiques approfondies.  Les
 * utilisateurs sont donc invités à charger  et  tester  l'adéquation  du
 * logiciel à leurs besoins dans des conditions permettant d'assurer la
 * sécurité de leurs systèmes et ou de leurs données et, plus généralement,
 * à l'utiliser et l'exploiter dans les mêmes conditions de sécurité.
 *
 * Le fait que vous puissiez accéder à cet en-tête signifie que vous avez
 * pris connaissance de la licence CeCILL, et que vous en avez accepté les
 * termes.
 */

namespace frontend\controllers;

use Yii;
use common\models\Product;
use common\models\LoginForm;
use common\models\Producer;
use frontend\models\PasswordResetRequestForm;
use frontend\models\ResetPasswordForm;
use frontend\models\SignupForm;
use common\models\ContactForm;
use yii\base\InvalidParamException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
use yii\filters\VerbFilter;
use yii\filters\AccessControl;
use yii\helpers\Html;
use frontend\controllers\FrontendController;
use common\models\UserProducer;
use dosamigos\leaflet\types\LatLng;
use dosamigos\leaflet\layers\Marker;
use dosamigos\leaflet\layers\TileLayer;
use dosamigos\leaflet\LeafLet;
use dosamigos\leaflet\widgets\Map;

/**
 * Site controller
 */
class SiteController extends FrontendController
{

        /**
         * @inheritdoc
         */
        public function behaviors()
        {
                return [
                        'access' => [
                                'class' => AccessControl::className(),
                                'only' => ['logout', 'signup'],
                                'rules' => [
                                        [
                                                'actions' => ['signup'],
                                                'allow' => true,
                                                'roles' => ['?'],
                                        ],
                                        [
                                                'actions' => ['logout'],
                                                'allow' => true,
                                                'roles' => ['@'],
                                        ],
                                ],
                        ],
                        'verbs' => [
                                'class' => VerbFilter::className(),
                                'actions' => [
                                        'logout' => ['get'],
                                ],
                        ],
                ];
        }

        /**
         * @inheritdoc
         */
        public function actions()
        {
                return [
                        'captcha' => [
                                'class' => 'yii\captcha\CaptchaAction',
                                'fixedVerifyCode' => YII_ENV_TEST ? 'testme' : null,
                        ],
                ];
        }

        /**
         * Affiche la page d'erreur.
         *
         * @return mixed
         */
        public function actionError()
        {
                $exception = Yii::$app->errorHandler->exception;

                if ($exception->getMessage() == 'Producteur introuvable' || Yii::$app->getRequest()->getQueryParam('producer_not_found')) {
                        return $this->render('error-404-producer', ['exception' => $exception]);
                }

                if ($exception !== null) {
                        return $this->render('error', ['exception' => $exception]);
                }
        }

        /**
         * Affiche la page d'accueil.
         *
         * @return mixed
         */
        public function actionIndex()
        {
                return $this->render('index', [
                        'producerDemoAccount' => Producer::getDemoAccount()
                ]);
        }

        /**
         * Liste les producteurs utilisant la plateforme.
         *
         * @return mixed
         */
        public function actionProducers()
        {
                $dataProviderProducers = new ActiveDataProvider([
                        'query' => Producer::find()
                                ->where([
                                        'active' => true,
                                ])
                                ->orderBy('name ASC'),
                        'pagination' => [
                                'pageSize' => 100,
                        ],
                ]);

                return $this->render('producers', [
                        'dataProviderProducers' => $dataProviderProducers
                ]);
        }

        /**
         * Affiche les mentions légales.
         *
         * @return mixed
         */
        public function actionMentions()
        {
                return $this->render('mentions');
        }

        /**
         * Affiche la page de connexion et traite le formulaire de connexion.
         *
         * @return mixed
         */
        public function actionLogin()
        {
                if (!\Yii::$app->user->isGuest) {
                        return Yii::$app->getResponse()->redirect(['site/index']);
                }

                $model = new LoginForm();
                if ($model->load(Yii::$app->request->post()) && $model->login()) {
                        $returnUrl = Yii::$app->request->get('return_url');
                        if ($returnUrl) {
                                return $this->redirect($returnUrl);
                        } else {
                                $userProducerArray = UserProducer::find()
                                        ->with(['producer'])
                                        ->where(['id_user' => User::getCurrentId(), 'active' => 1, 'bookmark' => 1])
                                        ->all();

                                if ($userProducerArray && is_array($userProducerArray) && count($userProducerArray) == 1) {
                                        return $this->redirect(Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index', 'slug_producer' => $userProducerArray[0]->producer->slug]));
                                } else {
                                        return $this->goBack();
                                }
                        }
                } else {
                        return $this->render('@frontend/views/site/login', [
                                'model' => $model,
                        ]);
                }
        }

        /**
         * Déconnecte l'utilisateur.
         *
         * @return mixed
         */
        public function actionLogout()
        {
                Yii::$app->user->logout();
                return $this->goHome();
        }

        /**
         * Affiche la page de contact et traite le formulaire s'il est soumis.
         *
         * @return mixed
         */
        public function actionContact()
        {
                $model = new ContactForm();
                if ($model->load(Yii::$app->request->post()) && $model->validate()) {
                        if ($model->sendEmail(Yii::$app->params['adminEmail'])) {
                                Yii::$app->session->setFlash('success', 'Votre message a bien été envoyé. Nous vous répondrons dès que possible.');
                        } else {
                                Yii::$app->session->setFlash('error', 'Il y a eu une erreur lors de l\'envoi de votre message.');
                        }

                        return $this->refresh();
                } else {
                        return $this->render('contact', [
                                'model' => $model,
                        ]);
                }
        }

        /**
         * Affiche la page d'inscription et traite son formulaire.
         *
         * @return mixed
         */
        public function actionSignup()
        {
                $model = new SignupForm();
                if ($model->load(Yii::$app->request->post())) {
                        $user = $model->signup();
                        if ($user) {
                                if (Yii::$app->getUser()->login($user)) {
                                        if ($model->option_user_producer == 'producer') {
                                                $this->redirect(Yii::$app->urlManagerBackend->createAbsoluteUrl(['site/index']));
                                        } else {
                                                $producer = Producer::findOne($model->id_producer);
                                                if ($producer) {
                                                        $this->redirect(Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index', 'slug_producer' => $producer->slug]));
                                                } else {
                                                        $this->redirect(['site/index']);
                                                }
                                        }
                                }
                        }
                }

                // liste des établissements disponibles
                $producersArray = Producer::getProducerPopulateDropdown();
                $dataProducers = $producersArray['data'];
                $optionsProducers = $producersArray['options'];

                return $this->render('signup', [
                        'model' => $model,
                        'dataProducers' => $dataProducers,
                        'optionsProducers' => $optionsProducers,
                ]);
        }

        /**
         * Affiche la page de demande de nouveau mot de passe.
         * Traitement du formulaire.
         *
         * @return mixed
         */
        public function actionRequestPasswordReset()
        {
                $model = new PasswordResetRequestForm();
                if ($model->load(Yii::$app->request->post()) && $model->validate()) {
                        if ($model->sendEmail()) {
                                Yii::$app->getSession()->setFlash('success', 'Un lien vous permettant de réinitialiser votre mot de passe vient d\'être envoyé sur votre boîte mail.');

                                return $this->goHome();
                        } else {
                                Yii::$app->getSession()->setFlash('error', 'Sorry, we are unable to reset password for email provided.');
                        }
                }

                return $this->render('requestPasswordResetToken', [
                        'model' => $model,
                ]);
        }

        /**
         * Met à jour le mot de passe de l'utilisateur.
         *
         * @param string $token
         * @return mixed
         * @throws BadRequestHttpException
         */
        public function actionResetPassword($token)
        {
                try {
                        $model = new ResetPasswordForm($token);
                } catch (InvalidParamException $e) {
                        throw new BadRequestHttpException($e->getMessage());
                }

                if ($model->load(Yii::$app->request->post()) && $model->validate() && $model->resetPassword()) {
                        Yii::$app->getSession()->setFlash('success', 'Votre nouveau mot de passe vient d\'être sauvegardé.');

                        return $this->goHome();
                }

                return $this->render('resetPassword', [
                        'model' => $model,
                ]);
        }

        /**
         * Affiche les conditions générale de service.
         *
         * @return mixed
         */
        public function actionCgv()
        {
                return $this->render('cgv');
        }

        /**
         * Affiche les précisions concernant l'utilisation du crédit.
         *
         * @return string
         */
        public function actionCredit()
        {
                return $this->render('credit');
        }

        /**
         * Affiche le formulaire de demande de code pour accéder à certains
         * producteurs.
         *
         * @param integer $id
         * @return mixed
         * @throws \yii\web\HttpException
         */
        public function actionProducerCode($id)
        {
                $producer = Producer::findOne($id);

                if (!$producer) {
                        throw new \yii\web\HttpException(404, 'Producteur introuvable');
                }

                $producerCodeForm = new ProducerCodeForm;
                $producerCodeForm->id_producer = $id;

                if ($producerCodeForm->load(Yii::$app->request->post()) && $producerCodeForm->validate()) {
                        Producer::addUser(User::getCurrentId(), $id);
                        $this->redirect(Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index', 'slug_producer' => $producer->slug]));
                }

                return $this->render('producer_code', [
                        'producer' => $producer,
                        'producerCodeForm' => $producerCodeForm,
                ]);
        }

        /**
         * Affiche la page de connexion / inscription  pour accéder notamment au
         * formulaire de commande des producteirs.
         *
         * @param integer $id
         * @return mixed
         */
        public function actionProducer($id)
        {
                $loginForm = new LoginForm();
                $signupForm = new SignupForm();

                $producer = Producer::searchOne([
                        'id' => $id
                ]);

                $loginForm->id_producer = $id;
                $signupForm->id_producer = $id;
                $signupForm->option_user_producer = 'user';

                $returnUrl = Yii::$app->request->get('returnUrl', Yii::$app->urlManagerProducer->createAbsoluteUrl(['site/index', 'slug_producer' => $producer->slug]));

                if (Yii::$app->user->isGuest) {
                        if ($loginForm->load(Yii::$app->request->post()) && $loginForm->login()) {
                                if (!strlen($producer->code)) {
                                        Producer::addUser(User::getCurrentId(), $id);
                                }
                                $this->redirect($returnUrl);
                        }

                        if ($signupForm->load(Yii::$app->request->post())) {
                                if ($user = $signupForm->signup()) {
                                        if (Yii::$app->getUser()->login($user)) {
                                                $this->redirect($returnUrl);
                                        }
                                }
                        }
                } else {
                        $this->redirect($returnUrl);
                }

                return $this->render('producer', [
                        'loginForm' => $loginForm,
                        'signupForm' => $signupForm,
                        'producer' => $producer,
                ]);
        }

        /**
         * Indique à l'utilisateur que l'espace d'un producteur est hors ligne
         *
         * @param integer $id
         * @return mixed
         */
        public function actionProducerOffline($id)
        {
                $producer = Producer::searchOne([
                        'id' => $id
                ]);

                return $this->render('producer_offline', [
                        'producer' => $producer,
                ]);
        }

}
