<?php

namespace common\models;

use Yii;
use yii\db\ActiveRecord;
use yii\db\Query;
use yii\db\Expression;
use common\components\Helper;

/**
 * This is the model class for table "ticket".
 *
 * @property integer $id_ticket
 * @property integer $id_user
 * @property integer $id_ticket_type
 * @property integer $id_account
 * @property integer $id_discount
 * @property integer $id_card
 * @property string $start
 * @property string $end
 * @property integer $max_usage_count
 * @property integer $usage_count
 * @property integer $status
 * @property integer $price_brutto
 * @property integer $part eddig a részletig kell kifizetve lenni
 * @property integer $part_count ennyi részlet van összesen
 * @property integer $part_paid ennyi részlet van kifizetve
 * @property string $comment
 * @property string $created_at
 * @property string $updated_at
 */
class Ticket  extends \common\models\BaseFitnessActiveRecord
{
	const STATUS_DELETED = 0;
	const STATUS_ACTIVE = 10;
	const STATUS_INACTIVE = 20;
	
	public static $SQL_UPDATE = "UPDATE card as c1
			left JOIN (  select  ticket.id_card as id_card , max(ticket.id_ticket) as id_ticket
 			from ticket 
			where ticket.start <= CURDATE() 
				and ticket.end >= curdate() 
                and ticket.status = 10 
				and ticket.count_move_out < ticket.max_usage_count                 
                group by id_card               
			order by id_card desc 
						 ) as t 
			on t.id_card = c1.id_card
			SET c1.flag  = case when t.id_card is null then ( c1.flag | 1 << 0  )  else ( c1.flag & ~(1 << 0)  )    end
            , c1.id_ticket_current = case when t.id_ticket is null then null else t.id_ticket end
			WHERE c1.type <> 50";
	
	public static $SQL_UPDATE_CARD = "UPDATE card as c1
			left JOIN (   select  ticket.id_card as id_card , max(ticket.id_ticket) as id_ticket
 			from ticket 
			where ticket.start <= CURDATE() 
				and ticket.end >= curdate() 
                and ticket.status = 10 
				and ticket.count_move_out < ticket.max_usage_count
				and ticket.id_card = :id
                group by id_card               
			order by id_card desc 
				) as t 
			on t.id_card = c1.id_card
			SET c1.flag  = case when t.id_card is null then ( c1.flag | 1 << 0  )  else ( c1.flag & ~(1 << 0)  )    end
            , c1.id_ticket_current = case when t.id_ticket is null then null else t.id_ticket end
			WHERE c1.type <> 50 and c1.id_card = :id";
	
	
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'ticket';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [[ 'id_user', 'id_ticket_type', 'id_account', 'id_discount', 'max_usage_count', 'usage_count', 'status', 'price_brutto'], 'integer'],
            [['start', 'end', 'created_at', 'updated_at'], 'safe'],
            [['comment'], 'required'],
            [['comment'], 'string', 'max' => 255],
        		
        	[[ 'start', ], 'date'  , 'timestampAttribute' => 'timestampStart' ,'timestampAttributeFormat' => 'yyyy-MM-dd'  ],
        	[[ 'end' , ], 'date'    , 'timestampAttribute' => 'timestampEnd' ,'timestampAttributeFormat' => 'yyyy-MM-dd'  ],
        	
        		
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id_ticket' => Yii::t('common/ticket', 'Bérlet azonosító'),
            'id_user' => Yii::t('common/ticket', 'Id User'),
            'id_ticket_type' => Yii::t('common/ticket', 'Id Ticket Type'),
            'id_account' => Yii::t('common/ticket', 'Id Account'),
            'id_discount' => Yii::t('common/ticket', 'Id Discount'),
            'start' => Yii::t('common/ticket', 'Start'),
            'end' => Yii::t('common/ticket', 'End'),
            'max_usage_count' => Yii::t('common/ticket', 'Max Usage Count'),
            'usage_count' => Yii::t('common/ticket', 'Usage Count'),
            'status' => Yii::t('common/ticket', 'Status'),
            'price_brutto' => Yii::t('common/ticket', 'Price Brutto'),
            'comment' => Yii::t('common/ticket', 'Comment'),
            'created_at' => Yii::t('common/ticket', 'Created At'),
            'updated_at' => Yii::t('common/ticket', 'Updated At'),
            'id_card' => Yii::t('backend/ticket','Card'),
            'id_customer' => Yii::t('backend/ticket','Customer'),
        		'payment_method' => Yii::t('common/transfer', 'Fizetési mód'),
        ];
    }
    

    public function getCard(){
    	return $this->hasOne( Card::className(), ["id_card" =>"id_card" ] );
    }
    public function getCardNumber(){
    $result = "";
    $card = $this->card;
    if ( isset($card)){
    	$result = $card->number;
    }
    return $result;
    }
    
    public function getCustomer(){
    	return $this->hasOne( Customer::className(), ["id_customer_card" =>"id_card" ] )->via('card');
    }
    
    public function getCustomerName(){
    	$result = "";
    	$customer = $this->customer;
    	if ( isset($customer)){
    		$result = $customer->name;
    	}
    	return $result;
    }

    public function getUser(){
    	return $this->hasOne( User::className(), ["id" =>"id_user" ] );
    }
    
    public function getTicketType(){
    	return $this->hasOne( TicketType::className(), ["id_ticket_type" =>"id_ticket_type" ] );
    }
    public function getDiscount(){
    	return $this->hasOne( Discount::className(), ["id_discount" =>"id_discount" ] );
    }
    
    public function getAccount() {
    	return $this->hasOne ( Account::className (), [
    			'id_account' => 'id_account'
    			] );
    }
    public function getAccountName() {
    	$result = "";
    	$account = $this->account;
    	if ( isset($account) ){
    		$result = $this->account->name;
    	}
    	return $result;
    }
    public function getDiscountName() {
    	$result = "";
    	$discount = $this->discount;
    	if ( isset($discount) ){
    		$result = $this->discount->name;
    	}
    	return $result;
    }
    public function getTicketTypeName() {
    	$result = "";
    	$ticketType = $this->ticketType;
    	if ( isset($ticketType) ){
    		$result = $ticketType->name;
    	}
    	return $result;
    }
    public function getUserName() {
    	$result = "";
    	$user = $this->user;
    	if ( isset($user) ){
    		$result = $user->username;
    	}
    	return $result;
    }
    
    
    /**
     * @param common\models\Card $card the card to which we are looking for
     * */
    public static function readActive($card){
    	
    	if ( $card == null )
    		return [];
    	
		$query = Ticket::find();
		$today = date('Y-m-d');

		$query->andWhere(['ticket.id_card' => $card->id_card]);
		$query->andWhere( 'ticket.start <= :today' ,[ 'today' => $today] );
		$query->andWhere( 'ticket.end >= :today' ,[ 'today' => $today] );
		$query->andWhere( 'ticket.status = :status' ,[ 'status' => Ticket::STATUS_ACTIVE] );
		$query->orderBy([  "ticket.created_at"  =>SORT_DESC]  );		
		$result  = $query->all();

		return $result;
		
    }
    
    
    public static function mkStatisticQuery($start,$end,$id_card = null){
 
    	
    	$query = new Query();
    	$query->addSelect( [
    			new Expression( 'ticket_type.id_ticket_type as id'),
    			new Expression( 'ticket_type.name as name'),
    			new Expression( 'coalesce( count(ticket.id_ticket),0) as total'),
    			
    			new Expression( "coalesce( sum( case when ticket.status <> " .Ticket::STATUS_DELETED ." AND ". Helper::sqlValidRule('ticket.start', 'ticket.end', ':start', ':end') . " then 1 else 0 end) , 0) as valid" ), //valid
    			new Expression( "coalesce( sum( case when ticket.status <> " .Ticket::STATUS_DELETED ." AND ". Helper::sqlInIntervalRule('ticket.created_at', ':start', ':end') . " then 1 else 0 end)  , 0) as created" ),//created
    			new Expression( "coalesce( sum( case when ticket.status <> " .Ticket::STATUS_DELETED ." AND ". Helper::sqlInIntervalRule('ticket.created_at', ':start', ':end') . " then transfer.money else 0 end)  , 0) as created_money" ),//created_money
    			new Expression( "coalesce( sum( case when ticket.status <> " .Ticket::STATUS_DELETED ." AND " . Helper::sqlExpireRule('ticket.start', 'ticket.end', ':start', ":end")  . " then 1 else 0 end)  , 0) as expired" ),
    			
    			
    	]);
    	
    	$query->from('ticket_type');
    	$query->innerJoin('ticket', 'ticket.id_ticket_type = ticket_type.id_ticket_type');
    	$query->innerJoin('transfer', 'ticket.id_ticket = transfer.id_object and transfer.type = '. Transfer::TYPE_TICKET );
    	
    	Helper::queryAccountConstraint($query, 'ticket.id_account');
    	
    	$query->andFilterWhere(['id_card' =>$id_card]);
    	
    	$query->andWhere(
			[
    			'or',
    			Helper::queryInIntervalRule('ticket.created_at', $start, $end),
    			Helper::queryValidRule('ticket.start', 'ticket.end', $start, $end),
    			Helper::queryExpireRule('ticket.start', 'ticket.end', $start, $end),
			]
    	);
    	
    	
    	$query->groupBy("ticket_type.id_ticket_type, ticket_type.name");
    	
    	$query->params([':start' => $start, ':end' => $end]);
    	
    	return $query;
    }
    
    public static function statuses( ) {
    	return [
    		Ticket::STATUS_ACTIVE => 'Aktív',	
    		Ticket::STATUS_DELETED => 'Törölve',	
    		Ticket::STATUS_INACTIVE => 'Inaktív',	
    	];
    }
 
    public static function toStatusName($id_status){
    	$result = "Ismeretlen";
    	$statuses = Ticket::statuses();
    	if ( array_key_exists($id_status, $statuses)){
    		$result = $statuses[$id_status];
    	}
    	return $result;
    }
    
    public function getStatusName(){
    	return static::toStatusName($this->status);
    }
    
    public function isDeleted(){
    	return $this->status == Ticket::STATUS_DELETED;
    }
    
    /**csoportos beszedéses a bérlet*/
    public function isInstallmentTicket(){
    	return   ( isset($this->part_count) && $this->part_count > 0 );
    }
    
    /**
     * Apply request
     * 
     * @var common\models\TicketInstallmentRequest $request megbízás
     * */
    public function applyTicketInstallmentRequest( $request ) {
    	//ha csoportos beszedéses
    	if ( $this->isInstallmentTicket() ){
    		if ( $request->isStatusAccepted() ){
				if ( $this->part_paid < $request->priority ){
					$this->part_paid = $request->priority;
				}
	    		$this->recalclulate();
    		}else if ( $request->isStatusRejected() ){
				$this->status = static::STATUS_INACTIVE;    			
    		}
    	}
    }
    /*
     * * 
     * @param common\models\TicketInstallmentRequest $request megbízás
     */
    public function setPartRequired($request){
    	// ha keveseb a részlet sorszám mint a bérlet max sorszáma
    	if ( $request->priority <= $this->part_count ){
    		//ha az aktuális elvárt részlet kisebb , mint a megbízása
    		if ( $this->part < $request-> priority ){
    			$this->part = $request->priority;
    		}
    	}
    }
    
    /**
     * Csoportos beszedéses bérlet érvényességének újraszámolása
     * */
    public function recalclulate( ) {
    	if ( $this->isInstallmentTicket()  ){
	    	$enabled = $this->part_paid >= $this->part;
	    	if ( $enabled == true ){
	    		$this->status = static::STATUS_ACTIVE;
	    	}else{
	    		$this->status = static::STATUS_INACTIVE;
	    	}
    	}
    }
    
    public function afterSave($insert, $changedAttributes) {
    	Card::updateCardFlagTicket($this->id_card);;
    }
    
    public function afterDelete(){
    	Card::updateCardFlagTicket($this->id_card);;
    }
    
    
    
}
