<?php

class SummaryAction extends CartAction {
	
	const OPERATION_ADD_DOMAIN = 'add-domain';
	const OPERATION_ADD_ADDONS = 'add-addons';
	const OPERATION_REMOVE_PURCHASE = 'remove-purchase';
	const OPERATION_REMOVE_OWN_DOMAIN = 'remove-own-domain';
	const OPERATION_REMOVE_ADDON = 'remove-addon';
	const OPERATION_APPLY_COUPON = 'apply-coupon';
	const OPERATION_CONTINUE_ORDER = 'continue-order';
	
	public function execute($request) {
		
		sfContext::getInstance()->getConfiguration()->loadHelpers('I18N');
		$cartItems = $this->_cart->getItems();
		
		if ($request->isMethod('post')) {
			
			$cartItemId = $request->getParameter('cartItemId');
			$purchaseId = $request->getParameter('purchaseId');
			$addonId = $request->getParameter('addonId');
			$operation = $request->getParameter('operation');
			
			switch ($operation) {
				case self::OPERATION_ADD_ADDONS:
					$cartItem = ResourceLocator::getInstance()->cart->getItem($cartItemId);
					ResourceLocator::getInstance()->cart->setCurrentItem($cartItem);
					$router = new Router();
					$router->init(
						array(
							new RouterPage('select-addons'),
							new RouterPage('summary')
						),
						new RouterPage('summary')
					);
					ResourceLocator::getInstance()->routersStack->push($router);
					$router->next();
					break;
				case self::OPERATION_ADD_DOMAIN:
					$cartItem = ResourceLocator::getInstance()->cart->getItem($cartItemId);
					$cartItem->setMasterPurchase($purchaseId);
					$this->_cart->setCurrentItem($cartItem);
					$router = new Router();
					$router->init(
						array(
							new RouterPage('select-domain'),
							new RouterPage('register-domain'),
							new RouterPage('summary')
						),
						new RouterPage('summary')
					);
					ResourceLocator::getInstance()->routersStack->push($router);
					$router->next();
					break;
				case self::OPERATION_REMOVE_PURCHASE:
					$this->_cart->removePurchase($purchaseId);
					break;
				case self::OPERATION_REMOVE_OWN_DOMAIN:
					$purchase = ResourceLocator::getInstance()->cart->getPurchase($purchaseId);
					$purchase->removeOwnDomain($request->getParameter('domainName'));
					break;
				case self::OPERATION_REMOVE_ADDON:
					ResourceLocator::getInstance()->cart->getPurchase($purchaseId)->removeAddon($addonId);
					break;
				case self::OPERATION_APPLY_COUPON:
					$code = $request->getParameter('coupon');
					$itemIds = array();
					$purchases = $this->_cart->getPurchases();
					foreach ($purchases as $purchase) {
						if (!isset($itemIds[$purchase->getPlanId()])) {
							$itemIds[$purchase->getPlanId()] = array();
						}
						$itemIds[$purchase->getPlanId()][] = $purchase;

						foreach ($purchase->getAddons() as $addon) {
							if (!isset($itemIds[$addon->getAddonId()])) {
								$itemIds[$addon->getAddonId()] = array();
							}
							$itemIds[$addon->getAddonId()][] = $addon;
							if ($addon->hasCouponByCode($code)) {
								$addon->unsetCoupon();
							}
						}
					}
					$targetIds = array_keys($itemIds);
					try {
						$ids = array();
						$coupon = ResourceLocator::getInstance()->billingCouponService->applyCoupon(
							$this->_store->getId(),
							$targetIds,
							$code,
							$ids
						);
						$names = array();
						foreach ($ids as $id) {
							if (isset($itemIds[$id])) {
								foreach ($itemIds[$id] as $item) {
									if ($item->setCoupon($coupon)) {
										$names[] = $item->getName();
										if ($coupon->couponApplyNumber) {
											break;
										}
									}
								}
							}
						}
						if (!$names) {
							throw new StoreException();
						}
						sfContext::getInstance()->getUser()->setAttribute('couponSuccessMessage', 'TRANS_COUPON_VALID');
						$output = implode(', ', $names);
						sfContext::getInstance()->getUser()->setAttribute('couponSuccessNames', $output);
					} catch (BillingObjectException $exception) {
						sfContext::getInstance()->getUser()->setAttribute('errorMessage', 'TRANS_COUPON_INVALID');
					}
					break;
				case self::OPERATION_CONTINUE_ORDER:
					$noOneDomainNames = array();
					$noOneAddonGroupNames = array();
					$noOneAddonNames = array();
					$plans = $this->_store->getPlans();
					// check plans, that must have domains and addons
					foreach (ResourceLocator::getInstance()->cart->getPurchases() as $purchase) {
						if (!$plan = $plans[$purchase->getPlanId()]) {
							throw new StoreException('Can not retrieve plan [' . $purchase->getPlanId() . ']');
						}
						if ($plan->mustHaveDomains()) {
							if (!$purchase->hasParameter('domainData') && !$purchase->hasOwnDomains())  {
								$result = false;
								foreach ($purchase->getPurchases() as $subPurchase) {
									$subPlan = $plans[$subPurchase->getPlanId()];
									if ($subPlan instanceof BillingDomainPlan) {
										$result = true;
										break;
									}
								}
								if (!$result) {
									$noOneDomainNames[] = $purchase->getName();
								}
							}
						}
						foreach ($plan->getAddonGroups($this->_store->getId(), $purchase->getCycleId()) as $addonGroup) {
							if (!$addonGroup->productAddonGroupNoneChoice) {
								$result = false;
								foreach ($addonGroup->getAddons() as $addon) {
									if ($purchase->hasAddonByAddonId($addon->getId())) {
										$result = true;
										break;
									}
								}
								if (!$result) {
									$noOneAddonGroupNames[] = $addonGroup->productAddonGroupName;
								}
							}
						}
						if ($plan->mustHaveAddons()) {
							if (!$purchase->hasAddons()) {
								$noOneAddonNames[] = $purchase->getName();
							}
						}
					}
                    $this->_cart->clearInvoiceID();
					if ($noOneDomainNames) {
						sfContext::getInstance()->getUser()->setAttribute('errorMessage', __('TRANS_FOLLOWING_PLANS_MUST_HAVE_DOMAINS', array('%NAMES%' => implode(', ', array_unique($noOneDomainNames)))));
					} else if ($noOneAddonGroupNames) {
						sfContext::getInstance()->getUser()->setAttribute('errorMessage', __('TRANS_FOLLOWING_ADDON_GROUPS_MUST_HAVE_ADDONS', array('%NAMES%' => implode(', ', array_unique($noOneAddonGroupNames)))));
					} else if ($noOneAddonNames) {
						sfContext::getInstance()->getUser()->setAttribute('errorMessage', __('TRANS_FOLLOWING_PLANS_MUST_HAVE_ADDONS', array('%NAMES%' => implode(', ', array_unique($noOneAddonNames)))));
					} else {
						$this->_router->next();
					}
					break;
			}
			
			$this->_router->refresh();
			
		}
		
		$amount = 0;
		$totalAmount = 0;
		$prorationAmount = 0;
		$minimalCycle = null;
		
		$cartItemsData = array();
		foreach ($cartItems as $cartItemId => $cartItem) {
			$cartItemData = array();
			
			foreach ($cartItem->getPurchases() as $purchase) {
				$subPurchases = $purchase->getPurchases(true);
				$cartItemData[$purchase->getId()] = $this->preparePurchaseData($purchase, $subPurchases, $amount, $totalAmount, $prorationAmount, $minimalCycle);
				$addons = array();
				foreach ($purchase->getAddons(true) as $addon) {
					$addons[] = $this->prepareAddonData($addon, $amount, $totalAmount, $prorationAmount, $minimalCycle);
				}
				$cartItemData[$purchase->getId()]['addons'] = $addons;
			}
			
			if ($cartItemData) {
				$cartItemsData[$cartItemId] = $cartItemData;
			}
			
		}
		
		$this->amount = $amount;
		$this->totalAmount = $totalAmount;
		$this->minimalCycle = $minimalCycle;
		
		$this->cartItemsData = $cartItemsData;
		
		$customer = sfContext::getInstance()->getUser()->getAttribute('customer');
		$customerData = sfContext::getInstance()->getUser()->getAttribute('customerData');
		if (!$customer && !$customerData && ($defaultTaxZoneId = isset($this->_store->defaultTaxZoneID) ? $this->_store->defaultTaxZoneID : false)) {
			$this->taxZone = ResourceLocator::getInstance()->billingTaxZoneService->getById($defaultTaxZoneId);
		}
		
		if ($this->couponSuccessMessage = sfContext::getInstance()->getUser()->getAttribute('couponSuccessMessage')) {
			$this->couponSuccessNames = sfContext::getInstance()->getUser()->getAttribute('couponSuccessNames');
			sfContext::getInstance()->getUser()->setAttribute('couponSuccessMessage', null);
			sfContext::getInstance()->getUser()->setAttribute('couponSuccessNames', null);
		}

		if ($this->errorMessage = sfContext::getInstance()->getUser()->getAttribute('errorMessage')) {
			sfContext::getInstance()->getUser()->setAttribute('errorMessage', null);
		}
		
	}
	
	private function preparePurchaseData($purchase, $subPurchases = array(), &$amount, &$totalAmount, &$prorationAmount, &$minimalCycle) {
		return PurchaseManager::preparePurchaseData($this->_store, $purchase, $subPurchases, &$amount, &$totalAmount, &$prorationAmount, &$minimalCycle);
	}
	
	private function prepareAddonData($addon, &$amount, &$totalAmount, &$prorationAmount, &$minimalCycle) {
		return PurchaseManager::prepareAddonData($this->_store, $addon, &$amount, &$totalAmount, &$prorationAmount, &$minimalCycle);
	}
	
}