<?php

namespace common\modules\triggers\controllers;

use common\components\BaseController;
use common\modules\bids\models\Bid;
use common\modules\cases\models\CasesBids;
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\CasesSchedule;
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',
            'Sendcases' => 'Send cases by schedule'
        ];
    }

    /**
     * @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(0);
        // Производим проверку по расписанию
        /** @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) {
            // Проверяем каждое сообщение на срабатывание триггера
            foreach($actualTriggers as $trigger) {
                // Вызвали метод проверки срабатывания условий
                $triggerResult = Conditions::init()->handleMessageByTriggerId($message, $trigger->getPrimaryKey());
                // Если триггер сработал инициируем действие
                if ($triggerResult===true) {
                    $init = $trigger->initAction(['email' => $message->email]);
                    if ($init!==true)
                        echo $init;
                }
            }
        }

        // Производим проверку событий
        $users = User::find()->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
     */
    public function actionRecheckcases($category_id = 4) {
        set_time_limit(0);
        /** @var User[] $users */
        $users = User::find()->all();
        // Получили массив case-ов
        /** @var CoContent[] $cases */
        $cases = CoContent::find()->where(['category_id'=>$category_id])->all();
        // Перемешали массив case в случайном порядке
        shuffle($cases);
        // Получили список всех подписок
        $bids = CasesBids::find()->all();
        // Перебираем все подписки юзера
        foreach($bids as $bid) {
            // Если емайл указан
            if (!is_null($bid->email)) {
                $user = User::find()->where(['email' => $bid->email])->one();
                // Перебираем все case-ы
                foreach($cases as $case) {
                    // Проверили наличие отправки кейса юзеру
                    $scheduleExist = CasesSchedule::find()->where(['case_id' => $case->id, 'user_id' => $user->id])->exists();
                    // Если отправка в расписании отсутствует
                    if (!$scheduleExist) {
                        // Заносим в расписание
                        $model = new CasesSchedule();
                        $model->user_id = (!is_null($user)) ? $user->id : null;
                        $model->case_id = $case->id;
                        $model->template_id = (!is_null($case->template_id)) ? $case->template_id : null;
                        $model->sended_date = null;
                        $model->sended = 0;
                        $model->actual = 1;
                        if (!$model->save())
                            echo current(current($model->getErrors())).'<br>';
                    }
                }
            }
        }
    }

    /**
     * Метод производит рассылку по расписанию
     *
     * @param int $neededTime
     */
    public function actionSendcases($neededTime=10) {
        set_time_limit(0);
        $date = new \DateTime();
        // URL основной страницы
        $baseUrl = 'http://task-on.com/';
        /** @var CasesBids[] $bids */
        $bids = CasesBids::find()->all();
        // Массив для проверки выполнения отправки по конкретному емайл
        $sendedEmails = [];
        // Перебираем все подписки в цикле
        foreach($bids as $bid) {
            // Получили последнее отправленное письмо
            $last_sent = CasesSchedule::find()->where(['email' => $bid->email, 'sended' => 1])->orderBy('sended_date DESC')->one();
            // Получили дату для дальнейшего сравнения
            $deliveryDate = new \DateTime($last_sent->sended_date);
            // Добавили к дате сравнения 7 дней
            $deliveryDate->modify('+7 days');
            // Если этому емайл еще не отправлено письмо в данной рассылке
            if (!in_array($bid->email, $sendedEmails)) {
                // Если разница между последней отправкой и сегодня - 7 дней
                if ($deliveryDate->format('d.m.Y')===$date->format('d.m.Y')) {
                    // Получили первую запись в расписании
                    $send_records = CasesSchedule::find()->where(['email' => $bid->email, 'sended' => 0])->orderBy('sended_date ASC')->all();
                    // Перебираем в цикле записи
                    foreach($send_records as $record) {
                        // Получили кейс
                        /** @var CoContent $case */
                        $case = $record->case;
                        // Если кейс есть и у него есть шаблон
                        if (!is_null($case) && (!is_null($case->template_id) || !is_null($record->template_id))) {
                            $template_id = (!is_null($case->template_id)) ? $case->template_id : $record->template_id;
                            // Заносим урл в переменную
                            $url = $case->url;
                            // Если пользователь указан
                            if (!is_null($record->user_id)) {
                                // Получаем время просмотра каждой страницы
                                $watchingtime = TriggerLogs::getSummaryTimeByUrl($url, $record->user->id);
                                // Если суммарное время просмотра меньше минимальной нормы (то есть кейс еще не просмотрен)
                                if ((int)$watchingtime<(int)$neededTime) {
                                    // Производим отправку письма
                                    // Получаем почту
                                    $email = $record->email;
                                    // Генерируем хеш
                                    $hash=AuthHashes::setNewHash($email);
                                    // Сформировали дату
                                    $templateData = [
                                        'case_link' => $baseUrl.$url.'?hash='.$hash.'&email='.$email,
                                        'user_fio' => $record->user->getFio(),
                                        'link_to_record' => \Yii::$app->params['frontUrl'].($url!='/'?'/':'').$url
                                    ];
                                    // Производим отправку
                                    /** @var \DateTime $time_now */
                                    $sended = TriggerSchedule::sendMessage($email, $template_id, $templateData, null);
                                    // Произвели отправку, следовательно переопределили значение переменной
                                    $sendedEmails[] = $bid->email;
                                    // Редактируем запись в расписании
                                    if ($sended===true) {
                                        /** @var CasesSchedule $model */
                                        $model = CasesSchedule::findOne($record->id);
                                        $model->sended_date = $date->format('Y-m-d H:i:s');
                                        $model->sended = 1;
                                        if (!$model->save())
                                            echo current(current($model->getErrors())).'<br>';
                                    } else {
                                        echo $sended.'<br>';
                                    }
                                }
                            } else {
                                $email = $record->email;
                                // Генерируем хеш
                                $hash=AuthHashes::setNewHash($email);
                                // Сформировали дату
                                $templateData = [
                                    'case_link' => $baseUrl.$url.'?hash='.$hash.'&email='.$email,
                                    'link_to_record' => \Yii::$app->params['frontUrl'].($url!='/'?'/':'').$url
                                ];
                                // Производим отправку
                                /** @var \DateTime $time_now */
                                $sended = TriggerSchedule::sendMessage($email, $template_id, $templateData, null);
                                // Произвели отправку, следовательно переопределили значение переменной
                                $sendedEmails[] = $bid->email;
                                // Редактируем запись в расписании
                                if ($sended===true) {
                                    /** @var CasesSchedule $model */
                                    $model = CasesSchedule::findOne($record->id);
                                    $model->sended_date = $date->format('Y-m-d H:i:s');
                                    $model->sended = 1;
                                    if (!$model->save())
                                        echo current(current($model->getErrors())).'<br>';
                                } else {
                                    echo $sended.'<br>';
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
