<?php
namespace ModulesAbstract\ElectronicInvoice\EntityQueueListing;

abstract class Model extends \App\Mvc\Model_ListingAbstract
{
	abstract protected function createListingObj();

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Model_ListingAbstract::list_execute()
	 */
	public function list_execute(\App\Mvc\View\Listing\Members\Params $listingParams)
	{
		$filters = $listingParams->getFilters();

		$listObj = $this->createListingObj();
		$listObj = $this->setColumns($listObj);
		$listObj = $this->applyFilters($listObj, $filters);

		$listObj->setOrderBy('addTime', 'DESC');

		$listObj = $this->entityList_inheritListingParams($listingParams, $listObj);

		$this->recordsList = $this->mapRecords($listObj->exportRecords());
		$this->totalRecordsCount = $listObj->getRecordsCount();
	}

	/**
	 * Sets the columns for the given $listObj.
	 *
	 * @param object $listObj The list object to set the columns for.
	 * @return object The modified $listObj with the updated columns.
	 */
	protected function setColumns($listObj)
	{
		$listObj->setColumns([
			'idInvoice',
			'idDocument',
			'status',

			'invoiceNumber',
			'invoiceDate',
			'idCorporate',
			'idCustomer',

			'addTime',
			'idAddUser',
			'lastUpdateTime',
		]);

		return $listObj;
	}

	/**
	 * Applies filters to a list object.
	 *
	 * @param object $listObj The list object to apply filters to.
	 * @param array $filters The filters to apply.
	 * @return object The list object with applied filters.
	 */
	protected function applyFilters($listObj, $filters)
	{
		if ($filters['addTime']['start']) {
			$listObj->setFilter('addTime', '>=', $filters['addTime']['start'] . " 00:00:00");
		}
		if ($filters['addTime']['end']) {
			$listObj->setFilter('addTime', '<=', $filters['addTime']['end'] . " 23:59:59");
		}

		if ($filters['status']) {
			$listObj->setFilter('status', 'IN', $filters['status']);
		}

		if ($filters['idInvoice']) {
			// Handle both comma and space separated list of IDs
			$list = array_filter(array_map('trim', preg_split('/[\s,]+/', $filters['idInvoice'])));
			if ($list) {
				$listObj->setFilter("idInvoice", 'IN', $list);
			}
		}

		if ($filters['invoiceNumber']) {
			// Handle both comma and space separated list of invoice numbers
			$list = array_filter(array_map('trim', preg_split('/[\s,]+/', $filters['invoiceNumber'])));
			if ($list) {
				$listObj->setFilter('invoiceNumber', 'IN', $list);
			}
		}

		if ($filters['invoiceDate']['start']) {
			$listObj->setFilter('invoiceDate', '>=', $filters['invoiceDate']['start']);
		}

		if ($filters['invoiceDate']['end']) {
			$listObj->setFilter('invoiceDate', '<=', $filters['invoiceDate']['end']);
		}

		if ($filters['idCorporate']['id']) {
			$listObj->setFilter('idCorporate', '=', $filters['idCorporate']['id']);
		}

		if ($filters['idCustomer']['id']) {
			$listObj->setFilter('idCustomer', '=', $filters['idCustomer']['id']);
		}

		if ($filters['clientType'] == 'individual') {
			$listObj->setFilter('idCustomer', '!=', '0');
		}
		elseif ($filters['clientType'] == 'corporate') {
			$listObj->setFilter('idCorporate', '!=', '0');
		}
		// else: any

		return $listObj;
	}

	/**
	 * Maps the given records.
	 *
	 * @param array $records The records to be mapped.
	 * @return array
	 */
	protected function mapRecords($records)
	{
		return $records;
	}

}
