<?php
namespace Modules\Bsp\Settlement;

class Controller extends \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract
{
	protected $listOrderingColumns = ['balanceStatus', 'ticketNumber', 'ticketDate',];

	protected function initialize()
	{
		parent::initialize();

		$this->actionsCfg['exportCurrentRecords'] =     	['authType' => 'easy', 'checkSection'=>false, 'checkOption'=>false];
		$this->actionsCfg['changeStatus'] =     			['authType' => 'easy', 'checkSection'=>false, 'checkOption'=>false];
		$this->actionsCfg['importCurrentRecords'] =     	['authType' => 'easy', 'checkSection'=>false, 'checkOption'=>false];
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionDefineParams()
	 */
	protected function optionDefineParams(\App\Mvc\View\Utils\RowOptions\Option\Option $option, $selection)
	{
		switch($option->getId()){
			case 'exportCurrentRecords':
			break;

			case 'importCurrentRecords':
			break;

			case 'changeStatus':
			case 'changeStatusBulk':
			break;

			default:
				return false;
		}

		return true;
	}

	/**
	 * (non-PHPdoc)
	 * @see \App\Mvc\Controller\Window\PaginatedListing\ListingAbstract::optionGetEntityName()
	 */
	protected function optionGetEntityName($id)
	{
		return '';
	}

	/**
	 * Export records as seen in the listing
	 * @return \Engine\Mvc\Response\BigFileDownload
	 */
	protected function actionExportCurrentRecords($R)
	{
		$msgs = \App\MessagesCollector::create();

		$closePopup = false;

		// step 1
		if ($R['save']) {
			\DB::prepareForLongRunningScript();
			// increase the time limit
			set_time_limit(1800);
			session_write_close();

			$listingParams = clone($this->loadListingParams($R)->getListingParams());
			$extension = '???';
			switch ($R['reportStyle']) {
				case 'bspReconciliationReport':
					$generator = new ModelGenerateReportBspReconciliationReport();
					$extension = 'csv';
				break;

				case 'bspExceptionsReport':
					$generator = new ModelGenerateReportBspExceptionsReport();
					$extension = 'xls';
				break;

				case 'exportOperationalStatus':
					$generator = new ModelGenerateReportBspOperationalStatus();
					$extension = 'csv';
				break;

				default:
					throw new \Exception(sprintf("[%s] Unknown report style: %s", __METHOD__, $R['reportStyle']));
			}
			$outputFile = \Engine\File::tempnam(sprintf("%s-%s.%s", __CLASS__, time(), $extension));	// write file to temporary location

			$generator->setListingParams($listingParams);
			$generator->generate($outputFile);


			// compose filename from the used filters
			$formFilters = new View_Utils_FormFilters($this);
			$formFilters->setValue('listingParams', $listingParams);
			$filterOverview = $formFilters->getForm()->getFilterOverviewValues();

			usort($filterOverview, function($a, $b) {
				return strcmp($a['id'], $b['id']);
			});

			$overviewStr = implode(", ", array_map(function($f) {
				return sprintf("%s-%s",
					preg_replace("/(filters_|_)/", '', $f['id']),
					trim(preg_replace("/[^a-zA-Z0-9\s]/", '', $f['overview']))
				);
			}, $filterOverview));

			// download & delete
			$fileName = sprintf("BSPSettlement, exported at %s%s.%s", \Engine\DateTime::create()->format('Ymd His'),
				($overviewStr?sprintf(", filtered by %s", $overviewStr):', default filters'),
				$extension
			);
			$response = new \Engine\Mvc\Response\BigFileDownload($outputFile);
			$response->body->setOption('deleteAfterSend', true);
			$response->setFilename($fileName);
			return $response;
		}

		$view = new View_GenerateReport($this);

		// send data to the view
		$view->addInput('formData', $R);
		$view->setClosePopup($closePopup);
		$view->getMessagesCollector()->appendMessages($msgs);

		// render the view
		return new \Engine\Mvc\Response\Html($view->render());
	}


	/**
	 * Export records as seen in the listing
	 * @return \Engine\Mvc\Response\Html
	 */
	protected function actionImportCurrentRecords($R): \Engine\Mvc\Response\Html
	{
		$msgs = \App\MessagesCollector::create();

		$closePopup = false;

		$view = new View_ImportOperationalStatus($this);

		// step 1
		if ($R['save']) {
			\DB::prepareForLongRunningScript();
			// increase the time limit
			set_time_limit(1800);
			session_write_close();

			// Handle file upload
			$uploadedFileObj = new \App\Form\UploadedFiles\File('importedFile');

			// Check if file was uploaded
			if (!$uploadedFileObj->hasValidFile()) {
				$msgs->addError($this->lang['generateReport']['msgs']['invalidFile']);
				return new \Engine\Mvc\Response\Html($view->render());
			}

			// Only CSV files allowed
			if (\Engine\File::getExtension($uploadedFileObj->getName()) != 'csv') {
				$msgs->addError($this->lang['generateReport']['msgs']['invalidTypeFile']);
				return new \Engine\Mvc\Response\Html($view->render());
			}

			$uploadedFile = $uploadedFileObj->getTempName();

			try {
				// Initialize CSV reader
				$csv = new \App\Utils\CSV\Reader\Reader();
				$csv->setDelimiter(',');
				$csv->openFile($uploadedFile);

				// Define expected columns matching ModelGenerateReportBspOperationalStatus export format
				$expectedColumns = [
					'key',
					'settlementOperationalStatus',
					'settlementOperationalDateTime',
					'settlementOperationalUserId'
				];

				$csv->setExpectedColumns($expectedColumns);

				// Read header row
				$headerRow = $csv->next(false);
				if ($headerRow && $headerRow->hasData()) {
					$csv->setHeaderRow($headerRow, false);
				}

				$importedCount = 0;
				$errorCount = 0;

				// Start transaction for batch processing
				\DB::startTransaction();

				// Process each row
				while ($row = $csv->next()) {
					try {
						// Use the key from the CSV export to update existing records
						$recordKey = $row->key;

						// Check if record exists
						$existingRecord = \Entity\BspSettlementRecord::select($recordKey);

						if ($existingRecord->recordExists()) {

							if ($row->settlementOperationalStatus) {
								// Validate operational status
								$validStatuses = ['none', 'inProgress', 'closed'];
								if (!in_array($row->settlementOperationalStatus, $validStatuses)) {
									$errorCount++;
									$msgs->addWarning(sprintf("Invalid operational status '%s' for record with key '%s'",
										$row->settlementOperationalStatus, $recordKey, implode(', ', $validStatuses)));
									continue;
								}

								// Validate user ID if provided
								$userEntity = \Entity\User::select($row->settlementOperationalUserId);
								if (!$userEntity->recordExists()) {
									$errorCount++;
									$msgs->addWarning(sprintf("Invalid user ID '%s' for record with key '%s'. User does not exist.",
										$row->settlementOperationalUserId, $recordKey));
									continue;
								}

								// Update existing record using the updateOperationalStatus operation
								$bspSettlement = \Entity\BspSettlementRecord::updateOperationalStatus($recordKey);

								// Set operational status if provided
								$bspSettlement->operationalStatus = $row->settlementOperationalStatus;
								$bspSettlement->operationalDateTime = $row->settlementOperationalDateTime;
								$bspSettlement->operationalUser = $row->settlementOperationalUserId;

								// Save the record
								$bspSettlement->save();
								$importedCount++;
							}

						}
						else {
							$errorCount++;
							$msgs->addWarning(sprintf("Record with key '%s' not found in database", $recordKey));
						}

					}
					catch (\App\Entity\Exception $e) {
						$errorCount++;
						$msgs->addWarning(sprintf("Error importing row with key %s: %s", $recordKey, $e->getMessage()));
					}
				}

				// Commit transaction
				\DB::commitTransaction();

				// Close CSV file
				$csv->closeFile();

				// Add success message
				if ($importedCount) {
					$msgs->addSuccess(sprintf("Successfully imported %d records.", $importedCount));
				}

				if ($errorCount) {
					$msgs->addWarning(sprintf("Failed to import %d records.", $errorCount));
				}

				// Close popup if successful import
				if (!$msgs->hasErrorOrWarning()) {
					$closePopup = true;
				}
			}
			catch (\Exception $e) {
				\DB::rollbackTransaction();
				$msgs->addError(sprintf("Error processing CSV file: %s", $e->getMessage()));
			}

		}

		// send data to the view
		$view->addInput('formData', $R);
		$view->setClosePopup($closePopup);
		$view->getMessagesCollector()->appendMessages($msgs);

		// render the view
		return new \Engine\Mvc\Response\Html($view->render());
	}

	protected function actionChangeStatus($R)
	{
		$msgs = \App\MessagesCollector::create();

		$closePopup = false;

		$view = new View_ChangeStatus($this);

		if ($R['save']) {
			\DB::startTransaction();

			foreach ($R['ids'] as $id) {
				$bspSettlementRecordUpd = \Entity\BspSettlementRecord::updateOperationalStatus($id);
				$bspSettlementRecordUpd->operationalStatus = $R['newStatus'];
				$bspSettlementRecordUpd->save();
			}
			\DB::commitTransaction();

			$msgs->addSuccess($this->lang['changeStatus']['success']);
			$closePopup = true;
		}

		// send data to the view
		$view->addInput('formData', $R);
		$view->setClosePopup($closePopup);
		$view->getMessagesCollector()->appendMessages($msgs);

		// render the view
		return new \Engine\Mvc\Response\Html($view->render());
	}

}
