<?php
/**
  * Ahead WebSoft Technologies Pvt Ltd.
  * @copyright  Copyright 2006-2026 Ahead WebSoft Technologies Pvt Ltd.
  * @license    https://www.socialengine.com/policies
*/

 include_once APPLICATION_PATH . "/application/libraries/Engine/Service/Authorize/autoload.php";
 use net\authorize\api\contract\v1 as AnetAPI; 
 use net\authorize\api\controller as AnetController; 

class Authorizepmnt_Plugin_Gateway_Wallet_Authorize extends Engine_Payment_Plugin_Abstract {

  protected $_gatewayInfo;
  protected $_gateway;
  
  // General

  /**
   * Constructor
   */
  public function __construct(Zend_Db_Table_Row_Abstract $gatewayInfo)
  {
      $this->_gatewayInfo = $gatewayInfo;
  }

  /**
   * Get the service API
   *
   * @return Engine_Service_PayPal
   */
  public function getService()
  {
    return $this->getGateway()->getService();
  }

  /**
   * Get the gateway object
   *
   * @return Engine_Payment_Gateway
   */
  public function getGateway()
  {
    // var_dump((array) $this->_gatewayInfo);die;
    if( null === $this->_gateway ) {
      $class = 'Engine_Payment_Gateway_Authorizepmnt';
      Engine_Loader::loadClass($class);
      $gateway = new $class(array(
        'config' => (array) $this->_gatewayInfo->config,
        'testMode' => $this->_gatewayInfo->test_mode,
        'currency' => Engine_Api::_()->getApi('settings', 'core')->getSetting('payment.currency', 'USD'),
      ));
      if( !($gateway instanceof Engine_Payment_Gateway) ) {
        throw new Engine_Exception('Plugin class not instance of Engine_Payment_Gateway');
      }
      $this->_gateway = $gateway;
    }

    return $this->_gateway;
  }

  // Actions
  /**
   * Create a transaction object from specified parameters
   *
   * @return Engine_Payment_Transaction
   */
  public function createTransaction(array $params)
  {
    $transaction = new Engine_Payment_Transaction($params);
    $transaction->process($this->getGateway());
    return $transaction;
  }

  /**
   * Create an ipn object from specified parameters
   *
   * @return Engine_Payment_Ipn
   */
  public function createIpn(array $params)
  {
    $ipn = new Engine_Payment_Ipn($params);
    $ipn->process($this->getGateway());
    return $ipn;
  }

  // SEv4 Specific
  /**
   * Create a transaction for a subscription
   *
   * @param User_Model_User $user
   * @param Zend_Db_Table_Row_Abstract $subscription
   * @param Zend_Db_Table_Row_Abstract $package
   * @param array $params
   * @return Engine_Payment_Gateway_Transaction
   */
  public function createWalletTransaction(User_Model_User $user, array $params = array()) {}

  // SEv4 Specific
  
  /**
   * Create a transaction for a subscription
   *
   * @param User_Model_User $user
   * @param Zend_Db_Table_Row_Abstract $subscription
   * @param Zend_Db_Table_Row_Abstract $package
   * @param array $params
   * @return Engine_Payment_Gateway_Transaction
   */
  public function createSubscriptionTransaction(User_Model_User $user, Zend_Db_Table_Row_Abstract $subscription, Payment_Model_Package $package, array $params = array()) {

  }
  
  /**
   * Process return of subscription transaction
   *
   * @param Payment_Model_Order $order
   * @param array $params
   */
  public function onSubscriptionTransactionReturn(
  Payment_Model_Order $order, array $params = array()) {

  }
  
  /**
   * Process return of subscription transaction
   *
   * @param Payment_Model_Order $order
   * @param array $params
   */
  public function onWalletTransactionReturn(Payment_Model_Order $order, array $params = array()) {

    // Check that gateways match
    if( $order->gateway_id != $this->_gatewayInfo->gateway_id ) {
      throw new Engine_Payment_Plugin_Exception('Gateways do not match');
    }
    // Get related info
    $user = $order->getUser();
    $subscription = $order->getSource();
    $view = Zend_Registry::isRegistered('Zend_View') ? Zend_Registry::get('Zend_View') : null;

    // validate data
    if(empty($_POST['card_number']) || empty($_POST['card_exp_month']) || empty($_POST['card_exp_year']) || empty($_POST['card_cvc']) || (empty($user->email) && empty($_POST["card_email"])) ){
      echo json_encode(array("status"=>0,"message" => $view->translate("Please provide all field values.")));die;
    }
    
    $desc = Engine_Api::_()->payment()->getPackageDescription(0, $_POST["amount"], 'wallet');
    if( strlen($desc) > 127 ) {
      $desc = substr($desc, 0, 124) . '...';
    } else if( !$desc || strlen($desc) <= 0 ) {
      $desc = 'N/A';
    }
    if( function_exists('iconv') && strlen($desc) != iconv_strlen($desc) ) {
      // PayPal requires that DESC be single-byte characters
      $desc = @iconv("UTF-8", "ISO-8859-1//TRANSLIT", $desc);
    }

    $itemName = $desc;  
    $itemNumber = $_POST["order_id"];  
    $itemPrice = $_POST["amount"];  
    $currency = Engine_Api::_()->payment()->getCurrentCurrency();

    $name = $user->getTitle(); 
    $email = $user->email ? $user->email : $_POST["email"]; 
    $card_number = preg_replace('/\s+/', '', $_POST['card_number']); 
    $card_exp_month = $_POST['card_exp_month']; 
    $card_exp_year = $_POST['card_exp_year']; 
    $card_exp_year_month = $card_exp_year.'-'.$card_exp_month; 
    $card_cvc = $_POST['card_cvc']; 

    $refID = 'REF'.time(); 
    $config = (array) $this->_gatewayInfo->config;
    $merchantAuthentication = new AnetAPI\MerchantAuthenticationType();    
    $merchantAuthentication->setName($config["login_id"]);    
    $merchantAuthentication->setTransactionKey($config["transaction_key"]); 


    // Create the payment data for a credit card 
    $creditCard = new AnetAPI\CreditCardType(); 
    $creditCard->setCardNumber($card_number); 
    $creditCard->setExpirationDate($card_exp_year_month); 
    $creditCard->setCardCode($card_cvc); 

    // Add the payment data to a paymentType object 
    $paymentOne = new AnetAPI\PaymentType(); 
    $paymentOne->setCreditCard($creditCard); 

    // Create order information 
    $orderAuthorize = new AnetAPI\OrderType(); 
    $orderAuthorize->setInvoiceNumber($order->getIdentity());
    $orderAuthorize->setDescription($itemName); 

    // Set the customer's identifying information 
    $customerData = new AnetAPI\CustomerDataType(); 
    $customerData->setType("individual"); 
    $customerData->setId($user->getIdentity());
    $customerData->setEmail($email); 


    // Create a transaction 
    $transactionRequestType = new AnetAPI\TransactionRequestType(); 
    $transactionRequestType->setTransactionType("authCaptureTransaction");    
    $transactionRequestType->setAmount($itemPrice); 
    $transactionRequestType->setOrder($orderAuthorize); 
    $transactionRequestType->setPayment($paymentOne); 
    $transactionRequestType->setCustomer($customerData); 
    $request = new AnetAPI\CreateTransactionRequest(); 
    $request->setMerchantAuthentication($merchantAuthentication); 
    $request->setRefId($refID); 
    $request->setTransactionRequest($transactionRequestType); 
    $controller = new AnetController\CreateTransactionController($request); 
    if( $this->_gatewayInfo->test_mode ) {
      $response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::SANDBOX);
    } else {
      $response = $controller->executeWithApiResponse(\net\authorize\api\constants\ANetEnvironment::PRODUCTION);
    }
     
    if ($response != null) { 
      if ($response->getMessages()->getResultCode() == "Ok") { 
        $tresponse = $response->getTransactionResponse(); 
        if ($tresponse != null && $tresponse->getMessages() != null) { 
          $transaction_gateway_id = $tresponse->getTransId();
          if($tresponse->getAuthCode() == "000000"){
            $transaction_gateway_id = $refID;
          } 
        }
      }
    }
    if(empty($transaction_gateway_id)){
      if(!empty($tresponse)){
        $error = "Transaction Failed!"; 
        if ($tresponse->getErrors() != null) { 
            $error = $tresponse->getErrors()[0]->getErrorText() ; 
        } 
        echo json_encode(array("status"=>0,"message" => $view->translate($error)));die;
      }else if(!empty($response)){
        $tresponse = $response->getTransactionResponse(); 
        if ($tresponse != null && $tresponse->getErrors() != null) { 
            $error = $tresponse->getErrors()[0]->getErrorText();
        } else { 
            $error = $response->getMessages()->getMessage()[0]->getText(); 
        } 
        echo json_encode(array("status"=>0,"message" => $view->translate($error)));die;
      }else{
        echo json_encode(array("status"=>0,"message" => $view->translate("Transaction Failed! No response returned")));die;
      }
    }

    $subscriptionParams = json_decode($subscription->params);
    $recurrence = $subscriptionParams->recurrence;
    $subscription_id = $subscriptionParams->subscription_id;
    
    
    $desc = Engine_Api::_()->payment()->getPackageDescription($recurrence, $subscriptionParams->price, 'wallet');
    if( strlen($desc) > 127 ) {
      $desc = substr($desc, 0, 124) . '...';
    } else if( !$desc || strlen($desc) <= 0 ) {
      $desc = 'N/A';
    }
    if( function_exists('iconv') && strlen($desc) != iconv_strlen($desc) ) {
      // PayPal requires that DESC be single-byte characters
      $desc = @iconv("UTF-8", "ISO-8859-1//TRANSLIT", $desc);
    }

    $paymentStatus = 'okay';
    $orderStatus = 'complete';

    $current_currency = strtoupper($currency);
    $currencyChangeRate = 1;
    $defaultCurrency = Engine_Api::_()->payment()->defaultCurrency();
    if ($current_currency != $defaultCurrency) {
      $currencyData = Engine_Api::_()->getDbTable('currencies', 'payment')->getCurrency($current_currency);
      $currencyChangeRate = $currencyData->change_rate;
    }
    $price = @round(($_POST["amount"] / $currencyChangeRate), 2);

    // Insert transaction
    $transactionsTable = Engine_Api::_()->getDbtable('transactions', 'payment');
    $transactionsTable->insert(array(
      'user_id' => $order->user_id,
      'gateway_id' => $this->_gatewayInfo->gateway_id,
      'timestamp' => new Zend_Db_Expr('NOW()'),
      'order_id' => $order->order_id,
      'type' => 'wallet recharge',
      'state' => $paymentStatus,
      'gateway_transaction_id' => $transaction_gateway_id,
      'amount' => $price, // @todo use this or gross (-fee)?
      'currency' => Engine_Api::_()->payment()->defaultCurrency(), //strtoupper($transaction->currency),
      'change_rate' => $currencyChangeRate, //currency change rate according to default currency
      'current_currency' => strtoupper($currency), //currency which is user paid
    ));
    $transaction_id = $transactionsTable->getAdapter()->lastInsertId();

    $subscription->transaction_id = $transaction_id;
    $subscription->save();
    
    // Update order with profile info and complete status?
    $order->state = $orderStatus;
    $order->gateway_transaction_id = $transaction_gateway_id;
    $order->save();

     // Payment success
     $subscription->onPaymentSuccess();
     $walletSession = new Zend_Session_Namespace('Payment_Wallet');
     $walletSession->unsetAll();
     // send notification
    // if( $subscription->didStatusChange() ) {
       //Notification Work
       $translate = Zend_Registry::get('Zend_Translate');
       $walletlink = 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array('module' => 'payment', 'controller' => 'settings', 'action' => 'wallet'), 'default', true);
       $walletlink = '<a href="'.$walletlink.'" >'.$translate->translate("wallet").'</a>';

       Engine_Api::_()->getDbTable('notifications', 'activity')->addNotification($user, $user, $user, 'payment_wallet_active', array('payment_method' => 'Authorize.net','walletlink' => $walletlink));

       //Email work
       Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_wallet_active', array(
         'wallet_terms' => $desc,
         'object_link' => 'https://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array("module" => 'payment', 'controller' => "settings", "action" => "wallet"), 'default', true),
       ));
      if(isset($_SESSION['Payment_Subscription']) && !empty($subscription_id)) {
        if($user) {
          Engine_Api::_()->payment()->firsttimeSignupSubscription($user);
        }
      }
      return 'active';
    // }
   
  }
  
  /**
   * Process ipn of subscription transaction
   *
   * @param Payment_Model_Order $order
   * @param Engine_Payment_Ipn $ipn
   */
  public function onWalletTransactionIpn(Payment_Model_Order $order,Engine_Payment_Ipn $ipn){ }
  
  /**
   * Process ipn of subscription transaction
   *
   * @param Payment_Model_Order $order
   * @param Engine_Payment_Ipn $ipn
   */
  public function onSubscriptionTransactionIpn(
  Payment_Model_Order $order, Engine_Payment_Ipn $ipn) {

  }
  

  /**
   * Cancel a subscription (i.e. disable the recurring payment profile)
   *
   * @params $transactionId
   * @return Engine_Payment_Plugin_Abstract
   */
  public function cancelSubscription($transactionId, $note = null)
  {
    return $this;
  }
  
  /**
   * Generate href to a page detailing the order
   *
   * @param string $transactionId
   * @return string
   */
  public function getOrderDetailLink($orderId)
  {
    return 'https://www.authorizepmnt.net/index.php?cmd=acct_pmt_details&id=' . $orderId;
  }

  /**
   * Generate href to a page detailing the transaction
   *
   * @param string $transactionId
   * @return string
   */
  public function getTransactionDetailLink($transactionId)
  {
    
    return 'https://www.authorizepmnt.net/index.php?cmd=acct_pmt_details&id=' . $transactionId;
  }

  /**
   * Get raw data about an order or recurring payment profile
   *
   * @param string $orderId
   * @return array
   */
  public function getOrderDetails($orderId)
  {
    try {
      return $this->getService()->detailRecurringPaymentsProfile($orderId);
    } catch( Exception $e ) {
      echo $e;
    }

    try {
      return $this->getTransactionDetails($orderId);
    } catch( Exception $e ) {
      echo $e;
    }

    return false;
  }

  /**
   * Get raw data about a transaction
   *
   * @param $transactionId
   * @return array
   */
  public function getTransactionDetails($transactionId)
  {
    return $this->getService()->detailTransaction($transactionId);
  }
  
  // Forms

  /**
   * Get the admin form for editing the gateway info
   *
   * @return Engine_Form
   */
  public function getAdminGatewayForm(){
    return new Authorizepmnt_Form_Admin_Gateway_Authorize();
  }

  public function processAdminGatewayForm(array $values){
    return $values;
  }
  
  // IPN
  /**
   * Process an IPN
   *
   * @param Engine_Payment_Ipn $ipn
   * @return Engine_Payment_Plugin_Abstract
   */
  public function onIpn(Engine_Payment_Ipn $ipn) {}
  
  
  // IPN
  /**
   * Process an IPN
   *
   * @param Payment_Model_Order $order
   * @return Engine_Payment_Plugin_Abstract
   */
  public function onTransactionIpn(Payment_Model_Order $order,  $rawData) {
    // Check that gateways match
    if ($order->gateway_id != $this->_gatewayInfo->gateway_id) {
        throw new Engine_Payment_Plugin_Exception('Gateways do not match');
    }
    
    // Get related info
    $user = $order->getUser();

    $subscription = $order->getSource();
    //$package = $subscription->getPackage();
    
    $subscriptionParams = json_decode($subscription->params);
    $recurrence = $subscriptionParams->recurrence;
   
    
    $desc = Engine_Api::_()->payment()->getPackageDescription($recurrence, $subscriptionParams->price, 'wallet');
    if( strlen($desc) > 127 ) {
      $desc = substr($desc, 0, 124) . '...';
    } else if( !$desc || strlen($desc) <= 0 ) {
      $desc = 'N/A';
    }
    if( function_exists('iconv') && strlen($desc) != iconv_strlen($desc) ) {
      // PayPal requires that DESC be single-byte characters
      $desc = @iconv("UTF-8", "ISO-8859-1//TRANSLIT", $desc);
    }

    $paymentStatus = 'okay';
    $orderStatus = 'complete';

    $current_currency = strtoupper($rawData['currency1']);
    $currencyChangeRate = 1;
    $defaultCurrency = Engine_Api::_()->payment()->defaultCurrency();
    if ($current_currency != $defaultCurrency) {
      $currencyData = Engine_Api::_()->getDbTable('currencies', 'payment')->getCurrency($current_currency);
      $currencyChangeRate = $currencyData->change_rate;
    }
    $price = @round(($rawData["amount1"] / $currencyChangeRate), 2);

    // Insert transaction
    $transactionsTable = Engine_Api::_()->getDbtable('transactions', 'payment');
    $transactionsTable->insert(array(
      'user_id' => $order->user_id,
      'gateway_id' => $this->_gatewayInfo->gateway_id,
      'timestamp' => new Zend_Db_Expr('NOW()'),
      'order_id' => $order->order_id,
      'type' => 'wallet recharge',
      'state' => $paymentStatus,
      'gateway_transaction_id' => $rawData["txn_id"],
      'amount' => $price, // @todo use this or gross (-fee)?
      'currency' => Engine_Api::_()->payment()->defaultCurrency(), //strtoupper($transaction->currency),
      'change_rate' => $currencyChangeRate, //currency change rate according to default currency
      'current_currency' => strtoupper($rawData["currency1"]), //currency which is user paid
    ));
    $transaction_id = $transactionsTable->getAdapter()->lastInsertId();

    $subscription->transaction_id = $transaction_id;
    $subscription->save();
    
    // Update order with profile info and complete status?
    $order->state = $orderStatus;
    $order->gateway_transaction_id = $rawData["txn_id"];
    $order->save();

     // Payment success
     $subscription->onPaymentSuccess();
     $walletSession = new Zend_Session_Namespace('Payment_Wallet');
     $walletSession->unsetAll();
     // send notification
    // if( $subscription->didStatusChange() ) {
       //Notification Work
       $translate = Zend_Registry::get('Zend_Translate');
       $walletlink = 'http://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array('module' => 'payment', 'controller' => 'settings', 'action' => 'wallet'), 'default', true);
       $walletlink = '<a href="'.$walletlink.'" >'.$translate->translate("wallet").'</a>';

       Engine_Api::_()->getDbTable('notifications', 'activity')->addNotification($user, $user, $user, 'payment_wallet_active', array('payment_method' => 'Authorize.net','walletlink' => $walletlink));

       //Email work
       Engine_Api::_()->getApi('mail', 'core')->sendSystem($user, 'payment_wallet_active', array(
         'wallet_terms' => $desc,
         'object_link' => 'https://' . $_SERVER['HTTP_HOST'] . Zend_Controller_Front::getInstance()->getRouter()->assemble(array("module" => 'payment', 'controller' => "settings", "action" => "wallet"), 'default', true),
       ));

       $subscription_id = $subscriptionParams->subscription_id;
       if(!empty($subscription_id)) {
         if($user) {
           Engine_Api::_()->payment()->firsttimeSignupSubscription($user);
         }
       }
     
      return 'active';
    // }

    return $this;
  }
  
  function setConfig($params) {
    
  }
  
  function test() {
  
  }
}
