<?php

namespace Zeedhi\Framework\Report;

use Zeedhi\Framework\DependencyInjection\InstanceManager;

/**
 * Class ReportService
 */
class ReportService {

	/** @var Strategy\ReportStrategy[] */
	protected $reportStrategies;

	public function __construct(array $reportStrategies) {
		$this->reportStrategies = $reportStrategies;
	}

    /**
     * @param $strategyName
     * @return Strategy\ReportStrategy
     * @throws Exception
     */
	protected function getStrategyByName($strategyName) {
		foreach ($this->reportStrategies as $reportStrategy) {
			if ($reportStrategy->getName() == $strategyName) {
				return $reportStrategy;
			}
		}
		throw Exception::strategyNotFound($strategyName);
	}

	/**
	 * @param       $strategyName
	 * @param       $reportName
	 * @param array $params
	 *
	 * @return mixed
	 * @throws Exception
	 */
	public function createRemoteReport($strategyName, $reportName, array $params = array(), $isUrl = false) {	
		$isPDF = false;
		$reportFormat = null;
		$reportStrategy = $this->getStrategyByName($strategyName);

		if(method_exists($reportStrategy, 'getReportFormat')) {
			$formatParam = isset($params['__format']) ? $params['__format'] : null;
			if(!$formatParam) {
				$formatParam = isset($params['__FORMAT']) ? $params['__FORMAT'] : null;
			}
			if($formatParam) {
				$reportStrategy->setReportFormat($formatParam);
			}			
			$reportFormat = $reportStrategy->getReportFormat();
			if(!empty($reportFormat)) {
				$isPDF = strtolower($reportFormat) == 'pdf' || strtolower($reportFormat) == 'html';
			}
		}

		if($isUrl || $isPDF) {
			$reportUrl = $reportStrategy->createRemoteReport($reportName, $params);
			if($isPDF && !$isUrl) {
				$key = bin2hex(random_bytes(20));
				$this->saveReportMongo($reportUrl, $key, $reportName, $reportFormat);
				return '/lib_openReport?requestType=DataSet&dataset[0][KEY]=' . $key;
			}
			return $reportUrl;
		} else {
			$birtFile = $this->downloadReport($strategyName, $reportName, $params);
			$content = $birtFile->getContent();
        	$encodedFile = base64_encode($content);
			if(!empty($reportFormat)) {
				$encodedFile .= '&format=' . $reportFormat;
			}
        	return $encodedFile;
		}
	}

	private function saveReportMongo($reportUrl, $key, $reportName, $reportFormat) {
		$dataset = array('$set' => array (
            'KEY'    => $key,
            'URL'    => $reportUrl,
            'NAME'   => $reportName,
            'FORMAT' => $reportFormat
        ));
        $filter = array(
            'KEY' => $key,
        );
		InstanceManager::getInstance()->getService('mongoDB')->update('ZhReportData', $filter, $dataset, true);
	}

	/**
	 * @param       $strategyName
	 * @param       $reportName
	 * @param array $params
	 *
	 * @return ReportFile
	 * @throws Exception
	 */
	public function downloadReport($strategyName, $reportName, array $params = array()) {
		$reportStrategy = $this->getStrategyByName($strategyName);
		return $reportStrategy->downloadReport($reportName, $params);
	}

}