<?php

namespace common\modules\testings\models;

use common\modules\triggers\components\conditions\conditions\UserSuccessfullyCompletedTheTest;
use common\modules\triggers\components\conditions\conditions\UserUnsuccessfullyCompletedTheTest;
use common\modules\triggers\models\TriggerCondition;
use common\modules\triggers\models\TriggerTrigger;
use Yii;
use yii\behaviors\TimestampBehavior;
use yii\db\Expression;

use common\modules\users\models\User;

/**
 * Class Passing
 * @package common\modules\testings\models
 *
 * @property integer $passed
 */
class Passing extends \common\components\ActiveRecordModel
{
    const PAGE_SIZE = 10;

	const NOT_STARTED = 0;
	const STARTED = 11;
	const ENDED = 1;

	const FAILED = 0;
	const PASSED = 1;

    const PASSING_PERCENT_RIGHT_CENTER = 50;
    const PASSING_PERCENT_RIGHT_ALMOST = 75;
    const PASSING_PERCENT_RIGHT_ALL = 100;

    public static $state_list = [
		self::NOT_STARTED => 'Не сдавал',
		self::STARTED => 'Тестирование',
		self::ENDED => 'Завершено',
    ];

    public static $passed_list = [
        self::FAILED => 'Не сдал',
		self::PASSED => 'Сдал',
    ];

    public static $answer_list = [
        self::FAILED => 'Не верно',
		self::PASSED => 'Верно',
    ];

	public static function tableName()
	{
		return 'testings_passings';
	}


    public function name()
    {
        return 'Прохождения';
    }

	/**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
        ];
    }

    public function rules()
	{
		return [
			[['user_id', 'test_id'], 'required'],
			[['user_id', 'test_id', 'status', 'passed', 'percent', 'points'], 'integer'],
			[['start_date', 'attempt'], 'safe'],
			[['end_date'], 'required', 'on' => 'extend'],
		];
	}

	public function attributeLabels() 
	{
		return [
			'test_id' => 'Tест',
			'user_id' => 'ФИО',
			'passed' => 'Сдал/Не сдал',
			'status' => 'Статус',
			'start_date' => 'Дата создания',
			'end_date' => 'Дата прохождения теста',
			'session_id' => 'Сессия',
			'filter_user_email' => 'Email',
			'filter_user_last_name' => 'ФИО',
		];
	}

	public function getMistake()
    {
        return $this->hasOne(Mistake::className(), ['passing_id' => 'id']);
    }

    public function getTest()
    {
        return $this->hasOne(Test::className(), ['id' => 'test_id']);
    }

    public function getUser()
    {
        return $this->hasOne(User::className(), ['id' => 'user_id']);
    }

    public function getQuestions()
    {
        return $this->hasMany(QuestionPassing::className(), ['passing_id' => 'id']);
    }

    public function getCountPassedQuestions() 
    {
        $count = 0;

        foreach($this->questions as $question) 
        {
            if($question->isRight) 
            {
                $count++;
            }
        }

        return $count;
    }

	public function getPercentRight() 
	{
		$all = 0;
		$right = 0;

		foreach ($this->questions as $pq) 
		{
			$all++;
			if ($pq->isRight) 
			{
				$right++;
			}
		}

		return ($all <> 0) ? ceil($right*100/$all) : "- ";
	}

	public function getPercentStep() 
	{
		return ceil(($this->percent * 100) / $this->test->pass_percent);
	}

	public function getMessageStep()
	{
		$list = [
			self::PASSING_PERCENT_RIGHT_ALL => Settings::getValue('message_passing_percent_right_all'),
	        self::PASSING_PERCENT_RIGHT_ALMOST => Settings::getValue('message_passing_percent_right_almost'),
			self::PASSING_PERCENT_RIGHT_CENTER => Settings::getValue('message_passing_percent_right_center'),
	    ];

	    foreach ($list as $percent => $message) 
	    {
	    	if($this->percentStep >= $percent)
		    {
		    	return array('message' => $list[$percent], 'percent' => $percent);
		    }
	    }
	    
	    return;
	}

	public function getTime() 
	{
		if($this->start_date && $this->end_date)
		{
			return (strtotime($this->end_date) - strtotime($this->start_date));
		}
		else
		{
			$time = 0;
			foreach ($this->questions as $q) 
			{
				$time += $q->answer_time;
			}
			return $time;
		}
	}

	public static function declOfNum($number, $titles)
	{
	    $cases = array (2, 0, 1, 1, 1, 2);
	    return $number." ".$titles[ ($number%100 > 4 && $number %100 < 20) ? 2 : $cases[min($number%10, 5)] ];
	}

	public function recountPassResult() 
	{
		if ($this->percent >= $this->test->pass_percent) 
		{
			$this->passed = self::PASSED;
		} 
		else 
		{
			$this->passed = self::FAILED;
		}

		return true;
	}

	public function addPoints()
	{
		if($this->passed == Passing::PASSED)
		{
			$this->points = $this->test->passed_scores;
		}
		else
		{
			$this->points = $this->test->notpassed_scores;
		}

		return true;
	}

	public function afterSave($insert, $changedAttributes)
	{
		parent::afterSave($insert, $changedAttributes);

		$this->initTriggerByTestFinish(['email' => Yii::$app->user->identity->email]);
	}

	/**
	 * @param array $params
	 * @return bool
	 */
	public function initTriggerByTestFinish($params=array()) {
		/** @var TriggerTrigger[] $actualTriggers */
		$actualTriggers = TriggerTrigger::getActualTriggers();
		foreach($actualTriggers as $trigger) {
			$exists = TriggerCondition::find()->where(['trigger_id'=>$trigger->id, 'condition_id'=>(($this->passed==1) ? UserSuccessfullyCompletedTheTest::CONDITION_ID : UserUnsuccessfullyCompletedTheTest::CONDITION_ID)])->exists();
			$count = TriggerCondition::find()->where(['trigger_id'=>$trigger->id])->count();
			// Добавляем в расписание срабатывание триггера завершения теста только при условии что у оно триггера есть и оно там одно
			if ($exists===true && $count==1) {
				$init = $trigger->initAction($params);
				if ($init===true) {
					$curl = curl_init();
					curl_setopt($curl, CURLOPT_URL, Yii::$app->urlManager->createAbsoluteUrl('/triggers/default/rechecktriggers'));
					curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
					if (!curl_exec($curl)) {
						$this->addError('passed', curl_error($curl));
						return false;
					}
					return true;
				} else {
					$this->addError('passed', $init);
					return false;
				}
			}
		}
		return true;
	}
}
