<?php

// TODO: la afisare sume, sa pot sa indic din tabel daca vreau sa faca rotunjiri, si de ex. sa pot introduce precizie (-3) si sa rotunjeasca la mii.

namespace App\QuickReports\PivotTables;

class Content
{

	/**
	 * The rows zone fields with their translation (associative array).
	 * @var array
	 */
	protected $rowsFields = [];

	/**
	 * The key for rows zone indicating the "others" fields.
	 * @var String $otherRowsKey
	 */
	protected $otherRowsKey = null;

	/**
	 * The name displayed for rows zone indicating the "others" fields.
	 * @var String
	 */
	protected $otherRowsText = null;

	/**
	 * The cols zone fields with their translation (associative array).
	 * @var array
	 */
	protected $colsFields = [];

	/**
	 * The key for cols zone indicating the "others" fields.
	 * @var String $otherRowsKey
	 */
	protected $otherColsKey = null;

	/**
	 * The name displayed for cols zone indicating the "others" fields.
	 * @var String
	 */
	protected $otherColsText = null;

	/**
	 * The data zone values (associative array of row->col->value.
	 * @var array
	 */
	protected $data = [];

	/**
	 * The rows total values.
	 * @var array
	 */
	protected $rowsTotals;

	/**
	 * The cols total values.
	 * @var array
	 */
	protected $colsTotals;

	/**
	 * The grand total.
	 * @var Float
	 */
	protected $grandTotal;

	/**
	 * Sets the rows fields.
	 * @param array $rowsFields
	 * @param String $otherRowsKey
	 * @param String $otherRowsText
	 */
	public function setRowsFields(Array $rowsFields, $otherRowsKey = null, $otherRowsText = '')
	{
		$this->rowsFields = $rowsFields;
		if ($otherRowsKey!==null) {
			$this->otherRowsKey = $otherRowsKey;
			$this->otherRowsText = '...';
		}
		if (strlen($otherRowsText)) {
			$this->otherRowsText = $otherRowsText;
		}
	}

	/**
	 * Resets the other rows params (used when we figure out there are no "other rows".
	 */
	public function resetOtherRows()
	{
		$this->otherRowsKey = null;
		$this->otherRowsText = null;
	}


	/**
	 * Returns the rows fields.
	 * @return Array
	 */
	public function getRowsFields()
	{
		return $this->rowsFields;
	}

	/**
	 * Sets the cols fields.
	 * @param array $colsFields
	 * @param String $otherColsKey
	 * @param String $otherColsText
	 */
	public function setColsFields(Array $colsFields, $otherColsKey = null, $otherColsText = '')
	{
		$this->colsFields = $colsFields;
		if ($otherColsKey!==null) {
			$this->otherColsKey = $otherColsKey;
			$this->otherColsText = '...';
		}
		if (strlen($otherColsText)) {
			$this->otherColsText = $otherColsText;
		}
	}

	/**
	 * Resets the other cols params (used when we figure out there are no "other cols".
	 */
	public function resetOtherCols()
	{
		$this->otherColsKey = null;
		$this->otherColsText = null;
	}

	/**
	 * Returns the cols fields.
	 * @return Array
	 */
	public function getColsFields()
	{
		return $this->colsFields;
	}

	/**
	 * Sets the data values.
	 */
	public function setData(array $data)
	{
		$this->data = $data;
	}

	/**
	 * Sets the rows totals.
	 * @param array $totals
	 */
	public function setRowsTotals(Array $totals)
	{
		$this->rowsTotals = $totals;
	}

	/**
	 * Sets the cols totals.
	 * @param array $totals
	 */
	public function setColsTotals(Array $totals)
	{
		$this->colsTotals = $totals;
	}

	/**
	 * Sets the grand total.
	 * @param Float $total
	 */
	public function setGrandTotal($total)
	{
		$this->grandTotal = $total;
	}

	/**
	 * Returns the rows totals.
	 */
	public function getRowsTotals()
	{
		return $this->rowsTotals;
	}

	/**
	 * Returns the cols totals.
	 */
	public function getColsTotals()
	{
		return $this->colsTotals;
	}

	/**
	 * Returns the grand total.
	 */
	public function getGrandTotal()
	{
		return $this->grandTotal;
	}

	/**
	 * Returns the other cols key.
	 * @return String
	 */
	public function getOtherColsKey()
	{
		return $this->otherColsKey;
	}

	/**
	 * Returns the other cols name.
	 * @return String
	 */
	public function getOtherColsText()
	{
		return $this->otherColsText;
	}

	/**
	 * Returns the other rows key.
	 * @return String
	 */
	public function getOtherRowsKey()
	{
		return $this->otherRowsKey;
	}

	/**
	 * Returns the other rows name.
	 * @return String
	 */
	public function getOtherRowsText()
	{
		return $this->otherRowsText;
	}

	/**
	 * Returns a value for a given data cell.
	 * @return Float
	 */
	public function getDataValue($row, $col)
	{
		return $this->data[$row][$col];
	}

	public function getAllData()
	{
		return $this->data;
	}

	/**
	 * Displays a price for debug.
	 * @param Float $price
	 */
	protected function debugPrice($price)
	{
		return \App\Utils\PriceFormat::format($price);
	}

	public function getDisplayMatrix(string $dataFormat='price'): array // TODO: set the correct data format from outside
	{
		// limit the data format
		if (!in_array($dataFormat, ['price', 'int'])) {
			throw new \Exception("Invalid data format: $dataFormat. Supported formats are 'price', 'int'.");
		}

		$table = [];

		// ADD FIRST ROW, COLS LIST, COLS OTHERS AND ROWS TOTALS ----------------------------------
		$firstRow = [];
		$firstRow[] = ['type' => 'firstCell', 'content'=>'', 'format'=>'string'];

		foreach($this->colsFields as $fld) {
			$firstRow[] = ['type' => 'colsList', 'content'=>$fld, 'format'=>'string'];
		}
		if ($this->otherColsKey) {
			$firstRow[] = ['type'=>'colsOthers', 'content'=>$this->otherColsText, 'format'=>'string'];
		}
		if ($this->rowsTotals) {
			$firstRow[] = ['type'=>'rowsTotalsText', 'content'=>'TOTAL', 'format'=>'string'];
		}
		$table[] = $firstRow;

		// ROWS FIELDS AND DATA (TABLE CONTENT) ---------------------------------------------------
		foreach($this->rowsFields as $rowFldCode=>$rowFldName) {
			$row = [];

			$row[] = ['type' => 'rowsList', 'content' => $rowFldName, 'format' => 'string'];

			foreach ($this->colsFields as $colFldCode => $colFldName) {
				$row[] = ['type' => 'data', 'content' => $this->data[$rowFldCode][$colFldCode], 'format' => $dataFormat]; // TODO: or int - depending on column type
			}

			if ($this->otherColsKey) {
				$row[] = ['type' => 'dataColsOthers', 'content' => $this->data[$rowFldCode][$this->otherColsKey], 'format' => $dataFormat];
			}

			if ($this->rowsTotals) {
				$row[] = ['type' => 'rowsTotals', 'content' => $this->rowsTotals[$rowFldCode], 'format' => $dataFormat];
			}

			$table[] = $row;
		}

		// OTHER ROWS DATA (TABLE CONTENT) --------------------------------------------------------
		if ($this->otherRowsKey) {
			$row = [];

			$row[] = ['type' => 'rowsOthers', 'content' => $this->otherRowsText, 'format' => 'string'];

			foreach($this->colsFields as $colFldCode=>$colFldName) {
				$row[] = ['type' => 'dataRowsOthers', 'content' => $this->data[$this->otherRowsKey][$colFldCode], 'format' => $dataFormat];
			}

			if ($this->otherColsKey) {
				$row[] = ['type' => 'dataOthersOthers', 'content' => $this->data[$this->otherRowsKey][$this->otherColsKey], 'format' => $dataFormat];
			}

			if ($this->rowsTotals) {
				$row[] = ['type' => 'rowsOthersTotals', 'content' => $this->rowsTotals[$this->otherRowsKey], 'format' => $dataFormat];
			}

			$table[] = $row;
		}

		// COLS TOTALS (TF) -----------------------------------------------------------------------
		if ($this->colsTotals) {
			$row = [];

			$row[] = ['type' => 'colsTotalsText', 'content' => 'TOTAL', 'format' => 'string']; // TODO: translate "TOTAL" word

			foreach($this->colsFields as $colFldCode=>$colFldName) {
				$row[] = ['type' => 'colsTotals', 'content' => $this->colsTotals[$colFldCode], 'format' => $dataFormat];
			}

			if ($this->otherColsKey) {
				$row[] = ['type' => 'colsOthersTotals', 'content' => $this->colsTotals[$this->otherColsKey], 'format' => $dataFormat];
			}

			$row[] = ['type' => 'grandTotal', 'content' => $this->grandTotal, 'format' => $dataFormat];

			$table[] = $row;
		}

		return $table;
	}

	/**
	 * Displays a simple HTML table containing the pivot table.
	 */
	public function debug()
	{

		echo '<table border="1">';

		echo "<tr>";

		// FIRST ROW (TH) -------------------------------------------------------------------------
		echo "<td>*</td>";

		// add rows fields
		foreach($this->colsFields as $fld) {
			echo "<td>{$fld}</td>";
		}
		if ($this->otherColsKey) {
			echo "<td>{$this->otherColsText}</td>";
		}

		if ($this->rowsTotals) {
			echo "<td>TOTAL</td>";
		}

		// ROWS FIELDS AND DATA (TABLE CONTENT) ---------------------------------------------------
		foreach($this->rowsFields as $rowFldCode=>$rowFldName) {

			echo "<tr>";
			echo "<td>{$rowFldName}</td>";

			foreach($this->colsFields as $colFldCode=>$colFldName) {
				echo "<td>";
				if ($this->data[$rowFldCode][$colFldCode]) {
					echo $this->debugPrice($this->data[$rowFldCode][$colFldCode]);
				} else {
					echo " - ";
				}
				echo "</td>";
			}

			if ($this->otherColsKey) {
				echo "<td>".$this->debugPrice($this->data[$rowFldCode][$this->otherColsKey])."</td>";
			}

			if ($this->rowsTotals) {
				echo "<td>".$this->debugPrice($this->rowsTotals[$rowFldCode])."</td>";
			}

			echo "</tr>";
		}

		// OTHER ROWS DATA (TABLE CONTENT) --------------------------------------------------------
		if ($this->otherRowsKey) {
			echo "<tr>";

			echo "<td>{$this->otherRowsText}</td>";

			foreach($this->colsFields as $colFldCode=>$colFldName) {
				echo "<td>";
				if ($this->data[$this->otherRowsKey][$colFldCode]) {
					echo $this->debugPrice($this->data[$this->otherRowsKey][$colFldCode]);
				} else {
					echo "-";
				}
				echo "</td>";
			}

			if ($this->otherColsKey) {
				echo "<td>{$this->data[$this->otherRowsKey][$this->otherColsKey]}</td>";
			}

			if ($this->rowsTotals) {
				echo "<td>".$this->debugPrice($this->rowsTotals[$this->otherRowsKey])."</td>";
			}

			echo "</tr>";
		}

		// COLS TOTALS (TF) -----------------------------------------------------------------------
		if ($this->colsTotals) {
			echo "<tr>";

			echo "<td>TOTAL</td>";

			foreach($this->colsFields as $colFldCode=>$colFldName) {
				echo "<td>".$this->debugPrice($this->colsTotals[$colFldCode])."</td>";
			}

			if ($this->otherColsKey) {
				echo "<td>".$this->debugPrice($this->colsTotals[$this->otherColsKey])."</td>";
			}

			echo "<td>".$this->debugPrice($this->grandTotal)."</td>";

			echo "<tr>";
		}

		echo "</table>";
	}

}
