<?php

namespace App\Reports\Generation;

class SortingManager
{

	/**
	 * The report main criterion is visible or not.
	 * Used for report templates but not for report generations.
	 */
	public ?bool $mainCriterionVisible;

	/**
	 * The report secondary criterion is visible or not.
	 * Used for report templates but not for report generations.
	 */
	public ?bool $secCriterionVisible;

	/**
	 * The report third criterion is visible or not.
	 * Used for report templates but not for report generations.
	 */
	public ?bool $thirdCriterionVisible;

	/**
	 * The report grouping is visible or not to the user.
	 * Used for report templates but not for report generations.
	 */
	public ?bool $groupByCriterionVisible;

	/**
	 * The column code used as main criterion for ordering the report records.
	 * Used in conjunction with the `mainCriterionOrderDirection` property.
	 */
	public ?string $mainCriterionColumn;

	/**
	 * The column code used as secondary criterion for ordering the report records.
	 * Used in conjunction with the `secCriterionOrderDirection` property.
	 */
	public ?string $secCriterionColumn;

	/**
	 * The column code used as third criterion for ordering the report records.
	 * Used in conjunction with the `thirdCriterionOrderDirection` property.
	 */
	public ?string $thirdCriterionColumn;

	/**
	 * The direction of the main criterion for ordering the report records.
	 * Used in conjunction with the `mainCriterionColumn` property.
	 * The value can be either 'ASC' or 'DESC'. It must be set when the corresponsing column code is set.
	 */
	public ?string $mainCriterionOrderDirection;

	/**
	 * The direction of the secondary criterion for ordering the report records.
	 * Used in conjunction with the `secCriterionColumn` property.
	 * The value can be either 'ASC' or 'DESC'. It must be set when the corresponsing column code is set.
	 */
	public ?string $secCriterionOrderDirection;

	/**
	 * The direction of the third criterion for ordering the report records.
	 * Used in conjunction with the `thirdCriterionColumn` property.
	 * The value can be either 'ASC' or 'DESC'. It must be set when the corresponsing column code is set.
	 */
	public ?string $thirdCriterionOrderDirection;

	/**
	 * Indicates if the report records should be grouped by a certain column. The columns is
	 * indicated by the 'main', 'sec' or 'third' value - these are the only valid values. If left
	 * null, we assume that the report records will not be grouped.
	 * @var string
	 */
	public ?string $groupBy;


	/**
	 * Checks if the class properties are valid and if the sorting params are correctly set.
	 * Does not consider the column codes as this depends on the report source.
	 * @return void
	 */
	public function check() :void
	{
		// check order directions
		if ($this->mainCriterionColumn and !in_array($this->mainCriterionOrderDirection, ['ASC', 'DESC'])) {
			throw new \App\Reports\Generation\Exception('The main criterion order direction is not valid. It must be either `ASC` or `DESC`.');
		}
		if ($this->secCriterionColumn and !in_array($this->secCriterionOrderDirection, ['ASC', 'DESC'])) {
			throw new \App\Reports\Generation\Exception('The secondary criterion order direction is not valid. It must be either `ASC` or `DESC`.');
		}
		if ($this->thirdCriterionColumn and !in_array($this->thirdCriterionOrderDirection, ['ASC', 'DESC'])) {
			throw new \App\Reports\Generation\Exception('The third criterion order direction is not valid. It must be either `ASC` or `DESC`.');
		}

		// check that the criterion column are defined in-chain
		if ($this->secCriterionColumn and !$this->mainCriterionColumn) {
			throw new \App\Reports\Generation\Exception('You must set the main criterion column before setting the secondary one.');
		}
		if ($this->thirdCriterionColumn and (!$this->mainCriterionColumn or !$this->secCriterionColumn)) {
			throw new \App\Reports\Generation\Exception('You must set the main and secondary criterion columns before setting the third one.');
		}

		// check that the criterion columns do not contain duplicates
		$cleanCriteriaList = array_filter( [ $this->mainCriterionColumn, $this->secCriterionColumn, $this->thirdCriterionColumn ] );
		if (count($cleanCriteriaList)!=count(array_unique($cleanCriteriaList))) {
			throw new \App\Reports\Generation\Exception('You cannot reuse the same column for the main, secondary and third criterion.');
		}

		// check grouping
		switch ($this->groupBy) {
			case null:
				// no grouping, so nothing to check
				break;
			case 'main':
				if (!$this->mainCriterionColumn) {
					throw new \App\Reports\Generation\Exception('The main criterion column must be set when grouping by it.');
				}
				break;
			case 'sec':
				if (!$this->secCriterionColumn) {
					throw new \App\Reports\Generation\Exception('The secondary criterion column must be set when grouping by it.');
				}
				break;
			case 'third':
				if (!$this->thirdCriterionColumn) {
					throw new \App\Reports\Generation\Exception('The third criterion column must be set when grouping by it.');
				}
				break;
			default:
				throw new \App\Reports\Generation\Exception('The grouping value is not valid. It must be either null, `main`, `sec` or `third`.');
		}
	}

//	public function importFromReportGeneration(\Entity\ReportGeneration $reportGen) :void
//	{
//		$this->mainCriterionVisible = $reportGen->sorting['mainCriterionVisible'] ?? null;
//		$this->secCriterionVisible = $reportGen->sorting['secCriterionVisible'] ?? null;
//		$this->thirdCriterionVisible = $reportGen->sorting['thirdCriterionVisible'] ?? null;
//		$this->groupByCriterionVisible = $reportGen->sorting['groupByCriterionVisible'] ?? null;
//
//		$this->mainCriterionColumn = $reportGen->sorting['mainCriterionColumn'] ?? null;
//		$this->secCriterionColumn = $reportGen->sorting['secCriterionColumn'] ?? null;
//		$this->thirdCriterionColumn = $reportGen->sorting['thirdCriterionColumn'] ?? null;
//
//		$this->mainCriterionOrderDirection = $reportGen->sorting['mainCriterionOrderDirection'] ?? null;
//		$this->secCriterionOrderDirection = $reportGen->sorting['secCriterionOrderDirection'] ?? null;
//		$this->thirdCriterionOrderDirection = $reportGen->sorting['thirdCriterionOrderDirection'] ?? null;
//
//		$this->groupBy = $reportGen->sorting['groupBy'] ?? null;
//
//	}

}