<?php
namespace OfficeBrain\Bundle\PaymentBundle\Manager\Extended;

use OfficeBrain\Bundle\PaymentBundle\Manager\AbstractManager\PaymentAbstract;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Payum\Core\Request\Capture;
use Payum\Core\Request\SecuredCapture;
use Payum\Core\Security\SensitiveValue;
use Payum\Core\Model\ArrayObject;
use Payum\Core\Registry\RegistryInterface;
use Payum\Core\Security\GenericTokenFactoryInterface;
use Payum\Core\Request\BinaryMaskStatusRequest;
use Payum\Core\Request\GetHumanStatus;
//use OfficeBrain\Bundle\PaymentBundle\Form\PaypalExpressType;
use OfficeBrain\Bundle\PaymentBundle\Form\PaypalCreditCardType;


class PaypalExtended extends PaymentAbstract {

	public function __construct($entityManager, $requestManager, $sessionManager, $productDetailServiceManager, $payumManager, $payumSecurityTokenFactoryManager, $routerManager, $payumSecurityHttpRequestVerifierManager, $thirdPartyManager, $commonLibraryManager, $orderManager, $serviceGroupRuleManager, $coreLibraryManager) {
		parent::__construct($entityManager, $requestManager, $sessionManager, $productDetailServiceManager, $payumManager, $payumSecurityTokenFactoryManager, $routerManager, $payumSecurityHttpRequestVerifierManager, $thirdPartyManager, $commonLibraryManager, $orderManager, $serviceGroupRuleManager, $coreLibraryManager);
	}
	public function __destruct() {
		parent::__destruct();
	}
	public function loadPaymentForm($controllerObj) {
		$paymentMethod = $this->requestManager->get('payment_type','paypalExpress');
		//echo "dfdfdf==".$paymentMethod; die;
		//$this->type = new PaypalExpressType();
		$this->type = new PaypalCreditCardType(false);
		$this->form = $controllerObj->createForm($this->type);
		$this->response['form']=$this->form->createView();
		$this->response['payment_type']=$paymentMethod;
		return $this->response;
	}

	public function preparePayment($controllerObj){
		$this->type = new PaypalCreditCardType(true);
		$paymentName = 'DoDirectPayment';
		$paymentMethod = $this->requestManager->get('payment_type','paypalExpress');
		$this->form = $controllerObj->createForm($this->type);
		$this->form->handleRequest($this->requestManager);
		$price=array();
		$total=0;
		if ($this->form->isValid())
		{	
			$sandbox = TRUE;
			// Set PayPal API version and credentials.
			$api_version = '85.0';
			$api_username = $sandbox ? 'sb-eoy5w18066638_api1.business.example.com' : 'LIVE_USERNAME_GOES_HERE';
			$api_password = $sandbox ? 'Q4SKQ22SWUCGWS48' : 'LIVE_PASSWORD_GOES_HERE';
			$api_signature = $sandbox ? 'Ad6jkKjpQAQOG63ru.f-V61bmfJnAnmxCiBsPKfAaNw1L-SgX4p64R-3' : 'LIVE_SIGNATURE_GOES_HERE';

			$formData = $this->form->getData();
			$productData =  $this->getProductData();

			foreach($productData as $index=>$data)
			{
				$totalTaxShippingWiseValue = 0;
				$details['product_name'][$index]=$data['product_name'];
				$details['product_api_code'][$index] =$data['sku_code'];
				$details['product_desc'][$index] =$data['product_name'];
				$details['quantity'][$index] =$data['total_qty'];
				$details['price'][$index] =$data['total_qty']*$data['unit_price'];
				/* if(count($data['charges'])>0 && array_key_exists('setup',$data['charges'])){
					$details['setupfee'][$index] = $data['charges'][''];
				}else{
					$details['setupfee'][$index] = 0;
				} */
				
				// Get Charges of Split Shipping 
				if(array_key_exists('split',$data) && count($data['split'])>0 )
				{
					$splitShipCharge = 0;
					$split_temp = 0;
					foreach($data['split'] as $splitShippingCharge)
					{
						$splitShipCharge = $splitShipCharge + $splitShippingCharge['shipping_detail']['shipping_charge'];
						$split_temp++;
					}
				}
				else
				{
					$splitShipCharge = 0;
				}
				
				// Get Charges of Split Shipping
				if(array_key_exists('standard',$data) && count($data['standard'])>0 )
				{
					$standardShipCharge = 0;
					$standard_temp = 0;
					foreach($data['standard'] as $splitShippingCharge)
					{
						$standardShipCharge = $standardShipCharge + $splitShippingCharge['shipping_detail']['shipping_charge'];
					}
				}
				else
				{
					$standardShipCharge = 0;
				} 
				
				// Get Charges of Split Shipping product setup charges / PMS charges
				if(count($data['charges'])>0){
					$charges = 0;
					foreach($data['charges'] as $productCharges)
					{
						$charges = $charges + $productCharges['charges_amount'];
					}
				}
				else{
					$charges = 0;
				}
				
				$taxShippingWise=0;
				if(count($data['split'])>0) {
					$shippingType=$data['shipping_type'];
					for($i=0;$i<count($data['split']);$i++) {
						$totalShippingCharge = $totalShippingCharge+$data['split'][$i]['shipping_detail']['shipping_charge'];
						$taxShippingWise=isset($data['split'][$i]['tax_shipping_wise']) ? number_format($data['split'][$i]['tax_shipping_wise'],3) : 0;
						$taxShippingWiseResult[$i]=number_format($taxShippingWise,3);
					}
				}
				$sub_total=$data['total_qty']*number_format($data['unit_price'],3);
				$sub_grand_total=$sub_total+$charges;
				$vatValue = 0;
				if(isset($data['tax']))
				{
					$tax=$this->calculateTax($data['tax']);
					$vat[] =array();
					if($data['tax']['vat_unit']=="percentage"){
						$vat[]=number_format($sub_total*$tax,3, '.', '');
					}else{
						$vat[]=number_format(($tax),3);
					}
					$vatValue=array_sum($vat);
				}
				$totalTaxShippingWiseValue+=array_sum($taxShippingWiseResult)+$vatValue;
				$totalTaxShippingWise=$totalTaxShippingWise+$totalTaxShippingWiseValue;
				//$price[]=$data['total_qty']*$data['unit_price'];
				$total=$total+$sub_grand_total+ $standardShipCharge + $splitShipCharge+$totalTaxShippingWiseValue+$charges;
				$currency = $data['currency'];
			}

			if(isset($formData['option']['billing_id'])) {
				$contactbook = $this->entityManager->getRepository('OfficeBrainUserBundle:ContactBook')->getContactBookById($formData['option']['billing_id']);
				//print_r(\Doctrine\Common\Util\Debug::dump($contactbook));
				$cityName = $this->entityManager->getRepository("OfficeBrainCoreBundle:City")->getCityNameById($contactbook->getCityId());
				$stateName = $this->entityManager->getRepository("OfficeBrainCoreBundle:State")->getStateNameById($contactbook->getStateId());
				$countryName = $this->entityManager->getRepository("OfficeBrainCoreBundle:Country")->getCountryCodeById($contactbook->getCountryId());
			}
			$tax_total=number_format($formData['option']['tax_amount'],2);
            $total=$total+$tax_total;
			$paymentDetails = array
            (
            'METHOD' => 'DoDirectPayment', 
            'USER' => $api_username, 
            'PWD' => $api_password, 
            'SIGNATURE' => $api_signature, 
            'VERSION' => $api_version, 
            'PAYMENTACTION' => 'Sale',                   
            //'IPADDRESS' => '137.184.220.107',
            //'CREDITCARDTYPE' => 'MasterCard', 
            'ACCT' => $formData['card']['number'],                        
            'EXPDATE' => $formData["card"]["expireAt"]->format('mY'),           
            'CVV2' => $formData['card']['securityCode'], 
            'FIRSTNAME' => $contactbook->getName(), 
            'LASTNAME' => $contactbook->getName(), 
            'STREET' => $contactbook->getStreet1(), 
            'CITY' => $cityName[0]['cityName'], 
            'STATE' => $stateName[0]['stateName'],                     
            'COUNTRYCODE' => $countryName[0]['countryCode'], 
            'ZIP' => $contactbook->getZipcode(), 
            'AMT' => $total, 
            'CURRENCYCODE' => $currency, 
            'DESC' => 'Testing Payments Pro'
            );
            //print_r($paymentDetails); die;
			$data = $this->doPayment($paymentDetails);
			if(array_key_exists('TRANSACTIONID',$data)){
				$storage = $this->payumManager->getStorage('OfficeBrain\Bundle\PaymentBundle\Entity\PaymentDetails');
			$details = $storage->create();

				$storage = $this->payumManager->getStorage('OfficeBrain\Bundle\PaymentBundle\Entity\PaymentDetails');
				$orderDetails = $storage->create();
				$orderDetails['productDetail'] = $details;
				$orderDetails['currency_code']= $currency;
				$orderDetails['amount'] = $total;

				$paymentDetails['productDetail'] = $details;
				$paymentDetails['currency_code']= $currency;
				$paymentDetails['amount'] = $total;
				
				$storage->update($orderDetails);
				$this->sessionManager->set('paymentDetail',array('billing_id'=>$formData['option']['billing_id'],'po_number'=>$formData['option']['number'],'transaction_id'=>$data['TRANSACTIONID'],'amount'=>$total,'method'=>'DoDirectPayment','tax_total'=>$tax_total));
				$this->response['status'] ="DoDirectPayment"; 
			}else{
				$this->response['url']=$controllerObj->generateUrl('office_brain_orderbundle_payment_paymentfailed');
				if($this->sessionManager->has('paymentDetail')){ $this->sessionManager->remove('paymentDetail'); }
				$this->response['status']="FAILED";
			}
		}
		else
		{
			$this->response['status']="NOTVALIDATE";
			$this->response['notValid']=$this->commonLibraryManager->prepareFormJsonError($this->form);
		}
		return $this->response;
	}


	private function doPayment($paymentDetails){
		$sandbox = TRUE;
		$api_endpoint = $sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp';
		$nvp_string = '';
		foreach($paymentDetails as $var=>$val)
		{
		    $nvp_string .= '&'.$var.'='.urlencode($val);    
		}
		// Send NVP string to PayPal and store response
		$curl = curl_init();
		        curl_setopt($curl, CURLOPT_VERBOSE, 1);
		        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
		        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
		        curl_setopt($curl, CURLOPT_URL, $api_endpoint);
		        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
		        curl_setopt($curl, CURLOPT_POSTFIELDS, $nvp_string);
		 
		$result = curl_exec($curl);  
		curl_close($curl);
		return $this->NVPToArray($result);
	}


	// Function to convert NTP string to an array
	private function NVPToArray($NVPString)
	{
	    $proArray = array();
	    while(strlen($NVPString))
	    {
	        // name
	        $keypos= strpos($NVPString,'=');
	        $keyval = substr($NVPString,0,$keypos);
	        // value
	        $valuepos = strpos($NVPString,'&') ? strpos($NVPString,'&'): strlen($NVPString);
	        $valval = substr($NVPString,$keypos+1,$valuepos-$keypos-1);
	        // decoding the respose
	        $proArray[$keyval] = urldecode($valval);
	        $NVPString = substr($NVPString,$valuepos+1,strlen($NVPString));
	    }
	    return $proArray;
	}

	/*public function preparePaymentBk($controllerObj) {
		
		$this->type = new PaypalExpressType();
		$paymentName = 'paypal_express_payment';
		$paymentMethod = $this->requestManager->get('payment_type');
		$this->form = $controllerObj->createForm($this->type);
		$this->form->handleRequest($this->requestManager);
		$vat=array();
		$info=array();
		
		$totalCharge=0;
		$total=0;
		$totalShippingCharge=0;
		$totalTaxShippingWise=0;
		if ($this->form->isValid())
		{
			$productData =  $this->getProductData();
			$formData = $this->form->getData();

			$storage = $this->payumManager->getStorage('OfficeBrain\Bundle\PaymentBundle\Entity\PaymentDetails');

			$details = $storage->create();
			foreach($productData as $index=>$data)
			{
				$itemLineCharge=0;
				$totalTaxShippingWiseValue = 0;
				$vatValue = 0;
				$details['L_PAYMENTREQUEST_0_NAME'.$index]=$data['product_name'];
				$details['L_PAYMENTREQUEST_0_NUMBER'.$index] = $data['sku_code'];
				$details['L_PAYMENTREQUEST_0_DESC'.$index] = $data['product_name']; //Allow only 120 character.
				$details['L_PAYMENTREQUEST_0_AMT'.$index] = number_format($data['unit_price'],2);
				$details['L_PAYMENTREQUEST_0_QTY'.$index] = $data['total_qty'];
				$total= $total+number_format($data['unit_price'],2)*$data['total_qty'];
				if(count($data['charges'])>0 && array_key_exists('charges',$data)){
					foreach($data['charges'] as $crg=>$charge){
						$itemLineCharge=$itemLineCharge+$charge['charges_amount'];
					}
				}
				$totalQuantity=$data['total_qty'];
				$taxShippingWiseResult=array();
				$productPrice=number_format($data['unit_price'],2);
				$taxShippingWise=0;
				if(count($data['split'])>0) {
					$shippingType=$data['shipping_type'];
					for($i=0;$i<count($data['split']);$i++) {
						$totalShippingCharge = $totalShippingCharge+$data['split'][$i]['shipping_detail']['shipping_charge'];
						$taxShippingWise=isset($data['split'][$i]['tax_shipping_wise']) ? $data['split'][$i]['tax_shipping_wise'] : 0;*/
						/*$totalQuantityPerShipping=0;
						for($j=0;$j<count($data['split'][$i]['variation_master']);$j++) {
							$totalChargeForCurrentSplit=0;
							for($k=0;$k<count($data['split'][$i]['variation_master'][$j]['variation_quantity']);$k++) {
								$totalQuantityPerShipping+=intval($data['split'][$i]['variation_master'][$j]['variation_quantity'][$k]['quantity']);
							}
						}
						
						if($shippingType=="standard") {
							$taxShippingWiseResult[$i]=(($totalQuantityPerShipping*$productPrice)+$itemLineCharge)*($taxShippingWise/100);
						} else if($shippingType=="split") {
							if($itemLineCharge!==0) {
								$totalChargeForCurrentSplit=(($itemLineCharge)/$totalQuantity)*$totalQuantityPerShipping;
							}
							$taxShippingWiseResult[$i]=(($totalQuantityPerShipping*$productPrice)+$totalChargeForCurrentSplit)*($taxShippingWise/100);
						}
						$taxShippingWiseResult[$i]=number_format($taxShippingWiseResult[$i],2);*/
				/*		$taxShippingWiseResult[$i]=$taxShippingWise;
					}
				}
				// Get Charges of Split Shipping product setup charges / PMS charges
				if(count($data['charges'])>0){
					$charges = 0;
					foreach($data['charges'] as $productCharges)
					{
						$charges = $charges + $productCharges['charges_amount'];
					}
				}
				else{
					$charges = 0;
				}
				
				$sub_total=$data['total_qty']*number_format($data['unit_price'],2);
				$sub_grand_total=$sub_total+$charges;
				$vatValue = 0;
				if(isset($data['tax']))
				{
					$tax=$this->calculateTax($data['tax']);
					$vat[] =array();
					if($data['tax']['vat_unit']=="percentage"){
						$vat[]=number_format($sub_total*$tax,2, '.', '');
					}else{
						$vat[]=number_format(($tax),2);
					}
					$vatValue=array_sum($vat);
				}
				$totalTaxShippingWiseValue+=array_sum($taxShippingWiseResult)+$vatValue;
				$totalTaxShippingWise=$totalTaxShippingWise+$totalTaxShippingWiseValue;
	
				$info['product_name'][$index]=$data['product_name'];
				$info['product_api_code'][$index] =$data['sku_code'];
				$info['product_desc'][$index] =$data['product_name']; //Allow only 120 character.
				$info['quantity'][$index] = $data['total_qty'];
				$info['price'][$index] = $total;
				$info['item_line_charges'][$index] = $itemLineCharge;
				$totalCharge= $totalCharge+$itemLineCharge;
				unset($vat);
			}
			
			$details['total_shipping_charges'] = $totalShippingCharge;
			$details['productDetail'] = $info;
			$details['PAYMENTREQUEST_0_PAYMENTACTION'] = 'Sale';
			$details['PAYMENTREQUEST_0_ITEMAMT'] =$total; //This is the total item amount
			$details['PAYMENTREQUEST_0_TAXAMT'] = $totalTaxShippingWise; //used to add Tax on total itemt amount
			$details['PAYMENTREQUEST_0_SHIPPINGAMT'] = $totalShippingCharge; // This is used to show shipping amount. //Postage and packaging
			$details['PAYMENTREQUEST_0_HANDLINGAMT'] = $totalCharge; //This is used to set the handling amount on total items amount and added in the shipping amount //Postage and packaging
			//$details['PAYMENTREQUEST_0_INSURANCEAMT'] = 1.00; //This is used to set the insurance amount on total items amount //Insurance
			$details['PAYMENTREQUEST_0_AMT'] = $details['PAYMENTREQUEST_0_ITEMAMT']+$details['PAYMENTREQUEST_0_SHIPPINGAMT']+$details['PAYMENTREQUEST_0_HANDLINGAMT']+$details['PAYMENTREQUEST_0_TAXAMT']; // This is total of total items amount, taxes, shipping or etc.
			$details['PAYMENTREQUEST_0_CURRENCYCODE'] = $productData[0]['currency'];  // This is used to set the currency.
			//$details['PAYMENTREQUEST_0_PAYMENTACTION'] = Sale;  //
			$details['ALLOWNOTE'] = 1;
			$details['NOSHIPPING'] = 1;*/
			/*echo "<pre>";
			print_r($details); die;
			if(isset($formData['option']['billing_id'])) {
				$contactbook = $this->entityManager->getRepository('OfficeBrainUserBundle:ContactBook')->getContactBookById($formData['option']['billing_id']);
				//print_r(\Doctrine\Common\Util\Debug::dump($contactbook));
				$cityName = $this->entityManager->getRepository("OfficeBrainCoreBundle:City")->getCityNameById($contactbook->getCityId());
				$stateName = $this->entityManager->getRepository("OfficeBrainCoreBundle:State")->getStateNameById($contactbook->getStateId());
				$countryName = $this->entityManager->getRepository("OfficeBrainCoreBundle:Country")->getCountryCodeById($contactbook->getCountryId());
				$details['PAYMENTREQUEST_0_SHIPTONAME'] = $contactbook->getName();
				$details['PAYMENTREQUEST_0_SHIPTOSTREET'] = $contactbook->getStreet1();
				$details['PAYMENTREQUEST_0_SHIPTOSTREET2'] = $contactbook->getStreet2();
				$details['PAYMENTREQUEST_0_SHIPTOCITY'] = $cityName[0]['cityName'];
				$details['PAYMENTREQUEST_0_SHIPTOSTATE'] = $stateName[0]['stateName'];
				$details['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $countryName[0]['countryCode'];
				$details['PAYMENTREQUEST_0_SHIPTOZIP'] = $contactbook->getZipcode();
				$details['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $contactbook->getPhone();
			}*/
			
			//$storage->update($details);
			/*$captureToken = $this->payumSecurityTokenFactoryManager->createCaptureToken($paymentName,$details,'office_brain_paymentBundle_payment_paypalresponse'); // the route to redirect after capture;	
			$details['RETURNURL'] = $captureToken->getTargetUrl();
			$details['CANCELURL'] = $this->requestManager->getScheme().'://'.$this->requestManager->getHost ().$controllerObj->generateUrl('office_brain_orderbundle_order_checkoutdetail');//$captureToken->getTargetUrl();
			$details['INVNUM'] = $details->getId();
			$this->sessionManager->set('paymentDetail',array('billing_id'=>$formData['option']['billing_id'],'po_number'=>$formData['option']['number']));
			$storage->update($details);
			$this->response['status']="CAPTURE";
			$this->response['captureUrl']=$captureToken->getTargetUrl();
		}else{
			$this->response['status']="NOTVALIDATE";
			$this->response['notValid']=$this->commonLibraryManager->prepareFormJsonError($this->form);
		}
		print_r($this->response); die;
		return $this->response;

	}*/
	
	/*public function captureDone($controllerObj) {
		$token = $this->payumSecurityHttpRequestVerifierManager->verify($this->requestManager);
		$paymentMethod=$token->getGatewayName();
		$payment = $this->payumManager->getGateway($token->getGatewayName());
		$payment->execute($status = new GetHumanStatus($token));
		
		if ($status->isCaptured()) {
			$data=$status->getModel()->offsetGet('productDetail');
			$data['transaction_id']=$status->getModel()->offsetGet('PAYMENTINFO_0_TRANSACTIONID');
			$data['method']=$paymentMethod;
			$data['totalAmt']=$status->getModel()->offsetGet('PAYMENTREQUEST_0_AMT');
			//print_r($status->getModel()->getIterator()); die;
			$this->sessionManager->setFlashBagMessage('notice',array('transaction_id'=>$data['transaction_id'],'amount'=>$data['totalAmt']));
			$this->sessionManager->setFlashBagMessage('data',$data);
			$paymentDetail=$this->sessionManager->get('paymentDetail');
			$paymentDetail = array_merge($paymentDetail,array('transaction_id'=>$data['transaction_id'],'amount'=>$data['totalAmt'],'method'=>$data['method']));
			$this->sessionManager->set('paymentDetail',$paymentDetail);
			$this->response['url']=$controllerObj->generateUrl('office_brain_orderbundle_payment_paymentsuccess');
			$this->response['status']="SUCCESS";
		} else if ($status->isPending()) {

			$data=$status->getModel()->offsetGet('productDetail');
			$data['transaction_id']=$status->getModel()->offsetGet('PAYMENTINFO_0_TRANSACTIONID');
			$data['method']=$paymentMethod;
			$data['totalAmt']=$status->getModel()->offsetGet('PAYMENTREQUEST_0_AMT');
			//print_r($status->getModel()->getIterator()); die;
			$this->sessionManager->setFlashBagMessage('notice',array('transaction_id'=>$data['transaction_id'],'amount'=>$data['totalAmt']));
			$this->sessionManager->setFlashBagMessage('data',$data);
			$paymentDetail=$this->sessionManager->get('paymentDetail');
			$paymentDetail = array_merge($paymentDetail,array('transaction_id'=>$data['transaction_id'],'amount'=>$data['totalAmt'],'method'=>$data['method']));
			$this->sessionManager->set('paymentDetail',$paymentDetail);
			$this->response['url']=$controllerObj->generateUrl('office_brain_orderbundle_payment_paymentsuccess');
			$this->response['status']="SUCCESS";
		} else {
			$data['method']=$paymentMethod;
			$data['reason']=null;
			if($this->sessionManager->has('paymentDetail')){ $this->sessionManager->remove('paymentDetail'); }
			$this->sessionManager->setFlashBagMessage('error',$data);
			$this->response['url']=$controllerObj->generateUrl('office_brain_orderbundle_payment_paymentfailed');
			$this->response['status']="FAILED";
		}
		return $this->response;
	}*/
	
}
