<?php

namespace App\Dashboard\Widget;

class Charts_EstimatedDailyBalance extends Charts_GeneralAbstract
{
	use Traits\FinancialWidget;

	/**
	 * {@inheritDoc}
	 * @see \App\Dashboard\Widget\Charts_GeneralAbstract::getTemplatePath()
	 */
	public function getTemplatePath()
	{
		return  APP_REAL_PATH."/_templates/application/dashboard/widgets/D3Charts/column.tpl";
	}

	/**
	 * {@inheritDoc}
	 * @see \App\Dashboard\Widget\Charts_GeneralAbstract::defineChart()
	 */
	protected function defineChart()
	{

		$chart = new \App\QuickReports\Charts\Types\Column();
//		$chart->setPivotSource('OrderServices');

		$_LANG = \App\Loader_Lang::getInstance()->getAll();

		// manually selected currency, existing currency is default
		if ($this->getOption('reportCurrency')=='work') {
			$reportCurrency = 'work';
			$currency = \App\Config\Currencies::getInstance()->getWorkCurrency();
		} else {
			$reportCurrency = 'default';
			$currency = \App\Config\Currencies::getInstance()->getDefaultCurrency();
		}

		$chart->setTitle($_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\Charts_EstimatedDailyBalance']['chartTitle']);
		$chartDescription = sprintf( $_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\Charts_EstimatedDailyBalance']['chartDescription1'], $currency );
		$chartDescription .= '<br />' . $_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\Charts_EstimatedDailyBalance']['chartDescription2'];
		$chart->setDescription($chartDescription);
		$chart->setDataSetsDisplayGrouping('clustered');

		// get and manually set the chart dataSets
		$records = $this->getRecords($reportCurrency);
		$dataSets = $this->getDataSets($records);
		$chart->setDataSetsManually( $dataSets );

		return $chart;

	}


	/**
	 * Returns the raw data sets for this chart.
	 * @return array
	 */
	private function getRecords($reportCurrency)
	{
		$duePayVal = "duePayDef";
		// if the currency is set to work
		if ($reportCurrency == 'work') {
			$duePayVal = "duePayWrk";
		}

		// GET DATA FROM DB ///////////////////////////////////////////////////////////////////////
		global $DBTPivotTablesData_clientInvoiceRows, $DBTPivotTablesData_supplierInvoiceRows;

		$startDate = TODAY_ISO;
		$endDate = \Engine\DateTime::create('+45 days')->formatDateIso();

		// get planned income invoices
		$dailyIncomeSQL = "
			SELECT IF(dueDate IS NOT NULL, dueDate, invoiceDate) AS invDate, SUM($duePayVal) AS totalValue
			FROM `$DBTPivotTablesData_clientInvoiceRows`
			WHERE
				(
					( dueDate IS NOT NULL AND (dueDate BETWEEN ? AND ?) )
					OR
					( dueDate IS NULL AND (invoiceDate BETWEEN ? AND ?) )
				)
				AND invoiceVoidDate IS NULL AND cashedStatus IN ('n', 'p') AND invoiceIssueDate IS NOT NULL
			GROUP BY invDate
		";
		$dailyIncome = $this->executeAndCacheSql($dailyIncomeSQL, [ $startDate, $endDate, $startDate, $endDate ]);

		// get planned expenses invoices
		$dailyExpenseSQL = "
			SELECT IF(dueDate IS NOT NULL, dueDate, invoiceDate) AS invDate, SUM($duePayVal) AS totalValue
			FROM `$DBTPivotTablesData_supplierInvoiceRows`
			WHERE
				(
					( dueDate IS NOT NULL AND (dueDate BETWEEN ? AND ?) )
					OR
					( dueDate IS NULL AND (invoiceDate BETWEEN ? AND ?) )
				)
				AND payedStatus IN ('n', 'p') AND statusOp = 'confirmed'
			GROUP BY invDate
		";
		$dailyExpense = $this->executeAndCacheSql($dailyExpenseSQL, [ $startDate, $endDate, $startDate, $endDate ]);


		// GROUP RECORDS FOR OUTPUT ///////////////////////////////////////////////////////////////
		$records = [];

		$dateObj = \Engine\DateTime::createFromIsoDate($startDate);
		$dateStr = $startDate;
		while ($dateStr<=$endDate) {
			$records['income'][$dateStr] = 0;
			$records['expense'][$dateStr] = 0;
			$records['dailyBalance'][$dateStr] = 0;
			$records['cashFlow'][$dateStr] = 0;
			// increase day
			$dateObj->add(\DateInterval::createFromDateString('1 day'));
			$dateStr = $dateObj->formatDateIso();
		}

		// add income
		foreach ($dailyIncome as $row) {
			$records['income'][$row['invDate']]		= (float)$row['totalValue'];
			$records['dailyBalance'][$row['invDate']]	+= (float)$row['totalValue'];
		}

		// add expenses
		foreach ($dailyExpense as $row) {
			$records['expense'][$row['invDate']]		= -(float)$row['totalValue'];
			$records['dailyBalance'][$row['invDate']]	-= (float)$row['totalValue'];
		}

		// determine cashflow
		$cashFlow = 0;
		foreach ($records['dailyBalance'] as $day=>$value) {
			$cashFlow += $value;
			$records['cashFlow'][$day] = $cashFlow;
		}

		return $records;
	}


	/**
	 * Prepare output.
	 * @param array $records
	 * @return array
	 */
	private function getDataSets(array $records)
	{

		$_LANG = \App\Loader_Lang::getInstance()->getGlobal();

		$data = [];

		foreach ($records as $status=>$statusRecords) {
			$thisData = [ 'attributes' => [ 'label' => $_LANG['dashboard']['widgetsList']['App\Dashboard\Widget\Charts_EstimatedDailyBalance']['field'][$status] ], 'data'=>[] ];
			foreach ($statusRecords as $date => $value) {
				$thisData['data'][] = ['n'=>\Engine\DateTime::createFromIsoDate($date)->format('d M'), 'v'=>round($value, 2)];
			}
			$data[] = $thisData;
		}

		return $data;

	}

	/**
	 * The form default options.
	 * {@inheritDoc}
	 * @see \App\Dashboard\Widget\QuickReports_GeneralAbstract::getDefaultOptions()
	 */
	protected function getDefaultOptions()
	{
		return [
			'reportCurrency' => 'default',
		];
	}

	/**
	 * Generate the options form
	 */
	protected function populateLocalOptionsForm(\Engine\Form\Container\GeneralAbstract $form)
	{
		// load lang
		$loaderLang = \App\Loader_Lang::getInstance();
		$loaderLang->loadAppFile("_customLoad/dashboard/widgets/_general.lang.php");
		$_LANG = $loaderLang->getAll();

		$fieldset = \Engine\Form\Container\Fieldset::create('');

		$defCurr = \App\Config\Currencies::getInstance()->getDefaultCurrency();
		$workCurr = \App\Config\Currencies::getInstance()->getWorkCurrency();

		$field = new \Engine\Form\Input\Radio($_LANG['dashboard']['widgets']['_GENERAL_']['qrExtra']['currency'], 'reportCurrency', $this->getOption('reportCurrency'));
		$field->setPossibleValues(['default'=>sprintf($_LANG['dashboard']['widgets']['_GENERAL_']['qrExtra']['defCurr'], $defCurr), 'work'=>sprintf($_LANG['dashboard']['widgets']['_GENERAL_']['qrExtra']['wrkCurr'], $workCurr)]);
		$fieldset->addElement($field);

		$form->addContainer($fieldset);
		return $form;
	}

	/**
	 * Extract data from the form return($R) and sets internal configs($this->options) accordingly
	 */
	protected function extractFormOptions($formData)
	{
		$options = ['reportCurrency' => $formData['reportCurrency'] ];
		$this->setOptions($options);
	}


}