<?php

// TODO: [notImportant] sa caute sugestie in combinatie pasager si checkin date ?!?

namespace App\AutoBalanceServices;

/**
 * The class suggests a balance based on a service id. After you call "process" the class returns:
 * balanceComponent (issue, refund, both), balanceScore, blanceScoreDetails (array)
 * @author Gabriel Grosu
 */
class ServiceBalanceSuggestion
{

	/**
	 * The service id.
	 * @var Int
	 */
	private $idService;

	/**
	 * The name of the db temp table that stores the supplier invoices rows.
	 * @var String
	 */
	private $supplierInvoiceRowsDbTable;

	/**
	 * Indicates which part of the service is included in the balance suggestion: issue/refund/both.
	 * @var String
	 */
	private $balanceComponent;

	/**
	 * Indicates the score of the balance (in percent: (0, 1]).
	 * @var String
	 */
	private $balanceScore;

	/**
	 * Indicates the score details of the balance (array of field=>points).
	 * @var array
	 */
	private $balanceScoreDetails = [];

	/**
	 * Supplier invoices rows list to be associated to the suggested balance.
	 * @var array
	 */
	private $supplierInvoiceRowsList = [];


	/**
	 * Sets the service id.
	 * @param Int $idService
	 */
	public function __construct($idService)
	{
		$this->idService = $idService;
	}

	/**
	 * Sets the supplier invoice rows table (for quicker access).
	 * @param String $supplierInvoiceRowsDbTable
	 */
	public function setSupplierInvoiceRowsDbTable($supplierInvoiceRowsDbTable)
	{
		$this->supplierInvoiceRowsDbTable = $supplierInvoiceRowsDbTable;
	}

	/**
	 * Does the actual search for supplier invoice rows that may be balanced together with the
	 * current service.
	 */
	public function process()
	{

		$suppInvRowsList = $this->getAllMatchingSupplierInvoiceRows();

		// if no matching supplier invoice rows, then
		if (!$suppInvRowsList) {
			return false;
		}

		// determine the score for the current filtered supplier invoice rows.
		$calculateScore = new CalculateScore($this->idService, $suppInvRowsList);
		$calculateScore->process();

		// collect and store the output
		$this->balanceScore = $calculateScore->getBalanceScorePercent();
		$this->balanceScoreDetails = $calculateScore->getBalanceScoreDetails();
		$this->supplierInvoiceRowsList = $calculateScore->getSupplierInvoiceRowsList();
		$this->balanceComponent = $calculateScore->getBalanceComponent();

	}


	/**
	 * Returns all supplier invoice rows that may be matched for the current service.
	 */
	private function getAllMatchingSupplierInvoiceRows()
	{

		$serviceEnt = \Entity\Service::select($this->idService);
		$orderEnt = $serviceEnt->order;
		$offerEnt = $serviceEnt->chosenOffer;

		$db = \DB::getInstance();

		$prepVars = [];
		$getSupplierInvoiceRowsSQL = "
			SELECT idRow
			FROM `{$this->supplierInvoiceRowsDbTable}`
			WHERE reservationId = ?
		";
		$prepVars[] = $orderEnt->getId();
		if ($orderEnt->reservationNumber) {
			$getSupplierInvoiceRowsSQL .= " OR reservationNumber LIKE ?";
			$prepVars[] = $orderEnt->reservationNumber;
		}
		if ($orderEnt->reservationCode) {
			$getSupplierInvoiceRowsSQL .= " OR reservationCode LIKE ?";
			$prepVars[] = $orderEnt->reservationCode;
		}
		$getSupplierInvoiceRowsSQL .= " OR idService = ?";
		$prepVars[] = $serviceEnt->getId();
		if ($offerEnt->externalSystemReservationId) {
			$getSupplierInvoiceRowsSQL .= " OR externalReservationId LIKE ?";
			$prepVars[] = $offerEnt->externalSystemReservationId;
		}
		if ($offerEnt->confirmationNumber) {
			$getSupplierInvoiceRowsSQL .= " OR confirmationNumber LIKE ?";
			$prepVars[] = $offerEnt->confirmationNumber;
		}
		if ($serviceEnt->passengersTicketsList) {
			$prepStmt = [];
			foreach($serviceEnt->passengersTicketsList as $tkt) {
				if ($tkt) {
					$prepStmt[] = "?";
					$prepStmt[] = "?";
					$prepVars[] = $tkt;
					$prepVars[] = $tkt.'R';
				}
			}
			if ($prepStmt) {
				$getSupplierInvoiceRowsSQL .= " OR ticketNo IN (".implode(", ", $prepStmt).")";
			}
		}

		$getSupplierInvoiceRows = $db->GetAll($getSupplierInvoiceRowsSQL, $prepVars);

		if (!is_array($getSupplierInvoiceRows)) {
			throw new \DBException('Could not search for matched supplier invoice rows when auto-balance runs.');
		}

		$return = [];
		foreach($getSupplierInvoiceRows as $rowDet) {
			$return[] = $rowDet['idRow'];
		}

		return $return;

	}



	/**
	 * Returns the service component: issue/refund/both.
	 */
	public function getBalanceComponent()
	{
		return $this->balanceComponent;
	}

	/**
	 * Returns the score details of the current suggestion.
	 */
	public function getBalanceScoreDetails()
	{
		return $this->balanceScoreDetails;
	}

	/**
	 * Returns the score of the current suggestion.
	 */
	public function getBalanceScore()
	{
		return $this->balanceScore;
	}

	/**
	 * Returns the list of supplier invoice rows list from the current suggestion.
	 */
	public function getSupplierInvoiceRowsList()
	{
		return $this->supplierInvoiceRowsList;
	}

}