<?php

namespace common\modules\triggers\controllers;

use common\components\BaseController;
use common\modules\bids\models\Bid;
use common\modules\content\models\CoContent;
use common\modules\messageTemplate\models\MessageTemplate;
use common\modules\triggers\components\conditions\Conditions;
use common\modules\triggers\models\AuthHashes;
use common\modules\triggers\models\TriggerLogs;
use common\modules\triggers\models\TriggerSchedule;
use common\modules\triggers\models\TriggerTrigger;
use common\modules\users\models\User;
use \DateTime;
use yii\helpers\ArrayHelper;
use yii\helpers\Json;
use common\modules\messageTemplate\components\Templates;
use common\components\UnisenderAPI;

/**
 * Default controller for the `triggers` module
 */
class DefaultController extends BaseController
{
    public static function actionsTitles(){
        return [
            'Index' => 'Главная страница модуля',
            'Rechecktriggers' => 'Запуск проверки срабатывания триггеров',
            'Recheckcases' => 'Запуск рассылки кейсов',
            'Settimeoflogs' => 'Фиксация времени логов',
            'Inittrigger' => 'Initiate trigger By id'
        ];
    }

    /**
     * @param $id
     * @param $value
     */
    public function actionSettimeoflogs($id, $value)
    {
        /** @var TriggerLogs $model */
        $model = TriggerLogs::findOne($id);
        if (!is_null($model)) {
            $model->presence_time = $value;
            $model->save(false);
        }
    }

    public function actionInittrigger($id){
        if (\Yii::$app->request->isAjax) {
            /** @var TriggerTrigger $trigger */
            $trigger = TriggerTrigger::findOne($id);
            $trigger->initAction();
        }
    }

    /**
     * Renders the index view for the module
     * @return string
     */
    public function actionIndex()
    {
        return $this->render('index');
    }

    /**
     * Метод для крона и ручного вызова. Проверяет таблицу с расписанием, выполняет сработавшие триггеры.
     */
    public function actionRechecktriggers(){
        set_time_limit(5000);
        // Производим проверку по расписанию
        /** @var TriggerTrigger[] $actualTriggers */
        // Получили текущую дату и время
        $timeNow = new DateTime();
        // Получили все те сообщения которые еще не обработаны и имеют дату равную или меньше текущей
        /** @var TriggerSchedule[] $uncheckedArray */
        $uncheckedArray = TriggerSchedule::find()->where('time <= :time_now', [':time_now' => $timeNow->format('Y-m-d H:i:s')])->all();
        // Получили все актуальные триггеры в базе
        $actualTriggers = TriggerTrigger::getActualTriggers();
        // Перебираем эти сообщения в цикле
        foreach($uncheckedArray as $message) {
            $triggerIsUsed=false;
            // Проверяем каждое сообщение на срабатывание триггера
            foreach($actualTriggers as $trigger) {
                // Вызвали метод проверки срабатывания условий
                $triggerResult = Conditions::init()->handleMessageByTriggerId($message, $trigger->getPrimaryKey());
                // Если триггер сработал инициируем действие
                if ($triggerResult===true) {
                    $triggerIsUsed=true;
                    $init = $trigger->initAction(['email' => $message->email]);
                    if ($init!==true)
                        echo $init;
                }
            }
            if ($triggerIsUsed===true) {
                /** @var TriggerSchedule $model */
                $model=TriggerSchedule::findOne($message->getPrimaryKey());
                $model->checked=1;
                $model->save();
            }
        }

        // Производим проверку событий
        $users = User::find()->where('id>0')->all();
        foreach($users as $user) {
            foreach($actualTriggers as $trigger) {
                // Вызвали метод проверки срабатывания условий
                $triggerResult = Conditions::init()->handleUserByTriggerId($user->getPrimaryKey(), $trigger->getPrimaryKey());
                // Если триггер сработал инициируем действие
                if ($triggerResult===true) {
                    $init = $trigger->initAction(['email' => $user->email]);
                    if ($init!==true)
                        echo $init;
                }
            }
        }
    }

    /**
     * Вызов логики, проверяющей список всех пользователей и просмотренные ими страницы.
     * В случае если юзер не смотрел какой либо из кейсов, выбирается и отправляется ОДИН
     * случайный кейс из просмотренных.
     *
     * @param int $category_id
     * @param int $template_id
     * @param int $neededTime
     */
    public function actionRecheckcases($category_id = 4, $template_id=1, $neededTime=10) {
        $date = new \DateTime();
        /** @var User[] $users */
        $users = User::find()->all();
        // URL основной страницы
        $baseUrl = 'http://task-on.com/';
        // Получили массив url-ов в категории
        $urls = ArrayHelper::map(CoContent::find()->where(['category_id'=>$category_id])->all(), 'id', 'url');
        // Перемешали массив ссылок в случайном порядке
        shuffle($urls);
        // Перебираем в цикле пользователей
        foreach($users as $user) {
            // Определили отправленность сообщения
            $sendedToUser=false;
            // Если письмо юзеру еще не отправлено
            if ($sendedToUser===false) {
                // Получили дату для дальнейшего сравнения
                $deliveryDate = new \DateTime($user->delivery_date);
                // Если пользователь подписан и дата соответствует требованиям
                if (Bid::find()->where(['email' => $user->email])->exists() && $deliveryDate<=$date) {
                    // Перебираем все url-ы
                    foreach($urls as $url) {
                        // Получаем время просмотра каждой страницы
                        $watchingtime = TriggerLogs::getSummaryTimeByUrl($url, $user->id);
                        // Если суммарное время просмотра больше минимальной нормы
                        if ((int)$watchingtime>(int)$neededTime) {
                            // Производим отправку письма
                            // Получаем почту
                            $email = $user->email;
                            // Генерируем хеш
                            $hash=AuthHashes::setNewHash($email);
                            // Сформировали дату
                            $templateData = [
                                'case_link' => $baseUrl.$url.'?hash='.$hash.'&email='.$email
                            ];
                            // Производим отправку
                            /** @var \DateTime $time_now */
                            TriggerSchedule::sendMessage($email, $template_id, $templateData, null);
                            // Произвели отправку, следовательно переопределили значение переменной
                            $sendedToUser=true;
                        }
                    }
                    // Создали дату следующей отправки
                    $updatedDate=new \DateTime();
                    // Произвели модификацию даты
                    $updatedDate->modify('+7 days');
                    /** @var User $user */
                    // Нашли пользователя
                    $user=User::findOne($this->id);
                    // Переопределили поле
                    $user->delivery_date = $updatedDate->format('Y-m-d');
                    // Сохранили изменения
                    $user->save(false);
                }
            }
        }
    }
}
