<?php

namespace frontend\models;

use Yii;
use yii\base\Model;
use yii\base\Exception;
use common\models\Ticket;
use common\models\Account;
use common\models\TicketType;
use common\models\Transfer;
use common\models\Contract;
use common\models\TicketInstallmentRequest;
use common\models\Discount;
use common\models\ShoppingCart;

/**
 * ContactForm is the model behind the contact form.
 */
class ContractForm extends Model {
	public $name;
	public $birthdate;
	public $birthplace;
	public $mothername;
	public $zip;
	public $city;
	public $address;
	public $bank_account;
	public $bank_name;
	public $phone;
	public $email;
	public $ticket_type;
	public $customer;
	public $payment_method;
	public $id_discount;
	private $ticket;
	private $transfer;
	public $contract;
	public $ticketType;
	private $money;
	private $discount;
	public $started_at;
	public $timestampStart;
	public $idUser;
	public $idAccount;
	/**
	 * @inheritdoc
	 */
	public function rules() {
		return [
				// name, email, subject and body are required
				[ 
						[ 
								'ticket_type',
								'name',
								'birthdate',
								'birthplace',
								'mothername',
								"zip",
								"city",
								"address",
								"bank_account",
								"bank_name",
								'phone',
								'email',
								'payment_method' ,
								'started_at',
								'started_at'
						],
						'required' 
				],
				// email has to be a valid email address
				[ 
						'email',
						'email' 
				],
				[ 
						'ticket_type',
						'integer' 
				],
				[ 
						[ 
								'phone' 
						],
						'string',
						'max' => 20 
				],
				[ 
						[ 
								'bank_account' 
						],
						'string',
						'max' => 24 
				],
				[ 
						[ 
								'bank_account' 
						],
						'validateBankAccount',
				],
				[ 
						[ 
								'bank_name' 
						],
						'string',
						'max' => 100 
				],
				[ 
						[ 
								'mothername',
								'birthplace',
								'name',
								'zip',
								'city',
								'address' 
						],
						'string',
						'max' => 100 
				],
				[ 
						[ 
								'birthdate' 
						],
						'date' 
				],
				[ 
						[ 
								'ticket_type',
								'id_discount',
								'payment_method' 
						],
						'integer' 
				],
				[ 
						[ 
								'ticket_type' 
						],
						'validateTicketType' 
				] ,
				[[ 'started_at',  ], 'date', 'format' =>Yii::$app->formatter->dateFormat  , 'timestampAttribute' => 'timestampStart' ,'timestampAttributeFormat' => 'yyyy-MM-dd' ,'timeZone' => 'UTC' ],
		];
	}
	
	public function validateBankAccount($attribute, $params) {
		if ( !is_numeric($this->bank_account)){
			$this->addError( $attribute, "A bankszámlaszám csak számokat tartalmazhat!");
		}else{
			if ( !( strlen($this->bank_account) == 16 || strlen($this->bank_account) == 24 ) ){
				$this->addError($attribute,"Bankszámlaszám 16 vagy 24 hosszú!");
			}
		}
	}
	
	
	public function validateTicketType($attribute, $params) {
		$this->ticketType = TicketType::findOne ( $this->ticket_type );
		if (! isset ( $this->ticketType )) {
			$this->addError ( $attribute, "Bérlet típus nem található" );
		}else{
			$contracts = Contract::find()
			->andWhere(	['>' ,'contract.expired_at', date('Y-m-d')])
			->andWhere(['not in' ,'contract.flag', Contract::getFlagsDoesNotProhibitNewContract() ])
			->andWhere(['contract.id_customer' => $this->customer->id_customer])->all();
			if ( count($contracts) > 0 ){
				$this->addError( $attribute , "Már van érvényes vagy lemondott szerződés az adott időszakban");
			}
		}
	}
	
	
	/**
	 * @inheritdoc
	 */
	public function attributeLabels() {
		return [ 
				'name' => 'Név',
				'birthdate' => 'Születési dátum',
				'birthplace' => 'Születési hely',
				'mothername' => 'Anyja neve',
				'zip' => 'Irányítószám',
				'city' => 'Város',
				'address' => 'Cím',
				'bank_account' => 'Bankszámlaszám',
				'bank_name' => 'Bank neve',
				'phone' => 'Telefonszám',
				'email' => 'E-mail',
				'ticket_type' => 'Bérlet típus' ,
				'payment_method' => 'Fizetési mód (első bérlet)' ,
				'id_discount' => 'Kedvezmény' ,
				'started_at' => 'Érvényesség kezdete' ,
		];
	}
	public function fillOut() {
		$this->name = $this->customer->name;
		$this->birthdate = isset ( $this->customer->birthdate ) ? \Yii::$app->formatter->asDate ( $this->customer->birthdate ) : '';
		$this->birthplace = $this->customer->birth_place;
		$this->mothername = $this->customer->mother_name;
		$this->zip = $this->customer->zip;
		$this->city = $this->customer->city;
		$this->address = $this->customer->address;
		$this->bank_account = $this->customer->bank_account;
		$this->bank_name = $this->customer->bank_name;
		$this->phone = $this->customer->phone;
		$this->email = $this->customer->email;
	}
	public function make() {
		$this->money = $this->ticketType->price_brutto;
		$this->discount = Discount::findOne($this->id_discount);
		if ( isset($this->discount)){
			$this->money =   Discount::applyDiscount($this->ticketType->price_brutto, $this->discount);
		}
		$this->updateCustomer ();
		
		
		$this->createTicket ();
		$this->createTransfer ();
		$this->appendToCustomerCart();
		$this->addContract();
		
		$this->ticket->id_contract = $this->contract->id_contract;
		
		if ( !$this->ticket->update(false)){
			\Yii::error("Nem sikerült a bérlethez hozzárendelni a szerződést");
			throw new Exception("Hiba történt mentés közben!");
		}
		
		return true;
	}
	public function updateCustomer() {
		$this->customer->name = $this->name;
		$this->customer->birthdate = $this->birthdate;
		$this->customer->birth_place = $this->birthplace;
		$this->customer->mother_name = $this->mothername;
		$this->customer->zip = $this->zip;
		$this->customer->city = $this->city;
		$this->customer->address = $this->address;
		$this->customer->bank_account = $this->bank_account;
		$this->customer->bank_name = $this->bank_name;
		$this->customer->phone = $this->phone;
		$this->customer->email = $this->email;
		
		if (! $this->customer->save ( false )) {
			throw new Exception ( 'nem sikerült a szerződés létrehozása' );
		}
	}
	public function createTicket() {
		
		$ticket = new Ticket ();
		$ticket->id_user = $this->getUserId();
		$ticket->id_account = $this->getAccountId();
		
		$ticket->id_discount = $this->id_discount;
		$ticket->start = $this->started_at;
		$date = new \DateTime ( $this->timestampStart);
		$date->modify ( '+1 month' );
		$date->modify ( '-1 day' );
		$ticket->end = $date->format ( 'Y-m-d H:i:s' );
		$ticket->id_ticket_type = $this->ticketType->id_ticket_type;
		$ticket->price_brutto = $this->money;
		$ticket->max_usage_count = $this->ticketType->max_usage_count;
		$ticket->usage_count = 0;
		$ticket->status = Ticket::STATUS_ACTIVE;
		$ticket->comment = "Szerződéses bérlet";
		$ticket->id_card = $this->customer->card->id_card;
		$ticket->part = 0;
		$ticket->part_paid = 0;
		$ticket->part_count = $this->ticketType->installment_count;
		
		if (! $ticket->save ( false )) {
			\Yii::error ( "A bérlet mentése sikertelen volt" );
			throw new Exception ( "Hiba történt mentés közben" );
		}
		
		$this->ticket = $ticket;
	}
	public function createTransfer() {
		$transfer = new Transfer ();
		$transfer->id_object = $this->ticket->id_ticket;
		$transfer->status = Transfer::STATUS_NOT_PAID;
		$transfer->type = Transfer::TYPE_TICKET;
		$transfer->item_price = $this->money;
		$transfer->count = 1;
		$transfer->money = $this->money;
		$transfer->id_user = $this->getUserId();
		$transfer->comment = "Szerződéses bérlet";
		$transfer->id_account = $this->getAccountId();
		$transfer->direction = Transfer::DIRECTION_IN;
		$transfer->id_customer = $this->customer->id_customer;
		$transfer->payment_method = $this->payment_method;
		$transfer->id_discount = $this->id_discount;
		
		if (! $transfer->save ( false )) {
			\Yii::error ( "A tranzakció mentése sikertelen volt" );
			throw new Exception ( "Hiba történt mentés közben" );
		}
		$this->transfer = $transfer;
	}
	
	public function addContract() {
		if (! $this->ticketType->isInstallment ()) {
			\Yii::error ( "A bérlet típus nem tágmogatja a szerződés kötést!" );
			throw new Exception ( "A bérlet típus nem tágmogatja a szerződés kötést!" );
		}
		
		$contract = new Contract ();
		$contract->id_customer = $this->customer->id_customer;
		$contract->id_user = $this->getUserId();
		$contract->status = Contract::$STATUS_PAID;
		$contract->flag = Contract::$FLAG_ACTIVE;
		$contract->part_count = $this->ticketType->installment_count;
		$contract->part_paid = 0;
		$contract->part_required = 0;
		$contract->started_at = $this->started_at;
		$date = new \DateTime( $this->timestampStart );
		$date->modify ( '+1 year' );
		$date->modify ( '-1 day' );
		$date->setTime(0, 0, 0);
		$contract->expired_at = $date->format ( 'Y-m-d H:i:s' );
		$contract->id_ticket_type = $this->ticketType->id_ticket_type;
		
		if (! $contract->save ( false )) {
			\Yii::error ( "A szerződés mentése sikertelen volt" );
			throw new Exception ( "Hiba történt mentés közben" );
		}
		
		$this->contract = $contract;
		
		$requests = TicketInstallmentRequest::createInstallments ( $this->ticket, $this->ticketType, $this->customer, $contract );
		foreach ( $requests as $request ) {
			$request->save ( false );
			if (! $request->save ( false )) {
				\Yii::error ( "A szerződés részlet mentése sikertelen volt" );
				throw new Exception ( "Hiba történt mentés közben" );
			}
		}
	}
	
	public function appendToCustomerCart(){
    		$item = new ShoppingCart();
    		$item->id_customer = $this->customer->id_customer;
    		$item->id_transfer = $this->transfer->id_transfer;
    		if ( !$item->save(false) ){
    			\Yii::error("Vendég kosár hozzárendelés sikertelen!");
    			throw new Exception ( "Hiba történt mentés közben" );
    		}
    		
    	}
    
    	
    protected function getUserId(){
    	if ( isset($this->idUser)){
    		return $this->idUser;
    	}
    	return \Yii::$app->user->id;
    }
    
    
    protected function getAccountId(){
    	if ( isset($this->idAccount)){
    		return $this->idAccount;
    	}
    	return Account::readDefault();
    }
    
}
