<?php

	defined('FULL_PATH') or die('restricted access!');

	class OrderHelper extends kHelper
	{
		/**
		 * Returns various information about given order
		 *
		 * @param OrdersItem $object
		 * @param string $currency
		 * @param bool $remove_errors
		 * @return Array
		 */
		function getOrderInfo(&$object, $currency, $remove_errors = true)
		{
			$errors = $this->Application->RecallVar('checkout_errors');

			$ret = Array (
				'order' => Array (
					'CouponId' => (int)$object->GetDBField('CouponId'),
					'CouponName' => (string)$object->GetDBField('CouponName'),
					'GiftCertificateId' => (int)$object->GetDBField('GiftCertificateDiscount'),
					'GiftCertificateDiscount' => $this->convertCurrency($object->GetDBField('GiftCertificateDiscount'), $currency),
					'DiscountTotal' => $this->convertCurrency($object->GetDBField('DiscountTotal'), $currency),
					'SubTotal' => $this->convertCurrency($object->GetDBField('SubTotal'), $currency),
				),
				'items' => Array (),
				'errors' => $errors ? unserialize($errors) : Array (),
			);

			/** @var kDBList $items */
			$items = $this->Application->recallObject('orditems', 'orditems_List', Array ('per_page' => -1));

			$items->Query();
			$items->GoFirst();

			$ret['order']['ItemsInCart'] = array_sum( $items->GetCol('Quantity') );

			if ( $items->EOL() ) {
				return $ret;
			}

			/** @var kCatDBItem $product */
			$product = $this->Application->recallObject('p', null, Array ('skip_autoload' => true));

			$sql =  $product->GetSelectSQL() . '
					WHERE ' . $product->TableName . '.' . $product->IDField . ' IN (' . implode(',', $items->GetCol('ProductId')) . ')';
			$products = $this->Conn->Query($sql, $product->IDField);

			while ( !$items->EOL() ) {
				// prepare product from order item
				$product->LoadFromHash( $products[ $items->GetDBField('ProductId') ] );
				$this->Application->SetVar('orditems_id', $items->GetID()); // for edit/delete links using GET

				// weird code from orditems:PrintList
				$this->Application->SetVar('p_id', $product->GetID());
				$this->Application->SetVar('m_cat_id', $product->GetDBField('CategoryId'));

				// collect order item info
				$url_params = Array (
					'p_id' => $product->GetID(),
					'm_cat_id' => $product->GetDBField('CategoryId'),
					'pass' => 'm,p',
				);

				$product_url = $this->Application->HREF('__default__', '', $url_params);

				$item_data = $items->GetDBField('ItemData');
				$item_data = $item_data ? unserialize($item_data) : Array ();

				$row_index = $items->GetDBField('ProductId') . ':' . $items->GetDBField('OptionsSalt') . ':' . $items->GetDBField('BackOrderFlag');

				/** @var ImageHelper $image_helper */
				$image_helper = $this->Application->recallObject('ImageHelper');

				// TODO: find a way to specify thumbnail size & default image

				$ret['items'][$row_index] = Array (
					'product_url' => $product_url,
					'product_type' => $product->GetDBField('Type'),
					'options' => isset($item_data['Options']) ? $item_data['Options'] : false,
					'free_promo_shipping' => $this->eligibleForFreePromoShipping($items),

					'fields' => Array (
						'OrderItemId' => $items->GetDBField('OrderItemId'),
						'ProductName' => $items->GetDBField('ProductName'),
						'PrimaryImage' => $product->GetField('PrimaryImage', 'resize:58x58;default:img/no_picture.gif'),
						'BackOrderFlag' => (int)$items->GetDBField('BackOrderFlag'),
						'FlatPrice' => $this->convertCurrency($items->GetDBField('FlatPrice'), $currency),
						'Price' => $this->convertCurrency($items->GetDBField('Price'), $currency),
						'Quantity' => (int)$items->GetDBField('Quantity'),
						'Virtual' => (int)$items->GetDBField('Virtual'),
						'Type' => (int)$product->GetDBField('Type'),

						'cust_Availability' => $product->GetDBField('cust_Availability'),
					),
				);

				$items->GoNext();
			}

			if ( $remove_errors ) {
				$this->Application->RemoveVar('checkout_errors');
			}

			return $ret;
		}

		function convertCurrency($amount, $currency)
		{
			/** @var CurrencyRates $converter */
			$converter = $this->Application->recallObject('CurrencyRates');

			// convert primary currency to selected (if they are the same, converter will just return)
			return (float)$converter->Convert($amount, 'PRIMARY', $this->getISO($currency));
		}

		function getISO($currency)
		{
			if ($currency == 'selected') {
				$iso = $this->Application->RecallVar('curr_iso');
			}
			elseif ($currency == 'primary' || $currency == '') {
				$iso = $this->Application->GetPrimaryCurrency();
			}
			else { //explicit currency
				$iso = strtoupper($currency);
			}

			return $iso;
		}

		/**
		 * Checks, that given order item is eligible  for free promo shipping
		 *
		 * @param kDBItem|kDBList $order_item
		 * @return bool
		 */
		function eligibleForFreePromoShipping(&$order_item)
		{
			if ( $order_item->GetDBField('Type') != PRODUCT_TYPE_TANGIBLE ) {
				return false;
			}

			$free_shipping = $order_item->GetDBField('MinQtyFreePromoShipping');

			return $free_shipping > 0 && $free_shipping <= $order_item->GetDBField('Quantity');
		}

		/**
		 * Returns a template, that will be used to continue shopping from "shopping cart" template
		 *
		 * @param string $template
		 * @return string
		 * @access public
		 */
		public function getContinueShoppingTemplate($template = '')
		{
			if ( !$template || $template == '__default__' ) {
				$template = $this->Application->RecallVar('continue_shopping');
			}

			if ( !$template ) {
				$template = 'in-commerce/index';
			}

			return $template;
		}

		/**
		 * Detects credit card type by it's number.
		 *
		 * @param string $number Credit card number.
		 *
		 * @return     integer
		 * @deprecated 5.2.2-B1
		 * @see        OrderHelper::getCreditCardType()
		 */
		public function getCreditCartType($number)
		{
			kUtil::deprecatedMethod(__METHOD__, '5.2.2-B1', 'OrderHelper::getCreditCardType');

			return $this->getCreditCardType($number);
		}

		/**
		 * Detects credit card type by it's number.
		 *
		 * @param string $number Credit card number.
		 *
		 * @return integer
		 */
		public function getCreditCardType($number)
		{
			// Get rid of any non-digits.
			$number = preg_replace('/[^\d]/', '', $number);

			$mapping = Array (
				'/^4.{15}$|^4.{12}$/' => 1, // Visa
				'/^5[1-5].{14}$/' => 2, // MasterCard
				'/^3[47].{13}$/' => 3, // American Express
				'/^6011.{12}$/' => 4, // Discover
				'/^30[0-5].{11}$|^3[68].{12}$/' => 5, // Diners Club
				'/^3.{15}$|^2131|1800.{11}$/' => 6, // JBC
			);

			foreach ($mapping as $number_regex => $card_type) {
				if ( preg_match($number_regex, $number) ) {
					return $card_type;
				}
			}

			return false;
		}

		/**
		 * Extracts fields, used to created user from order
		 *
		 * @param OrdersItem $order
		 * @param string $field_prefix
		 * @return Array
		 * @access public
		 */
		public function getUserFields(&$order, $field_prefix = 'Billing')
		{
			$fields_hash = Array ();
			$names = explode(' ', $order->GetDBField($field_prefix . 'To'), 2);

			$fields_hash['FirstName'] = (string)getArrayValue($names, 0);
			$fields_hash['LastName'] = (string)getArrayValue($names, 1);

			$order_fields = Array (
				'Company', 'Phone', 'Fax', 'Email', 'Address1' => 'Street',
				'Address2' => 'Street2', 'City', 'State', 'Zip', 'Country'
			);

			foreach ($order_fields as $src_field => $dst_field) {
				if ( is_numeric($src_field) ) {
					$src_field = $dst_field;
				}

				$fields_hash[$dst_field] = $order->GetDBField($field_prefix . $src_field);
			}

			return $fields_hash;
		}
	}
