<?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 backend\controllers;

use common\helpers\GlobalParam;
use common\logic\Distribution\Distribution\Model\Distribution;
use common\logic\Order\Order\Model\Order;
use common\logic\PointSale\PointSale\Model\PointSale;
use common\logic\Product\Product\Model\Product;
use common\logic\User\User\Model\User;
use Yii;
use yii\filters\AccessControl;
use common\forms\LoginForm;
use yii\filters\VerbFilter;

/**
 * Site controller
 */
class SiteController extends BackendController
{
    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::class,
                'rules' => [
                    [
                        'actions' => ['login', 'error'],
                        'allow' => true,
                    ],
                    [
                        'actions' => ['logout', 'index'],
                        'allow' => true,
                        'roles' => ['@'],
                        'matchCallback' => function ($rule, $action) {
                            return $this->getUserManager()->hasAccessBackend();
                        }
                    ],
                    [
                        'actions' => ['change-producer'],
                        'allow' => true,
                        'roles' => ['@'],
                        'matchCallback' => function ($rule, $action) {
                            return $this->getUserManager()->getCurrentStatus() == User::STATUS_ADMIN;
                        }
                    ],
                ],
            ],
            'verbs' => [
                'class' => VerbFilter::class,
                'actions' => [
                ],
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function actions()
    {
        return [
            'error' => [
                'class' => 'yii\web\ErrorAction',
            ],
        ];
    }

    /**
     * Affiche le tableau de bord du backend avec les dernières commandes
     * réalisée, les dernières inscriptions, la liste des clients ayant un crédit
     * négatif etc.
     *
     * @return mixed
     */
    public function actionIndex()
    {
        $userManager = $this->getUserManager();
        $producerManager = $this->getProducerManager();

        $optionDashboardNumberDistributions = $producerManager->getConfig('option_dashboard_number_distributions');
        $dashboardNumberDistributions = $optionDashboardNumberDistributions ? $optionDashboardNumberDistributions : 3;

        $optionDashboardDateStart = $producerManager->getConfig('option_dashboard_date_start');
        $optionDashboardDateEnd = $producerManager->getConfig('option_dashboard_date_end');

        $queryDistributions = Distribution::find()->with('order');

        if ($optionDashboardDateStart || $optionDashboardDateEnd) {
            if ($optionDashboardDateStart) {
                $queryDistributions->andWhere(['>=', 'distribution.date', $optionDashboardDateStart]);
            }
            if ($optionDashboardDateEnd) {
                $queryDistributions->andWhere(['<=', 'distribution.date', $optionDashboardDateEnd]);
            }
        } else {
            $queryDistributions->andWhere(['>=', 'distribution.date', date('Y-m-d')]);
        }


        $distributionsArray = $queryDistributions->andWhere([
            'distribution.id_producer' => GlobalParam::getCurrentProducerId(),
            'distribution.active' => 1
        ])
            ->orderBy('date ASC')
            ->limit($dashboardNumberDistributions)
            ->all();

        // dernières commandes
        $paramsOrders = [];
        if ($optionDashboardDateStart || $optionDashboardDateEnd) {
            $conditionsOrders = '';
            if ($optionDashboardDateStart) {
                $conditionsOrders .= 'distribution.date >= :date_start';
                $paramsOrders[':date_start'] = $optionDashboardDateStart;
            }
            if ($optionDashboardDateEnd) {
                if ($optionDashboardDateStart) {
                    $conditionsOrders .= ' AND ';
                }
                $conditionsOrders .= 'distribution.date <= :date_end';
                $paramsOrders[':date_end'] = $optionDashboardDateEnd;
            }
        } else {
            $conditionsOrders = 'distribution.date >= :date_start';
            $paramsOrders[':date_start'] = date('Y-m-d 00:00:00');
        }

        $ordersArray = Order::searchAll([], [
            'orderby' => 'date DESC',
            'conditions' => $conditionsOrders . ' AND (origin = \'' . Order::ORIGIN_USER . '\' OR origin = \'' . Order::ORIGIN_ADMIN . '\' OR (origin = \'' . Order::ORIGIN_AUTO . '\' AND (date_update IS NOT NULL OR date_delete IS NOT NULL)))',
            'params' => $paramsOrders,
        ]);

        // clients
        $usersArray = $userManager->queryUsersBy()
            ->orderBy('created_at DESC')
            ->limit(5)
            ->all();

        $usersNegativeCredit = $userManager->queryUsersBy(['id_producer' => GlobalParam::getCurrentProducerId()])
            ->andWhere('user_producer.credit < 0')
            ->all();

        $producerCurrent = GlobalParam::getCurrentProducer();
        $productsCount = Product::searchCount();
        $pointsSaleCount = PointSale::searchCount();

        return $this->render('index', [
            'distributionsArray' => $distributionsArray,
            'ordersArray' => $ordersArray,
            'usersArray' => $usersArray,
            'usersNegativeCredit' => $usersNegativeCredit,
            'producer' => $producerCurrent,
            'productsCount' => $productsCount,
            'pointsSaleCount' => $pointsSaleCount
        ]);
    }

    /**
     * Affiche la page de connexion.
     */
    public function actionLogin()
    {
        if (!\Yii::$app->user->isGuest) {
            return $this->goHome();
        }

        $model = new LoginForm();
        if ($model->load(\Yii::$app->request->post()) && $model->login()) {
            return $this->goBack();
        } else {
            return $this->render('login', [
                'model' => $model,
            ]);
        }
    }

    /**
     * Déconnecte l'utilisateur et le redirige à la page d'accueil.
     */
    public function actionLogout()
    {
        Yii::$app->user->logout();

        return $this->goHome();
    }

    /**
     * Change le producteur courant de l'utilisateur connecté.
     * Permet de passer d'un producteur à un autre en tant qu'administrateur.
     */
    public function actionChangeProducer(int $id)
    {
        Yii::$app->user->identity->id_producer = $id;
        Yii::$app->user->identity->save();
        $this->redirect(['site/index']);
    }
}
