<?php

namespace Modules\Orders\ImportedOrders\ImportOffer;

/**
 * The class is used for inserting a new offer on a TINA service. The offer details are copied
 * from the imported service mentioned in the constructor. The status of the offer may also be set
 * (the offer can be: only inserted, inserted and chosen, inserted, chosen and confirmed.
 * @author Gabi
 */
class Model extends \App\Mvc\ModelAbstract
{

	/**
	 * The TINA service id onto which a new offer is added.
	 * @var Int
	 */
	protected $idService;

	/**
	 * The imported service id (from TINA) from where the (chosen) offer is copied onto the TINA service.
	 * @var Int
	 */
	protected $idImportedService;

	/**
	 * The offer status (indicates if the inserted offer will also be chosen and confirmed).
	 * The value can be: 'insert', 'insertChoose', 'insertChooseConfirm'
	 * @var string
	 */
	protected $offerStatus = 'insert';

	/**
	 * Associates service id and imported service id.
	 * @param Int $idService
	 * @param Int $idImportedService
	 */
	public function __construct($idService, $idImportedService)
	{
		parent::__construct();
		$this->idService = $idService;
		$this->idImportedService = $idImportedService;
	}

	/**
	 * Sets the offer status.
	 * @param String $offerStatus
	 * @throws \Exception - for an invalid status provided.
	 */
	public function setOfferStatus($offerStatus)
	{
		if ( !in_array($offerStatus, ['insert', 'insertChoose', 'insertChooseConfirm']) ) {
			throw new \Exception(sprintf('The offer status `%s` is not valid.', $offerStatus));
		}
		$this->offerStatus = $offerStatus;
	}

	/**
	 * Checks the input (service / imported service id)
	 * @throws \Exception
	 * @throws \App\MessagesException
	 */
	protected function check()
	{

		$msgs = new \App\MessagesCollector();

		if (!\DB::isInsideTransaction()) {
			throw new \Exception('No DB transaction was started. You cannot execute `'.__CLASS__.'` unless you start a transaction before.');
		}

		// CHECK TINA SERVICE /////////////////////////////////////////////////////////////////////
		$serviceEnt = \Entity\Service::selectForUpdate($this->idService);
		if (!$serviceEnt->recordExists()) {
			$msgs->addError($this->lang['index']['msgs']['invalidServiceId']);
		} elseif ($serviceEnt->statusOp=='XX') {
			$msgs->addWarning();
		}

		// CHECK IMPORTED SERVICE /////////////////////////////////////////////////////////////////
		$importedServiceEnt = \Entity\ImportedService::selectForUpdate($this->idImportedService);
		if (!$importedServiceEnt->recordExists()) {
			$msgs->addError($this->lang['index']['msgs']['invalidImpServId']);
		} elseif ($importedServiceEnt->processStatus!='new') {
			$msgs->addWarning($this->lang['index']['msgs']['impServProcessed']);
		}

		// throw exception ifd something went wrong
		if ($msgs->hasErrorOrWarning()) {
			throw new \App\MessagesException($msgs);
		}

	}


	/**
	 * Executes the inserting of offer from imported service.
	 */
	public function execute()
	{
		$this->check();

		// MAIN INITS /////////////////////////////////////////////////////////////////////////////
		$importedServiceEnt = \Entity\ImportedService::selectForUpdate($this->idImportedService);
		$importedServiceObj = $importedServiceEnt->object;
		$importedOfferObj = $importedServiceObj->chosenOffer;
		$serviceSelEnt = \Entity\Service::selectForUpdate($this->idService);

		// ASSOCIATE TINA SERVICE WITH IMPORTED SERVICE ///////////////////////////////////////////
		$serviceUpdateEnt = \Entity\Service::update($this->idService);
		$serviceUpdateEnt->importedServicesRefsInsert = [$this->idImportedService];
		$serviceUpdateEnt->save();

		// INSERT OFFER ///////////////////////////////////////////////////////////////////////////
		$offerEnt = \Entity\Offer::insert();
		$offerItemEnt = \Entity\OfferItem::insert();
		// populate default offer details (what was copied from imported offer)
		$populateOfferObj = new \App\ImportedOrder\PopulateEntity\Offer($importedOfferObj, $offerEnt, $importedServiceEnt->idSystem);
		$populateOfferObj->setOfferItem($offerItemEnt);
		$populateOfferObj->setIdCorporateForCardMatch($serviceSelEnt->order->idCorporateOwner);
		$populateOfferObj->populate();
		// attach offer items and service id
		$offerEnt->offerItems = [$offerItemEnt];
		$offerEnt->idService = $this->idService;
		$offerEnt->idImportedService = $this->idImportedService; // add reference on the new offer for the imported service
		$offerEnt->save();

		$idOffer = $offerEnt->getId();

		// SELECT (AND CONFIRM) OFFER /////////////////////////////////////////////////////////////
		if ($this->offerStatus=='insertChoose' or $this->offerStatus=='insertChooseConfirm') {
			$serviceUpdateEnt = \Entity\Service::update($this->idService);
			$serviceUpdateEnt->chosenOfferId = $idOffer;
			$serviceUpdateEnt->confirmedOffer = ($this->offerStatus=='insertChooseConfirm');
			$serviceUpdateEnt->save();
		}

	}

}

