<?php

require_once("lib-action/action.php");
require_once("objects/Package.php");
require_once("objects/Product.php");
require_once("objects/Client.php");

class EditNewOrdersResponse extends MB_Action
{
	public $params = array("clientID");

	public function execute()
	{
		parent::execute();

		if($_REQUEST["referralActionID"] == getActionID("ShowDashboardNewOrders")) {
			$this->setReferralActionID(getActionID("ShowDashboard"));
			$this->setReferralActionFile("dashboard.php");
		} else {
			$this->setReferralActionID(getActionID("ShowNewOrders"));
			$this->setReferralActionFile("clients.php");
		}

		// These are accepted clients, update their status to active
		// AND -- If their packages are pending, update their status to active
		// EXCEPT -- If their packages are in the queue, leave them alone for the queue to run
		$clientIDs = $this->_filterClientsByVendor((array)$_REQUEST["activate"]);
		foreach($clientIDs as $clientID) {
			$packages = correctArray(grabResultsFromMBAPIArray(array(
				"mbapi" => array(
					"command" => "GetPackages",
					"params" => array(
						"clientID" => (int) $clientID,
						"getPackageAttributeData" => 1,
					),
				),
			)));
			foreach ($packages as $package) {
				if (1 == $package["packageActive"] && Package::STATUS_PENDING == $package["packageStatus"] &&
					!in_array($package["packageType"], array(Product::TYPE_HOSTING, Product::TYPE_SSL_CERT, Product::TYPE_RESELLER))
				) {
					updateFor("packages", array(
						"packageID" => $package["packageID"],
						"packageStatus" => getAPIStatusID("package", "none"),
					));
				}
			}

			try {
				$customer = Factory()->Client($clientID);
				$customer->client_status = Client::STATUS_ACTIVE;
				$customer->client_status_reason = $customer->isReseller() ?
					blmsg("TRANS_RESELLER_NEW_ACTIVE_STATUS_REASON") : blmsg("TRANS_CUSTOMER_NEW_ACTIVE_STATUS_REASON");
				require_once("object_managers/ClientManager.php");
				ClientManager::update($customer);
			} catch (ProductException $e) {
				billing_put_error($e->getMessage());
				redirect("dashboard.php", getActionID("ShowDashboard"));
			}

			if ($customer->isReseller()) {
				require_once("object_managers/ResellerManager.php");
				ResellerManager::repairSSO($customer->getReseller());
			}
		}

		// These are not accepted clients, update their status to canceled
		// AND -- If their packages are pending, update their status to canceled
		// EXCEPT -- If their packages are in the queue, update the queue item to canceled
		// ELSE -- If their packages are already active, send them to the queue to be deleted
		$clientIDs = $this->_filterClientsByVendor((array)$_REQUEST["cancel"]);
		$pendingPackageIDs = NULL;

		foreach($clientIDs as $clientID) {
			$packages = correctArray(grabResultsFromMBAPIArray(array(
				"mbapi" => array(
					"command" => "GetPackages",
					"params" => array(
						"clientID" => (int) $clientID,
						"getPackageAttributeData" => 1,
					),
				),
			)));

			$customer = Factory()->Client($clientID);
			$statusReason = $customer->isReseller() ? blmsg("TRANS_RESELLER_NEW_CANCEL_STATUS_REASON") : blmsg("TRANS_CUSTOMER_NEW_CANCEL_STATUS_REASON");
			foreach ($packages as $package){
				$pendingID = getAPIStatusID("package", "pending");
				$activeID = getAPIStatusID("package", "none");
				$panelTied = FALSE;
				//Pull the server-group tied packages out
				foreach ((array) $package["packageAttributes"] as $attribute){
					if((int)$attribute["serverGroupID"]) {
						$panelTied = TRUE;
						break;
					}
				}

				// IF Package record is ACTIVE
				// IF Package status is PENDING
				// IF Package IS NOT tied to a panel
				// THEN update package status to canceled
				if($package["packageActive"] && $package["packageStatus"]  == $pendingID && !$panelTied) {

					//Flip the package status to canceled
					dbg("Flip the package status to canceled");
					updateFor("packages", array(
						"packageID" => $package["packageID"],
						"packageStatus" => getAPIStatusID("package", "canceled"),
						"packageStatusReason" => $statusReason,
					));

				// IF Package record is ACTIVE
				// IF Package status is ACTIVE
				// IF Package IS NOT tied to a panel
				// THEN update package status to canceled
				} else if($package["packageActive"] && $package["packageStatus"]  == $activeID && !$panelTied) {

					//Flip the package status to canceled
					dbg("Flip the package status to canceled");
					updateFor("packages", array(
						"packageID" => $package["packageID"],
						"packageStatus" => getAPIStatusID("package", "canceled"),
						"packageStatusReason" => $statusReason,
					));

				// IF Package record is ACTIVE
				// IF Package status is PENDING
				// IF Package __IS__ tied to a panel
				// THEN update package status to canceled
				// AND update system queue status to canceled
				} else if($package["packageActive"] && $package["packageStatus"]  == $pendingID && $panelTied) {

					//Flip the package status to canceled
					dbg("Flip the package status to canceled");
					updateFor("packages", array(
						"packageID" => $package["packageID"],
						"packageStatus" => getAPIStatusID("package", "canceled"),
						"packageStatusReason" => $statusReason,
					));

					//Flip any systeQueue events to canceled if they exist for this package
					dbg("Flip any systeQueue events to canceled if they exist for this package");
					updateFor("systemQueue", array(
						"packageID" => $package["packageID"],
						"systemQueueStatus" => getAPIStatusID("package", "canceled")
					));

				// IF Package record is ACTIVE
				// IF Package status is __ACTIVE__
				// IF Package __IS__ tied to a panel
				// THEN INSERT system queue status to DELETE package
				// **** SYSTEM QUEUE MUST THEN SET THE PACKAGE TO CANCELED AFTER SUCCESS
				} else if ($package["packageActive"] && $package["packageStatus"]  == $activeID && $panelTied) {

					// SEND ITEM TO THE QUEUE
					dbg("SEND ITEM TO THE QUEUE");
					$this->createNewSystemQueueEvent($package,$_REQUEST["cancelAction"]);

				}
			}

			//Flip client status to canceled
			dbg("Flip client status to active");
			$this->cancelCustomer($customer, Client::STATUS_CANCELED, $statusReason);
		}

		// These are not accepted clients, update their status to fraud
		// AND -- If their packages are pending, update their status to fraud
		// EXCEPT -- If their packages are in the queue, update the queue item to canceled
		// ELSE -- If their packages are already active, send them to the queue to be deleted
		$clientIDs = $this->_filterClientsByVendor((array)$_REQUEST["fraud"]);
		$pendingPackageIDs = NULL;

		foreach($clientIDs as $clientID) {

			$invoiceReversal = dispatchMBAPI(toXML(array(
				"mbapi" => array(
					"command" => "ProcessCreditNote",
					"params" => array(
						"clientID" => (int) $clientID,
					),
				),
			)));

			$packages = correctArray(grabResultsFromMBAPIArray(array(
				"mbapi" => array(
					"command" => "GetPackages",
					"params" => array(
						"clientID" => (int) $clientID,
						"getPackageAttributeData" => 1,
					),
				),
			)));

			$customer = Factory()->Client($clientID);
			$statusReason = $customer->isReseller() ? blmsg("TRANS_RESELLER_NEW_FRAUDULENT_STATUS_REASON") : blmsg("TRANS_CUSTOMER_NEW_FRAUDULENT_STATUS_REASON");
			foreach ($packages as $package) {
				$pendingID = getAPIStatusID("package", "pending");
				$fraudID = getAPIStatusID("package", "fraudulent");
				$activeID = getAPIStatusID("package", "none");
				$panelTied = FALSE;
				//Pull the server-group tied packages out
				foreach ((array) $package["packageAttributes"] as $attribute){
					if((int)$attribute["serverGroupID"]) {
						$panelTied = TRUE;
						break;
					}
				}

				// IF Package record is ACTIVE
				// IF Package status is PENDING
				// IF Package IS NOT tied to a panel
				// THEN update package status to fraud
				if($package["packageActive"] && $package["packageStatus"]  == $pendingID && !$panelTied) {

					//Flip the package status to canceled
					dbg("Flip the package status to fraudulent");
					updateFor("packages", array(
						"packageID" => $package["packageID"],
						"packageStatus" => getAPIStatusID("package", "fraudulent"),
						"packageStatusReason" => $statusReason,
					));

				// IF Package record is ACTIVE
				// IF Package status is ACTIVE
				// IF Package IS NOT tied to a panel
				// THEN update package status to canceled
				} else if($package["packageActive"] && $package["packageStatus"]  == $activeID && !$panelTied) {

					//Flip the package status to canceled
					dbg("Flip the package status to fraudulent");
					updateFor("packages", array(
						"packageID" => $package["packageID"],
						"packageStatus" => getAPIStatusID("package", "fraudulent"),
						"packageStatusReason" => $statusReason,
					));

				// IF Package record is ACTIVE
				// IF Package status is PENDING
				// IF Package __IS__ tied to a panel
				// THEN update package status to canceled
				// AND update system queue status to canceled
				} else if($package["packageActive"] && $package["packageStatus"]  == $pendingID && $panelTied) {

					//Flip the package status to canceled
					dbg("Flip the package status to fraudulent");
					updateFor("packages", array(
						"packageID" => $package["packageID"],
						"packageStatus" => getAPIStatusID("package", "fraudulent"),
						"packageStatusReason" => $statusReason,
					));

					//Flip any systeQueue events to canceled if they exist for this package
					dbg("Flip any systeQueue events to canceled if they exist for this package");
					updateFor("systemQueue", array(
						"packageID" => $package["packageID"],
						"systemQueueStatus" => getAPIStatusID("package", "fraudulent")
					));

				// IF Package record is ACTIVE
				// IF Package status is __ACTIVE__
				// IF Package __IS__ tied to a panel
				// THEN INSERT system queue status to DELETE package
				// **** SYSTEM QUEUE MUST THEN SET THE PACKAGE TO CANCELED AFTER SUCCESS
				} else if ($package["packageActive"] && $package["packageStatus"]  == $activeID && $panelTied) {

					// SEND ITEM TO THE QUEUE
					dbg("SEND ITEM TO THE QUEUE");
					$this->createNewSystemQueueEvent($package,$_REQUEST["cancelAction"]);

				}
			}

			//Flip client status to canceled
			dbg("Flip client status to fraudulent");
			$this->cancelCustomer($customer, Client::STATUS_FRAUDULENT, $statusReason);
		}

		redirect($this->getReferralActionFile(), $this->getReferralActionID(), array("n"=>uniqid(0) ));

		$this->addErrorTemplates();
		return $this->hasExecutedSuccessfully();
	}
	
	private function _filterClientsByVendor($clientIds)
	{
		$result = array();
		$session = getCurrentSession();
		foreach ($clientIds as $id) {
			if ($session->checkVendor(Factory()->Client($id))) {
				$result[] = $id;
			}
		}
		return $result;
	}

	private function createNewSystemQueueEvent($packageData,$queueAction="suspend")
	{
		//NOTE: if the package status is changed from active, the system queue items
		//will not run.  The system queue will flip the status after running the suspend or delete calls

		$cancelActions = array("suspend","delete");
		$queueAction = (in_array($queueAction,$cancelActions)) ? $queueAction : "suspend" ;

		$packageID = (int) $packageData["packageID"];

		$pushQueueItem = $serverGroupID = $configGroupID = FALSE;
		if(is_array($packageData["packageAttributes"])) {
			foreach($packageData["packageAttributes"] as $key => $value) {
				if($value["packageAttributeName"] == "panel_status") {
					$pushQueueItem = ($value["packageAttributeValue"] == "none")? TRUE : $pushQueueItem;
					$serverGroupID = $value["serverGroupID"];
					$configGroupID = $value["configGroupID"];
				}
			}
		}

		if($pushQueueItem) {

			switch($queueAction) {
				case "suspend":
					$subCommand = "panelSuspend";
					break;
				case "delete":
					$subCommand = "panelDelete";
					break;
			}

			$panelQuery = array(
				"mbapi" => array(
					"command" => "ProcessPanel",
					"subCommand" => $subCommand,
					"params" =>
					array(
						"subCommand" => $subCommand,
						"configGroupID" => $configGroupID,
						"serverGroupID" => $serverGroupID,
						"packageID" => $packageID,
					))
			);

			$panelXML = toXML($panelQuery);

			$panelQuery = new MBQuery(
				"SetSystemQueue", "insert",
				array(
					"systemQueueCommand" => "ProcessPanel",
					"configGroupID" => $configGroupID,
					"packageID" => $packageID,
					"systemQueueCommandInput" => htmlentities($panelXML),
					"systemQueueDateToRun" => mktime(),
					"systemQueueDateFinished" => 0,
				)
			);

			$this->addErrorsFromResult($panelQuery->getResult());
		}
	}

	private function cancelCustomer(Client $customer, $cancelStatus, $cancelStatusReason)
	{
		if ($customer->isReseller()) {
			$reseller = $customer->getReseller();
			$reseller->active = 0;
			$reseller->status = $cancelStatus;
			$reseller->status_reason = $cancelStatusReason;
			$reseller->date_cancelled = time();
			$reseller->update();
		} else {
			$customer->client_active = 0;
			$customer->client_status = $cancelStatus;
			$customer->client_status_reason = $cancelStatusReason;
			$customer->client_date_cancelled = time();
			$customer->update();
		}
	}
}
