<?php

namespace common\components;

use yii\base\Object;
use common\models\TicketInstallmentRequest;
use common\components\giro\GiroDETSTATetel;
use common\models\Account;
use common\models\Contract;

/**
 * This is the model class for table "ticket".
 *
 * @property common\components\giro\GiroDETSTATetel $tetel
 * @property common\models\TicketInstallmentRequest $megbizas
 * @property common\models\Ticket $ticket
 * @property common\models\Contract $contract
 *
 *
 */
class DetStatTetelProcessor extends Object {
	/**
	 * A válasz tétel . Ha nincs megadva, automatikus visszautasítjuk a megbízást
	 * */
	public $tetel; // config
	/**
	 * A megbízás. Ha a megbízás már el van fogadva, megszakítjuk a feldolgozást
	 * */
	public $megbizas; // config
	/**
	 * A szerződés. A megbízás hoz tartozó szerződés
	 * */
	public $contract;
	/**
	 * a tételből kiolvasott kód. Lásd extractKodAndStatus
	 * */
	protected $kod;
	/**
	 * Státusz. Az új státusza a megbízásnak a tétel alapján
	 * */
	protected $status;
	/**
	 * A komment. Lásd fillComment metódus
	 * */
	protected $comment;
	/**
	 * A bérlet objectkum, amit elmentettünk
	 * */
	protected $ticket;
	/**
	 * A tranzakció, amit mentettünk
	 * */
	protected $transfer;
	
	protected $eredetiMegbizasStatus;
	
	public function run() {
		
		\Yii::info('Megbízás feldolgozása: megbízás azonosító=' .$this->megbizas->id_ticket_installment_request);
		
		if ($this->isAlreadeyAccepted ()) {
			\Yii::info('A megbízás feldolgozásának megszakítása. A megbízás már elfogadott: megbízás azonosító=' .$this->megbizas->id_ticket_installment_request);
			return;
		}
		
		if ( !isset($this->tetel)){
			\Yii::info('A megbízás feldolgozásának megszakítása. Nincs valaszsor a detsta üzenetben');
			return;
		}
		
		$this->rememberEredetiMegbizasStatus();
		$this->readContract();
		$this->extractKodAndStatus ();
		$this->fillComment();
		
		if ( $this->status == TicketInstallmentRequest::$STATUS_ACCEPTED ){
			$this->buyNewTicket();
		}else{
			$this->doRejectRequest();
		}
		
	}
	
	
	protected function rememberEredetiMegbizasStatus(){
		$this->eredetiMegbizasStatus = $this->megbizas->status;
	}
	
	protected function isEredetiMegbizasStatusFinished(){
		return $this->eredetiMegbizasStatus == TicketInstallmentRequest::$STATUS_ACCEPTED || 
		$this->eredetiMegbizasStatus == TicketInstallmentRequest::$STATUS_ACCEPTED_MANUAL ||
		$this->eredetiMegbizasStatus == TicketInstallmentRequest::$STATUS_REJECTED;
	}
	
	protected function buyNewTicket(){
		\Yii::info('Új bérlet vásárlás folyamant indítása' );
		
		$megbizas = $this->megbizas;
		$customer = $this->contract->customer;
		$card = $customer->card;
		$account = Account::findOne(1);
		$ticketType =  $this->contract->ticketType;
		$discount =  $this->contract->discount;
		
		$ticketSale = new TicketSale(
			[
					  'ticketType'=>  $ticketType,
					  'customer'=>  $customer,
					  'account'=>  $account,
					  'card'=>  $card,
					  'discount'=>  $discount,
					  'contract'=>  $this->contract,
					  'ticketInstallmentRequest' => $megbizas
			]		
		);
		
		$ticketSale->doSale();
		\Yii::info('Bérlet és tranzakció elmentve' );
		
		$this->transfer = $ticketSale->transfer;
		$this->ticket = $ticketSale->ticket;
		
		$this->updateContractOnSuccess();
		$this->updateMegbizasOnSuccess();
		
	}
	
	/**
	 * A szerződés betöltése
	 * */
	protected function readContract(){
		$this->contract = $this->megbizas->contract;
		\Yii::info('Szerződés betöltve. Id:' .$this->contract->id_contract);
	}
	
	
	/**
	 * A megbízás módosítása sikeres detsta üzenet esetén
	 * */
	protected function updateMegbizasOnSuccess(){
		
		\Yii::info('Megbízás frissítése - megbizás elfogadva ' );
		
		$this->megbizas->status =  $this->status;
		$this->megbizas->id_transfer = $this->transfer->id_transfer;
		$this->megbizas->id_ticket = $this->ticket->id_ticket;
		$this->megbizas->request_processed_at = Helper::getDateTimeString();
		$this->megbizas->detsta_answer = $this->kod;
		$this->megbizas->comment = $this->comment;
		
		if ( !$this->megbizas->save(false) ){
			\Yii::error("Nem sikerült menteni a megbízást!");
			throw new \Exception("Nem sikerült menteni a megbízást!");
		}
		\Yii::info("A megbízás elmentve!");
		
	}
	
	/**
	 * Megbízás módosítása , ha a detsta üzenetben a megbízás vissza lett utasítva
	 * */
	protected function updateMegbizasOnFail(){
	
		\Yii::info('Megbázás frissítése - megbízás visszautasítva ' );
		
		$this->megbizas->status =  $this->status;
		$this->megbizas->detsta_answer = $this->kod;
		$this->megbizas->comment = $this->comment;
		$this->megbizas->request_processed_at = Helper::getDateTimeString();
	
		if ( !$this->megbizas->save(false) ){
			\Yii::error("Nem sikerült menteni a megbízást!");
			throw new \Exception("Nem sikerült menteni a megbízást!");
		}
		\Yii::info("A megbízás elmentve!");
	
	}
	
	/**
	 * Szerződés módosítása, ha a detsta üzenetben a  megbízás el lett fogadva
	 * */
	protected function updateContractOnSuccess(){
		\Yii::info('Szerződés frissítése - megbizás elfogadva ' );
		$this->incRequiredParts();
		$this->contract->part_paid = $this->contract->part_paid +1;
		$this->updateContractPaidStatus();
	
		if ( !$this->contract->save(false) ){
			\Yii::error("Nem sikerült menteni a szerződést!");
			throw new \Exception("Nem sikerült menteni a szerződést!");
		}
		\Yii::info("A szerződés elmentve!");
	}
	
	protected function updateContractOnFail(){
		\Yii::info('Szerződés frissítése - megbizás visszautasítva ' );
		$this->incRequiredParts();
		$this->updateContractPaidStatus();
// 		$this->contract->status = Contract::$STATUS_NOT_PAID;
		if ( !$this->contract->save(false) ){
			\Yii::error("Nem sikerült menteni a szerződést!");
			throw new \Exception("Nem sikerült menteni a szerződést!");
		}
		\Yii::info("A szerződés elmentve!");
	}
	
	
	/**
	 * Szerződés 
	 * */
	protected function incRequiredParts(){
		if ( !$this->isEredetiMegbizasStatusFinished() ){
			$this->contract->part_required = $this->contract->part_required +1;
			\Yii::info("Szerződés szükséges megbizások száma növelve");
		}else{
			\Yii::info("Szerződés szükséges megbizások száma nem lett növelve az eredeti státusz miatt");
		}
	}
	
	protected function updateContractPaidStatus(){
		$required = $this->contract->part_required;
		$paid = $this->contract->part_paid;
		$ok = $required <= $paid;
		if ($ok ){
			$this->contract->status = Contract::$STATUS_PAID;
		}else{
			$this->contract->status = Contract::$STATUS_NOT_PAID;
		}
		\Yii::info("Szerződés új státusza id= " .$this->contract->id_contract . ", Státusz: " . $this->contract->status  . " (" . Contract::toStatusName($this->contract->status) . ")");
	}
	
	/**
	 * Szerződés és megbízás frissítése , ha a detsta üzenet visszautásításra került
	 * */
	protected function doRejectRequest(){
		$this->updateContractOnFail();
		$this->updateMegbizasOnFail();
	}
	
	/**
	 * Komment összeállítás a status mező alapján
	 * */
	protected function fillComment() {
		$this->comment = "Megbízás teljesítve";
		if ($this->status != TicketInstallmentRequest::$STATUS_ACCEPTED) {
			if ($this->kod == "xx") {
				$this->comment = "Nem található a detsta fájlban a tétel válasza";
			} else {
				if (array_key_exists ( $this->kod, GiroDETSTATetel::$INFORMACIOK )) {
					$this->comment = "Hiba kód: " . $this->kod . " - " . GiroDETSTATetel::$INFORMACIOK [$this->kod];
				} else {
					$this->comment = "Ismeretlen hiba kód: " . $this->kod;
				}
			}
		}
	}
	
	/**
	 * Visszajelző kód kiolvasása a detsta tételből.
	 * Status beállítása a kód alapján
	 * */
	protected function extractKodAndStatus() {
		\Yii::info('Visszajelző kód kiolvasása' );
		$this->status = TicketInstallmentRequest::$STATUS_REJECTED;
		$this->kod = 'xx';
		if (isset ( $this->tetel )) {
			$this->kod = $this->tetel->visszajelzesInformacio;
		}
		if ($this->kod == GiroDETSTATetel::$INFORMACIO_TELJESITETT) {
			$this->status = TicketInstallmentRequest::$STATUS_ACCEPTED;
		} else {
			$this->status = TicketInstallmentRequest::$STATUS_REJECTED;
		}
		\Yii::info('Visszajelző kód kiolvasva: kod=' .$this->kod);
		\Yii::info('Visszajelző kód kiolvasva: statusz=' .$this->status. " (" . TicketInstallmentRequest::toStatusName($this->status)  .")");
	}
	protected function isAlreadeyAccepted() {
		return $this->megbizas->isStatusAccepted ();
	}
	public function hasError() {
		return false;
	}
}