<?php
/**
* @package XenCentral Ad Server
* @author Skydevelop EU
* @copyright Drnoyan & Nalyan LDA, Portugal, EU
* @license http://www.dnf.pt/eula.html
* @link http://www.skydevelop.com
* @revision 97
* @version 2.0.0 beta 3 rev. 3
*/

class XenCentral_AdServer_ControllerPublic_Credit
    extends XenForo_ControllerPublic_Abstract
    implements XenCentral_Framework_ControllerPublic_PaymentApiInterface
{
    protected function _checkCsrf($action)
    {
        if(in_array($action, array('PurchaseReturn', 'PurchaseNotify'))) {
            return;
        }

        parent::_checkCsrf($action);
    }

    public function actionPurchase()
    {
        $credit=$this->getInput()->filterSingle('credit', XenForo_Input::UNUM);
        $methodList = new XenCentral_PaymentApi_MethodList(
            'ads/credit',
            'XenCentral_AdServer_ControllerPublic_Credit',
            new XenForo_Phrase('xcas_purchase_credit_for_user_x', array('user' => XenForo_Visitor::getInstance()->username)),
            XenForo_Visitor::getInstance()->getUserId(),
            $credit,
            XenForo_Application::getOptions()->xcas_transaction_currency
        );

        $methodList->setAdditionalInformation(array(
            'user_id' => XenForo_Visitor::getUserId(),
            'credit' => $credit,
        ));

        if ($paypalEmail = $this->_getOptionsModel()->getPaypalEmail()) {
            $methodList->addPayPal($paypalEmail, $this->_getOptionsModel()->debugMode());
        }

        $methodList->addManualMethod($this->_getOptionsModel()->debugMode());

        if (XenForo_Visitor::getInstance()->isSuperAdmin()) {
            $methodList->addLocalMethod();
        }

        $paymentApiErrors = array();

        $paymentApiForms = $methodList->getForms($paymentApiErrors);

        if (!empty($paymentApiErrors)) {
            if (XenForo_Visitor::getInstance()->isSuperAdmin()) {
                return $this->responseError(implode('<br />', $paymentApiErrors));
            }
        }

        if (empty($paymentApiForms)) {
            return $this->responseMessage(new XenForo_Phrase('xcfw_no_payment_methods_configured'));
        }

        foreach ($paymentApiForms AS &$paymentMethodInfo) {
            $paymentMethodInfo['title'] = new XenForo_Phrase('xcfw_pay_via_' . $paymentMethodInfo['id']);
        }

        return $this->responseView('XenCentral_AdServer_ViewPublic_Credit_Purchase', 'xcas_confirm_credit_purchase', array(
                'forms' => $paymentApiForms,
                'user' => XenForo_Visitor::getInstance()->toArray(),
                'credit'=> $credit,
                'currency'=> XenForo_Application::getOptions()->xcas_transaction_currency,
                'breadCrumbs'=> $this->_getBreadCrumbs(new XenForo_Phrase('xcas_confirm_credit_purchase'))
            )
        );
    }

    public function actionPurchaseCancel()
    {
        // redirect to ad list again
        return $this->responseRedirect(
            XenForo_ControllerResponse_Redirect::SUCCESS,
            XenForo_Link::buildPublicLink('ads')
        );
    }

    public function actionPurchaseReturn()
    {
        $paymentMethod = $this->_assertValidPaymentMethod();

        if ($paymentMethod->validateRequest()) {
            $transactionId = $paymentMethod->getTransactionId();
            $processed = $paymentMethod->transactionProcessed();
            if (!$processed) {
                // try to process transaction
                $processed = false;
                try {
                    $processed = $this->_processTransaction($paymentMethod);
                } catch (Exception $ex) {

                }
                if ($processed) {
                    $paymentMethod->saveTransaction();
                    $processed = $paymentMethod->transactionProcessed();
                } else {
                    return $this->responseMessage($paymentMethod->getErrors());
                }
            }
            if (!$processed) {
                // still not processed would mean some error
                // this would most likely mean IPN was not received yet
                return $this->responseMessage(new XenForo_Phrase('xcfw_your_payment_was_validated_but_processor_not_confirmed', array(
                    'transactionId' => $transactionId
                )));
            }

            if ($processed['status'] === 'payment') {
                $info = $paymentMethod->getAdditionalInfo();
                return $this->responseView('XenCentral_AdServer_ViewPublic_PaymentComplete', 'xcfw_redirect', array(
                    'phrase' => new XenForo_Phrase('xcas_your_purchase_is_successfully_activated'),
                    'link' => XenForo_Link::buildPublicLink('ads')
                ));
            } else {
                return $this->responseMessage(
                    new XenForo_Phrase('xcfw_payment_status_is_x',
                        array('status' => $processed['status'], 'transactionId' => $transactionId)
                    )
                );
            }
        }

        if ($paymentMethod->hasErrors()) {
            XenCentral_PaymentApi_Module::getInstance()->logError($paymentMethod);
        }

        // again, simply thank you page,
        // as some payment providers will not submit payment info to this page
        return $this->responseMessage(new XenForo_Phrase('xcfw_thank_you_for_payment'));
    }

    public function actionPurchaseNotify()
    {
        $paymentMethod = $this->_assertValidPaymentMethod();

        $response = new Zend_Controller_Response_Http();

        if ($paymentMethod->validateRequest()) {
            $processedTransaction = $paymentMethod->transactionProcessed();
            if (
                $processedTransaction == false // the first notification
                OR
                $processedTransaction['status'] != $paymentMethod->getType()
                AND $processedTransaction['status'] != 'payment' // some update BEFORE the payment was processed
            ) {
                // new transaction or transaction type was updated (pending was approved)
                if ($this->_processTransaction($paymentMethod)) {
                    $paymentMethod->saveTransaction();
                    $response->setHttpResponseCode(200);
                    if ($paymentMethod->getResponseRequired()) {
                        $response->setBody(new XenForo_Phrase('xcfw_payment_is_successfully_processed'));
                    }
                } else {
                    $response->setHttpResponseCode(500);
                    if ($paymentMethod->getResponseRequired()) {
                        $response->setBody($paymentMethod->getLastError());
                    }
                }
            }
        } else {
            $response->setHttpResponseCode(500);
            if ($paymentMethod->getResponseRequired()) {
                $response->setBody(new XenForo_Phrase('xcfw_there_was_a_problem_validating_the_payment'));
            }
        }

        if ($paymentMethod->hasErrors()) {
            XenCentral_PaymentApi_Module::getInstance()->logError($paymentMethod);
        }

        $response->sendResponse();
        exit;
    }

    public function actionPurchasePaymentInstructions()
    {
        $this->getRequest()->setParam('purchase_handler', __CLASS__);
        return $this->responseReroute('XenCentral_Framework_ControllerPublic_PaymentApi', 'payment-instructions');
    }

    /**
     * @param XenForo_Phrase $current
     * @return array
     */
    protected function _getBreadCrumbs($current = null)
    {
        $breadCrumbs = array(
            'account' => array(
                'href' => XenForo_Link::buildPublicLink('account'),
                'value' => new XenForo_Phrase('your_account')
            ),
            'home' => array(
                'href' => XenForo_Link::buildPublicLink('full:ads'),
                'value' => new XenForo_Phrase('xcas_my_ads')
            )
        );

        if ($current) {
            $requestPaths = XenForo_Application::get('requestPaths');
            $breadCrumbs['current'] = array(
                'href' => $requestPaths['fullUri'],
                'value' => $current
            );
        }

        return $breadCrumbs;
    }

    /**
     * @param $paymentMethod XenCentral_PaymentApi_Method
     * @return bool
     * @throws XenForo_ControllerResponse_Exception
     */
    protected function _processTransaction($paymentMethod)
    {
        $paymentInfo = $paymentMethod->getAdditionalInfo();

        if ($paymentMethod->getType() == 'payment') {
            $this->_getUserModel()->addUserCredit($paymentInfo['user_id'], $paymentInfo['credit']);

            // log purchase
            $this->_getCreditPurchaseLogModel()->logPayment(
                $paymentInfo['user_id'],
                time(),
                $paymentMethod->getInfoId(),
                $paymentMethod->getTransactionId()
            );
        } else if ($paymentMethod->getType() == 'refund') {
            $this->_getUserModel()->removeUserCredit($paymentInfo['user_id'], $paymentInfo['credit']);

            // log purchase
            $this->_getCreditPurchaseLogModel()->logPayment(
                $paymentInfo['user_id'],
                time(),
                $paymentMethod->getInfoId(),
                $paymentMethod->getTransactionId()
            );
        } else {
            // the other type we have are pending transactions, we do not do anything for them yet
        }

        // update banner active status to activate paused banners
        XenCentral_AdServer_Cron::updateBannerStatus();

        return true;
    }

    /**
     * @return XenCentral_PaymentApi_Method
     */
    protected function _assertValidPaymentMethod()
    {
        return $paymentMethod = $this->getHelper('XenCentral_Framework_ControllerHelper_PaymentApi')->assertValidPaymentMethod(
            $this->_getOptionsModel()->debugMode()
        );
    }

    /**
     * @return XenCentral_AdServer_Model_XenForo_User
     */
    protected function _getUserModel()
    {
        return $this->getModelFromCache('XenForo_Model_User');
    }

    /**
     * @return XenCentral_AdServer_Model_Options
     */
    protected function _getOptionsModel()
    {
        return $this->getModelFromCache('XenCentral_AdServer_Model_Options');
    }

    /**
     * @return XenCentral_AdServer_Model_Stats
     */
    protected function _getStatsModel()
    {
        return $this->getModelFromCache('XenCentral_AdServer_Model_Stats');
    }

    /**
     * @return XenCentral_AdServer_Model_Banner
     */
    protected function _getBannerModel()
    {
        return $this->getModelFromCache('XenCentral_AdServer_Model_Banner');
    }

    /**
     * @return XenCentral_AdServer_Model_Zone
     */
    protected function _getZoneModel()
    {
        return $this->getModelFromCache('XenCentral_AdServer_Model_Zone');
    }


    /**
     * @return XenCentral_AdServer_Model_CreditLog
     */
    protected function _getCreditPurchaseLogModel()
    {
        return $this->getModelFromCache('XenCentral_AdServer_Model_CreditLog');
    }
}