<?php
namespace App\ImportedDocument\EntityMatch;

/**
 * Stores the corporate details for an imported document.
 * @author cristiana.matache
 */
class Corporate extends \App\EntityMatch\Corporate
{

	/**
	 * Forces the overwrite of cleanMatches() which cleans up all matching except 'ordersExtSys'
	 * criterion (if any).
	 */
	use \App\ImportedDocument\EntityMatch\ExtSysCleanMatchesTrait;

	/**
	 * Sets the id of the corporate in external system.
	 * @param String $idEntityExtSys
	 * @param Int $idSystem - the external system id
	 */
	public function setIdInExtSys($idEntityExtSys, $idSystem)
	{
		$this->setSearchCriterion('documentExtSys', $idEntityExtSys, false, ['idSystem'=>$idSystem]);
	}


	/**
	 * Searches for matches using the imported document corporates associations.
	 * @see \App\EntityMatch\Corporate::dispatchSearchRecords()
	 */
	protected function dispatchSearchRecords($field, $value, $useWildcard, Array $options = [])
	{

		if ($field=='documentExtSys') {
			$matchedId = \App\Config\ImportedDocuments\Matches::getInstance()->getCorporate($options['idSystem'], $value);
			if ($matchedId) {
				return $this->searchRecord_primaryKey($matchedId);
			} else {
				return null;
			}
		}
		elseif ($field=='invoicesList') {
			return $this->searchRecord_invoicesList($options['invoicesList']);
		}
		elseif ($field=='importedServicesList') {
			return $this->searchRecord_importedServicesList($options['importedServicesList']);
		}
		elseif ($field=='servicesList') {
			return $this->searchRecord_servicesList($options['servicesList']);
		}
		else {
			return parent::dispatchSearchRecords($field, $value, $useWildcard, $options);
		}

	}


	/**
	 * Set the invoices criterion
	 * @param array $invoicesList
	 * @throws \Exception
	 */
	public function setInvoicesList(Array $invoicesList)
	{
		// check sa fie invoice obj
		foreach ($invoicesList as $invoice) {
			if (!($invoice instanceof \App\ImportedDocument\ClientInvoice) ) {
				throw new \Exception("The invoices must be instance of \App\ImportedDocument\ClientInvoice.");
			}
		}

		$this->setSearchCriterion('invoicesList', true, false, ['invoicesList'=>$invoicesList]);
	}

	/**
	 * Sets the imported services criterion.
	 * @param array $importedServicesList
	 * @throws \Exception
	 */
	public function setImportedServices(Array $importedServicesList)
	{
		// check object types
		foreach ($importedServicesList as $service) {
			if (!($service instanceof \App\ImportedDocument\ImportedService) ) {
				throw new \Exception("The imported services must be instance of \App\ImportedDocument\ImportedService.");
			}
		}

		$this->setSearchCriterion('importedServicesList', true, false, ['importedServicesList'=>$importedServicesList]);
	}


	/**
	 * Sets the services criterion
	 * @param array $servicesList
	 * @throws \Exception
	 */
	public function setServices(Array $servicesList)
	{
		// check the object types
		foreach ($servicesList as $service) {
			if (!($service instanceof \App\ImportedDocument\Service) ) {
				throw new \Exception("The services must be instance of \App\ImportedDocument\Service.");
			}
		}

		$this->setSearchCriterion('servicesList', true, false, ['servicesList'=>$servicesList]);
	}


	/**
	 * Search the corporate by "invoicesList" criterion.
	 * @param array $invoicesList
	 */
	private function searchRecord_invoicesList(Array $invoicesList)
	{

		$return = null;
		$corporatesList = [];

		foreach ($invoicesList as $invoice) {
			$results = $invoice->getMatchedIds();
			foreach ($results as $idInv) {
				$corporatesList[] = \Entity\Invoice::select($idInv)->idCorporate;
			}
		}

		$corporatesList = array_unique($corporatesList);

		if ($corporatesList) {
			$return = [];
			foreach ($corporatesList as $idCorp) {
				$corpEnt =\Entity\Corporate::select($idCorp);
				$return[$idCorp] = [];
				foreach ($this->exportFields as $field) {
					$return[$idCorp][$field] = $corpEnt->$field;
				}

			}
		}

		return $return;

	}

	/**
	 * Collects corporations list based on imported services.
	 * @param array $importedServicesList
	 */
	private function searchRecord_importedServicesList(Array $importedServicesList)
	{

		$return = null;

		// collect importedService-service-relevantInvoice-idCorporate
		$corporatesList = [];
		foreach ($importedServicesList as $impServ) {
			$idImportedService = $impServ->getMatchedId();
			if ($idImportedService) {
				$importedServiceEnt = \Entity\ImportedService::select($idImportedService);
				$idCorp = $importedServiceEnt->serviceTina->relevantInvoice->idCorporate;
				if ($idCorp) {
					$corporatesList[$idCorp] = $idCorp;
				}
			}

		}

		// attach the output
		if ($corporatesList) {
			$return = [];
			foreach ($corporatesList as $idCorp) {
				$corpEnt =\Entity\Corporate::select($idCorp);
				$return[$idCorp] = [];
				foreach ($this->exportFields as $field) {
					$return[$idCorp][$field] = $corpEnt->$field;
				}
			}
		}

		return $return;

	}

	/**
	 * Collects corporations list based on services.
	 * @param array $servicesList
	 */
	private function searchRecord_servicesList(Array $servicesList)
	{

		$return = null;

		$corporatesList = [];
		foreach ($servicesList as $serv) {
			$idServ = $serv->getMatchedId();
			if ($idServ) {
				$serviceEnt = \Entity\Service::select($idServ);
				$idCorp = $serviceEnt->relevantInvoice->idCorporate;
				if ($idCorp) {
					$corporatesList[$idCorp] = $idCorp;
				}
			}

		}

		// attach the output
		if ($corporatesList) {
			$return = [];
			foreach ($corporatesList as $idCorp) {
				$corpEnt =\Entity\Corporate::select($idCorp);
				$return[$idCorp] = [];
				foreach ($this->exportFields as $field) {
					$return[$idCorp][$field] = $corpEnt->$field;
				}
			}
		}

		return $return;

	}

	/***
	 * Loads the criteria from imported doc.
	 * @param \App\ImportedDocument\Cashing $impDocObj
	 */
	public function setFromImportedDocumentObj(\App\ImportedDocument\Cashing $impDocObj)
	{
		if ($impDocObj->getInvoicesList()) {
			$this->setInvoicesList($impDocObj->getInvoicesList());
		}

		if ($impDocObj->getImportedServicesList()) {
			$this->setImportedServices($impDocObj->getImportedServicesList());
		}

		if ($impDocObj->getTinaServicesList()) {
			$this->setServices($impDocObj->getTinaServicesList());
		}
	}

}