<?php

namespace App\Webhook;

/**
 * Based on a provided entity, and its last send value, the class decides if the request should be
 * made again and also provides the new value to be stored as "lastSentValue" for future processing.
 * @author Gabriel
 */
class EntityChanged
{

	/**
	 * The current entity type
	 * @var string
	 */
	private $entity;

	/**
	 * The curret entity id.
	 * @var int
	 */
	private $id;

	/**
	 * The current entity action.
	 * @var string
	 */
	private $action;

	/**
	 * The last sent value for the current entity. It's not always filled in, only in some cases; eg. when
	 * updating cashedStatus for an invoice, it checks if the invoice status has actually changed or not.
	 * @var mixed
	 */
	private $lastSentValue;

	/**
	 * Indicates if the webhook should be sent.
	 * @var boolean
	 */
	private $shouldNotify = null;

	/**
	 * The new value that is indicated via the webhook; after the webhook is sent, the new value becomes lastSentValue.
	 * @var mixed
	 */
	private $newSendValue = null;

	public function __construct(string $entity, int $id, string $action, $lastSentValue)
	{
		$this->entity			= $entity;
		$this->id				= $id;
		$this->action			= $action;
		$this->lastSentValue	= $lastSentValue;
	}

	/**
	 * Decides if the webhook should be sent; fills in the shouldNotify and newSendValue attributes.
	 * @throws \Exception
	 */
	public function process()
	{

		switch ($this->entity) {

			// CORPORATE / CUSTOMER / SUPPLIER ----------------------------------------------------
			case 'Corporate': case 'Customer': case 'Supplier':
				$this->shouldNotify_partners();
			break;

			// SERVICE  ---------------------------------------------------------------------------
			case 'Service':
				$this->shouldNotify_service();
			break;

			// INVOICE ----------------------------------------------------------------------------
			case 'Invoice':
				$this->shouldNotify_invoice();
			break;

			// INVOICE CASHING --------------------------------------------------------------------
			case 'InvoiceCashing':
				$this->shouldNotify_invoiceCashing();
			break;

			// DOCUMENT ---------------------------------------------------------------------------
			case 'Document':
				$this->shouldNotify_document();
			break;

			default:
				throw new \Exception("Entity `{$this->entity}` not treated by webhook requests. Should it?");

		}

	}

	/**
	 * Returns the shouldNotify attribute, after process was executed.
	 * @return boolean
	 */
	public function shouldNotify()
	{
		return $this->shouldNotify;
	}

	/**
	 * Returns the newSendValue attribute, after process was executed.
	 * @return boolean
	 */
	public function getNewSendValue()
	{
		return $this->newSendValue;
	}


	private function shouldNotify_partners()
	{
		$this->shouldNotify = true;
	}


	private function shouldNotify_service()
	{

		switch ($this->action) {

			case 'insert': case 'update':
				$this->shouldNotify = true;
			break;

			case 'statusOp':
				$serviceEnt = \Entity\Service::selectForUpdate($this->id);
				$this->shouldNotify = ($serviceEnt->statusOp!=$this->lastSentValue);
				$this->newSendValue = $serviceEnt->statusOp;
			break ;

			case 'statusFin':
				$serviceEnt = \Entity\Service::selectForUpdate($this->id);
				$this->shouldNotify = ($serviceEnt->statusFin!=$this->lastSentValue);
				$this->newSendValue = $serviceEnt->statusFin;
			break;

			case 'cashedStatus':
				$serviceEnt = \Entity\Service::selectForUpdate($this->id);
				$this->shouldNotify = ($serviceEnt->invoicesCashedStatus!=$this->lastSentValue);
				$this->newSendValue = $serviceEnt->invoicesCashedStatus;
			break;

			default:
				throw new \Exception("Entity-action `{$this->entity}`-`{$this->action}` not treated by webhook requests. Should it?");
		}

	}


	private function shouldNotify_invoice()
	{

		switch ($this->action) {
			case 'insert': case 'update': case 'cancel':
				$this->shouldNotify = true;
			break;
			case 'issue':
				$invoiceEnt = \Entity\Invoice::selectForUpdate($this->id);
				$this->shouldNotify = ($invoiceEnt->issueTime!=$this->lastSentValue);
				$this->newSendValue = $invoiceEnt->issueTime;
			break;

			case 'cashedStatus':
				$invoiceEnt = \Entity\Invoice::selectForUpdate($this->id);
				$this->shouldNotify = ($invoiceEnt->cashedStatus!=$this->lastSentValue);
				$this->newSendValue = $invoiceEnt->cashedStatus;
			break;

			default:
				throw new \Exception("Entity-action `{$this->entity}`-`{$this->action}` not treated by webhook requests. Should it?");
		}

	}


	private function shouldNotify_invoiceCashing()
	{

		switch ($this->action) {

			case 'insert': case 'update': case 'cancel':
				$this->shouldNotify = true;
			break;

			case 'issue':
				$invoiceCashingEnt = \Entity\InvoiceCashing::selectForUpdate($this->id);
				$this->shouldNotify = ($invoiceCashingEnt->issueTime!=$this->lastSentValue);
				$this->newSendValue = $invoiceCashingEnt->issueTime;
			break;

			case 'blockStatus':
				$invoiceCashingEnt = \Entity\InvoiceCashing::selectForUpdate($this->id);
				$this->shouldNotify = ($invoiceCashingEnt->blockTime!=$this->lastSentValue);
				$this->newSendValue = $invoiceCashingEnt->blockTime;
			break;

			default:
				throw new \Exception("Entity-action `{$this->entity}`-`{$this->action}` not treated by webhook requests. Should it?");
		}
	}


	private function shouldNotify_document()
	{

		switch ($this->action) {

			case 'insert':
				$this->shouldNotify = true;
			break;

			default:
				throw new \Exception("Entity-action `{$this->entity}`-`{$this->action}` not treated by webhook requests. Should it?");
		}
	}



}