<?php

namespace Combodo\iTop\Application\Helper;

use ApplicationContext;
use ApplicationException;
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use DBObjectSearch;
use Dict;
use Exception;
use iTopWebPage;
use MetaModel;
use SynchroReplica;
use utils;

class SynchroReplicaHelper
{
	public static function OperationUnlinkAll(iTopWebPage $oP, ApplicationContext $oAppContext, $sOperation = 'unlink'): void
	{
		$oP->DisableBreadCrumb();
		$sClass = utils::ReadParam('class', '', false, 'class');
		$sFilter = utils::ReadPostedParam('filter', '', 'raw_data');
		$oFullSetFilter = DBObjectSearch::unserialize($sFilter);
		// Add user filter
		$oFullSetFilter->UpdateContextFromUser();
		$aSelectObject = utils::ReadMultipleSelection($oFullSetFilter);
		if (empty($sClass) || empty($aSelectObject)) { // TO DO: check that the class name is valid !
			throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'selectObject[]'));
		}
		$sCancelUrl = "./UI.php?operation=search&filter=".urlencode($sFilter)."&".$oAppContext->GetForLink();

		$aHeaders = [
			'object' => ['label' => MetaModel::GetName($sClass), 'description' => Dict::S('UI:ModifiedObject')],
			'status' => [
				'label'       => Dict::S('UI:BulkModifyStatus'),
				'description' => Dict::S('UI:BulkModifyStatus+'),
			],
			'errors' => [
				'label'       => Dict::S('UI:BulkModifyErrors'),
				'description' => Dict::S('UI:BulkModifyErrors+'),
			],
		];
		$aRows = [];

		$sHeaderTitle = Dict::Format('UI:Modify_N_ObjectsOf_Class', count($aSelectObject), MetaModel::GetName($sClass));
		$sClassIcon = MetaModel::GetClassIcon($sClass, false);

		// Not in preview mode, do the update for real
		$sTransactionId = utils::ReadPostedParam('transaction_id', '', 'transaction_id');
		if (!utils::IsTransactionValid($sTransactionId, false)) {
			throw new Exception(Dict::S('UI:Error:ObjectAlreadyUpdated'));
		}
		utils::RemoveTransaction($sTransactionId);

		// Avoid too many events
		$iPreviousTimeLimit = ini_get('max_execution_time');
		$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
		$aErrors = [];
		foreach ($aSelectObject as $iId) {
			set_time_limit(intval($iLoopTimeLimit));
			/** @var \cmdbAbstractObject $oObj */
			$oReplica = MetaModel::GetObject(SynchroReplica::class, $iId);
			$bResult = true;
			try {
				if (in_array($sOperation, ['unlink', 'unlinksynchro'])) {
					$oReplica->UnLink();
				}
				if (in_array($sOperation, ['synchro', 'unlinksynchro'])) {
					$oStatLog = $oReplica->ReSynchro();
					$aErrors = $oStatLog->GetTraces();
				}
				if ($sOperation == 'allowdelete') {
					$oReplica->Set('status_dest_creator', 1);
					$oReplica->DBUpdate();
				}
				if ($sOperation == 'denydelete') {
					$oReplica->Set('status_dest_creator', 0);
					$oReplica->DBUpdate();
				}
			} catch (Exception $e) {
				$bResult = false;
				$aErrors[] = $e->getMessage();
			}

			$sStatus = $bResult ? Dict::S('UI:BulkModifyStatusModified') : Dict::S('UI:BulkModifyStatusSkipped');

			$aErrorsToDisplay = array_map(function ($sError) {
				return utils::HtmlEntities($sError);
			}, $aErrors);
			$aRows[] = [
				'object' => $oReplica->GetHyperlink(),
				'status' => $sStatus,
				'errors' => '<p>'.($bResult ? '' : implode('</p><p>', $aErrorsToDisplay)).'</p>',
			];
		}

		set_time_limit(intval($iPreviousTimeLimit));
		$oTable = DataTableUIBlockFactory::MakeForForm('BulkModify', $aHeaders, $aRows);
		$oTable->AddOption("bFullscreen", true);

		$oPanel = PanelUIBlockFactory::MakeForClass($sClass, '');
		$oPanel->SetIcon($sClassIcon);
		$oPanel->SetTitle($sHeaderTitle);
		$oPanel->AddCSSClass('ibo-datatable-panel');
		$oPanel->AddSubBlock($oTable);

		$oP->AddUiBlock($oPanel);
		$oP->AddSubBlock(ButtonUIBlockFactory::MakeForSecondaryAction(Dict::S('UI:Button:Done')))->SetOnClickJsCode("window.location.href='$sCancelUrl'")->AddCSSClass('mt-5');
	}
}
