<?php

namespace common\models;

use Yii;
use common\components\AccountAwareBehavior;
use common\components\UserAwareBehavior;
use yii\helpers\ArrayHelper;
use yii\behaviors\TimestampBehavior;
use yii\db\Query;
use yii\db\Expression;
use common\components\RoleDefinition;

/**
 * This is the model class for table "collection".
 *
 * @property integer $id_collection
 * @property integer $id_user
 * @property integer $created_by
 * @property integer $id_account
 * @property integer $money
 * @property string $start
 * @property string $end
 * @property integer $type
 * @property string $created_at
 * @property string $updated_at
 */
class Collection extends \common\models\BaseFitnessActiveRecord
{
	
	const TYPE_RECEPTION = 10;
	
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'collection';
    }
    
    /**
     * @inheritdoc
     */
    public function behaviors()
    {
    	return ArrayHelper::merge(  [
    			[
    					'class' => TimestampBehavior::className(),
    					'value' => function(){ return date('Y-m-d H:i:s' ); }
    			],
    			[
    					'class' => UserAwareBehavior::className(),
    			],
    			[
    					'class' => AccountAwareBehavior::className(),
    			],
    			], parent::behaviors());
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['id_user', 'created_by', 'id_account', 'money', 'type'], 'integer'],
            [['money', 'type', 'created_at', 'updated_at'], 'required'],
            [['start', 'end', 'created_at', 'updated_at'], 'safe']
        ];
    }
    
    
    public function getAccount(){
    	return $this->hasOne( Account::className(), ["id_account" =>"id_account" ] ) ;
    }
    
    public function getAccountName(){
    	$result = "";
    	$account = $this->account;
    	if (isset($account)){
    		$result  = $account->name;
    	}
    
    	return $result;
    }
    

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id_collection' => Yii::t('common/collection', 'Id Collection'),
            'id_user' => Yii::t('common/collection', 'Id User'),
            'created_by' => Yii::t('common/collection', 'Created By'),
            'id_account' => Yii::t('common/collection', 'Id Account'),
            'money' => Yii::t('common/collection', 'Money'),
            'start' => Yii::t('common/collection', 'Start'),
            'end' => Yii::t('common/collection', 'End'),
            'type' => Yii::t('common/collection', 'Type'),
            'created_at' => Yii::t('common/collection', 'Created At'),
            'updated_at' => Yii::t('common/collection', 'Updated At'),
        ];
    }
    
    
    /**
     * @param \common\models\User $user the user 
     * */
    public static function readLast($user,$types = [Collection::TYPE_RECEPTION]){
    	$result = null;
    	$query = Collection::find();
    	if ( isset($user)){
    		$query->andWhere(['id_user' =>$user->id]);
    	}
    	$query->andFilterWhere([ 'in', 'type' ,$types]);
    	
    	$query->orderBy(['end' => SORT_DESC]);
    	
    	$query->limit(1);
    	$result = $query->one();
    	
    	return $result;
    }
    
    
    /**
     * 
     * */
public static function mkTotalQuery($mode = 'reception', $start,$end,$idUser,$types,$idAccount){
    	
    	$query = new Query();
    	
    	$query->innerJoin("account",'account.id_account = collection.id_account' );
    	
    	if ( !RoleDefinition::isAdmin() ){
    		$query->innerJoin("user_account_assignment",'collection.id_account = user_account_assignment.id_account' );
    		$query->andWhere(['user_account_assignment.id_user' => Yii::$app->user->id ]);
    		
    		$query->andWhere(['account.type' => Account::TYPE_ALL ]);
    		 
    		if ( RoleDefinition::isReception()){
    			$query->andWhere(['transfer.id_user' => Yii::$app->user->id ]);
    		}
    		
    	}
    	
    	$query->addSelect( [
    			new Expression( ' collection.id_account as account'),
    			new Expression( ' COALESCE(sum( collection.money ) ,0) as money /** collections total money */' )
    	
    	]);
    	$query->from('collection');
    	
    	$query->andFilterWhere([
    			'collection.id_account' => $idAccount,
    			]);

    	$query->andFilterWhere(['collection.id_user' => $idUser]);
    	$query->andFilterWhere(['in' ,'collection.type', $types]);
    	self::inInterval($query, 'collection.end' , $start, $end);
    	
    	$query->groupBy('collection.id_account');
    	
    	return $query;
    	
    	
    }
    
    public static function mkTotalsResultWithAllAvailableAccount($queryResult,$accounts,$accountMap,$idAccount){
    
    	$totals = [];
    	$totals['total'] = 0;
    
    	$totals['accounts'] = [];
    
    	foreach ($accounts as $account){
    		if ( isset($idAccount) &&  is_numeric($idAccount)  && $idAccount != $account->id_account  ){
    			continue ;
    		}
    
    		$accountTotal = [
    		'id_account' => $account->id_account,
    		'label' => 	$account->name,
    		'money' => 0,
    		];
    
    		$item = self::findByAccountInQueryResult($queryResult, $account);
    
    		if ( isset($item)){
    			$accountTotal['money'] = $item['money'];
    		}
    		 
    		$totals['accounts'][] = $accountTotal;
    		$totals['total'] += $accountTotal['money'];
    	}
    	return $totals;
    }
    
    public static function findByAccountInQueryResult( $queryResult, $account ){
    	$result = null;
    	foreach ($queryResult as $item){
    		if( $item['account'] == $account->id_account ){
    			$result = $item;
    		}
    	}
    	return $result;
    }
    
    public static function inInterval($query ,$field , $start,$end ){
    	$query->andFilterWhere([ '>=', $field , $start ]   );
    	$query->andFilterWhere([ '<' , $field  , $end ]   );
    }
    
    
    /**create and execute a "total" query*/
    public static function exTotalQuery($mode,$start,$end,$idUser,$types,$idAccount){
    	$query =  self::mkTotalQuery($mode, $start, $end, $idUser, $types, $idAccount );
    	$command = $query->createCommand();
    	$result = $command->queryAll();
    	return $result;
    }
    
    /**
     *find all transfers which were paid in the period
     * */
    public static function mkReceptionTotal( $start, $end, $idUser, $types, $idAccount, $accounts, $accountMap){
    	$result = [];
    	$queryResult =  self::exTotalQuery('reception', $start, $end, $idUser, $types, $idAccount );
    	$result = self::mkTotalsResultWithAllAvailableAccount($queryResult, $accounts, $accountMap, $idAccount);
    	return $result;
    }
}
