<?php

/**
 * Class d3_order_heidelpay
 */
class d3_order_heidelpay extends d3_order_heidelpay_parent
{

    /**
     * Return-Klasse, die von der hp_resonse.php nach Aufruf order::execute() erhalten wurde (z.B. "thankyou")
     *
     * @var string
     */
    public $s3dsClassReturn;

    /**
     * Kontrollvariable fuer die Beendigung des 3DSecure-iFrames
     *
     * @var string
     */
    protected $_blIsHeidelpaySecureSuccess = false;

    protected $_sHeidelpaySecureTemplate = 'heidelpay_order_3ds.tpl';

    protected $_sHeidelpaySecureiFrameTemplate = 'heidelpay_order_3ds_iframe.tpl';

    /**
     * array of years
     * @var array
     */
    protected $_aCreditYears = null;

    /**
     * class constructor, register d3_d3heidelpay_models_settings_heidelpay
     */
    public function __construct()
    {
        $settings = oxNew('d3_d3heidelpay_models_settings_heidelpay', d3_cfg_mod::get('d3heidelpay'));
        oxRegistry::set('d3_d3heidelpay_models_settings_heidelpay', $settings);
        parent::__construct();
    }

    /**
     * try to execute order
     * Returns the following action
     *
     * @throws oxException
     * @return string Return-Wert fuer weiteren Klassen-Shopaufruf
     */
    public function execute()
    {
        if (false == d3_cfg_mod::get('d3heidelpay')->isActive()) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'module is inactive',
                'module is inactive'
            );

            return parent::execute();
        }

        try {
            $mPayment = $this->getPayment();

            if (false === $mPayment) {
                d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                    d3log::WARNING,
                    __CLASS__,
                    __FUNCTION__,
                    __LINE__,
                    'payment is not set, execute parent',
                    print_r(var_export($mPayment, true), true)
                );

                return parent::execute();
            }

            $blUseHPStore = $this->getConfig()->getRequestParameter("usehpstore");
            if($this->hasUserHPStoreData($mPayment->getId()) && $blUseHPStore) {
                $oUserStorage = $this->getUserHPStoreData($mPayment->getId());
                $this->getSession()->setVariable('dynvalue', $oUserStorage->aDynValue);
                d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                    d3log::INFO,
                    __CLASS__,
                    __FUNCTION__,
                    __LINE__,
                    'set user storage data to session',
                    print_r(var_export($oUserStorage->aDynValue, true), true)
                );
                return parent::execute();
            }

            /** @var d3_d3heidelpay_models_settings_heidelpay $settings */
            $settings       = oxRegistry::get('d3_d3heidelpay_models_settings_heidelpay');
            $oHeidelPayment = $settings->getPayment($mPayment);

            /** @var d3_d3heidelpay_controllers_order $controllerFacade */
            $controllerFacade = oxNew(
                'd3_d3heidelpay_controllers_order',
                oxRegistry::get('oxRegistry'),
                d3_cfg_mod::get('d3heidelpay'),
                oxNew('d3_d3heidelpay_models_factory', d3_cfg_mod::get('d3heidelpay'))
            );
            $mResult          = $controllerFacade->execute($oHeidelPayment);

            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'd3_d3heidelpay_controllers_order return value',
                print_r(var_export($mResult, true), true)
            );

            if (true === $mResult) {
                return parent::execute();
            }

            if (is_string($mResult)) {
                return $mResult;
            }

        } catch (d3_d3heidelpay_models_verify_exception_notloggedinexception $oEx) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'exception handling',
                get_class($oEx) . PHP_EOL . $oEx->getMessage() . PHP_EOL . $oEx->getTraceAsString()
            );

            return 'user';
        } catch (d3_d3heidelpay_models_verify_exception_checksessionchallengeexception $oEx) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'exception handling',
                get_class($oEx) . PHP_EOL . $oEx->getMessage() . PHP_EOL . $oEx->getTraceAsString()
            );

            return '';
        } catch (d3_d3heidelpay_models_verify_exception_agbnotacceptedexception $oEx) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'exception handling',
                get_class($oEx) . PHP_EOL . $oEx->getMessage() . PHP_EOL . $oEx->getTraceAsString()
            );
            $this->_blConfirmAGBError = 1;

            return '';
        } catch (d3_d3heidelpay_models_verify_exception_customerinformationnotacceptedexception $oEx) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'exception handling',
                get_class($oEx) . PHP_EOL . $oEx->getMessage() . PHP_EOL . $oEx->getTraceAsString()
            );
            $this->_blConfirmCustInfoError = 1;

            return '';
        } catch (d3_d3heidelpay_models_payment_exception_PaymentNotReferencedToHeidelpayException $oEx) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'exception handling',
                get_class($oEx) . PHP_EOL . $oEx->getMessage() . PHP_EOL . $oEx->getTraceAsString()
            );

            return parent::execute();
        } catch (d3_d3heidelpay_models_settings_exception_emptypaymentlistexception $oEx) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'exception handling',
                get_class($oEx) . PHP_EOL . $oEx->getMessage() . PHP_EOL . $oEx->getTraceAsString()
            );

            return parent::execute();
        }

        /** @var oxException $exception */
        $exception = oxNew('oxException', oxRegistry::getLang()->translateString('d3heidelpay_execute_error'));
        oxRegistry::get("oxUtilsView")->addErrorToDisplay($exception);

        d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
            d3log::INFO,
            __CLASS__,
            __FUNCTION__,
            __LINE__,
            'exception handling',
            get_class($exception) . PHP_EOL . $exception->getMessage() . PHP_EOL . $exception->getTraceAsString()
        );

        return '';
    }

    /**
     * {@inheritdoc}
     */
    protected function _getNextStep($mSuccess)
    {
        if (false == d3_cfg_mod::get('d3heidelpay')->isActive()) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'module is inactive',
                'module is inactive'
            );

            return parent::_getNextStep($mSuccess);
        }

        if ($mSuccess === 'Show3DSecureFrame') {
            $sTemplateFor3DSecure = 'heidelpay_order_3ds.tpl';
            if ($this->d3CheckForMobileTheme()) {
                $sTemplateFor3DSecure = 'heidelpay_order_3ds_mobile.tpl';
            }

            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'next step is Show3DSecureFrame',
                "set return: 'order?fnc=Show3DSecureFrame&heidelpaytemplate=" . $sTemplateFor3DSecure . "'"
            );

            return 'order?fnc=Show3DSecureFrame&heidelpaytemplate=' . $sTemplateFor3DSecure;
        }

        $sReturn = parent::_getNextStep($mSuccess);

        /** @var d3_d3heidelpay_controllers_order $controllerFacade */
        $controllerFacade = oxNew(
            'd3_d3heidelpay_controllers_order',
            oxRegistry::get('oxRegistry'),
            d3_cfg_mod::get('d3heidelpay'),
            oxNew('d3_d3heidelpay_models_factory', d3_cfg_mod::get('d3heidelpay'))
        );

        $mNextStep = $controllerFacade->getNextOrderStep($sReturn, $mSuccess);

        d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
            d3log::INFO,
            __CLASS__,
            __FUNCTION__,
            __LINE__,
            'return value',
            "success: $sReturn, nextstep: " . var_export($mNextStep, true)

        );

        return $mNextStep;

    }

    /**
     * {@inheritdoc}
     */
    public function render()
    {
        $ret = parent::render();
        if (false === d3_cfg_mod::get('d3heidelpay')->isActive()) {
            return $ret;
        }
        $this->addTplParam('isHeidelpayDebugMode', (bool)d3_cfg_mod::get('d3heidelpay')->getValue('d3heidelpay_blTestmode'));

        $oHeidelpayViewConfig = oxNew(
            'd3_d3heidelpay_models_viewconfig',
            d3_cfg_mod::get('d3heidelpay'),
            oxRegistry::get('oxRegistry'),
            oxNew('d3_d3heidelpay_models_factory', d3_cfg_mod::get('d3heidelpay'))
        );

        $this->addTplParam('oHeidelpayViewConfig', $oHeidelpayViewConfig);
        $sHeidelpayTemplate = oxRegistry::getConfig()->getRequestParameter('heidelpaytemplate');

        if (false == empty($sHeidelpayTemplate)) {
            $this->_sThisTemplate = $sHeidelpayTemplate;
        }

        return $this->_sThisTemplate;
    }

    /**
     * Return route to payment if no d3 secure payment
     *
     * @return string partizielle rueckgabe der klasse
     */
    public function show3DSecureFrame()
    {
        if (false == d3_cfg_mod::get('d3heidelpay')->isActive()) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'module is inactive',
                'module is inactive'
            );

            return '';
        }

        /** @var d3_d3heidelpay_models_factory $oFactory */
        $oFactory = oxNew('d3_d3heidelpay_models_factory', d3_cfg_mod::get('d3heidelpay'));
        $sReturn  = '';

        // irgendein Wert nicht gesetzt oder falsch? Dann zurueck zu Schitt 3 !
        if (false == $oFactory->getSettings()->isSecurePayment(oxRegistry::get('oxRegistry'), $oFactory)) {
            $sReturn = 'payment?payerror=2';
        }

        d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
            d3log::INFO,
            __CLASS__,
            __FUNCTION__,
            __LINE__,
            'return value',
            var_export($sReturn, true)
        );

        return $sReturn;
    }

    /**
     * @return bool
     */
    public function d3CheckForMobileTheme()
    {
        $blIsMobile = false;
        if (class_exists('oeThemeSwitcherThemeManager') == true) {
            /** @var oeThemeSwitcherThemeManager $oThemeManager */
            $oThemeManager = new oeThemeSwitcherThemeManager();
            $blIsMobile    = $oThemeManager->isMobileThemeRequested();
        }

        return $blIsMobile;
    }

    /**
     * Template variable getter. Returns array of years for credit cards
     *
     * @return array
     */
    public function getCreditYears()
    {
        if ($this->_aCreditYears === null) {
            $this->_aCreditYears = false;

            $this->_aCreditYears = range(date('Y'), date('Y') + 10);
        }

        return $this->_aCreditYears;
    }

    //<editor-fold desc="TODO:3 ways with existing paymentdata possible. see /tests/acceptance/selenium/dudeWantToPay.graphml">
    /**
     * Returns true if user has stored payment data
     *
     * @param $sPaymentId
     *
     * @return bool
     */
    public function hasUserHPStoreData($sPaymentId)
    {
        if (false == d3_cfg_mod::get('d3heidelpay')->isActive()) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->Log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'module is inactive',
                'module is inactive'
            );

            return false;
        }

        // keine Anzeige gespeicherter Registrierungsdaten erlauben?
        if (false == d3_cfg_mod::get('d3heidelpay')->getValue('d3heidelpay_blShowStoredHPData')) {
            return false;
        }

        return (bool)$this->getUserHPStoreID($sPaymentId);
    }

    /**
     * Returns user stored payment data
     *
     * @param $sPaymentId
     *
     * @return bool|object
     */
    public function getUserHPStoreData($sPaymentId)
    {
        if (false == d3_cfg_mod::get('d3heidelpay')->isActive()) {
            return '';
        }

        $oxId = $this->getUserHPStoreID($sPaymentId);
        if (false == $oxId) {
            return '';
        }

        /** @var oxbase $oUsrStoreData */
        $oUsrStoreData = oxNew('oxbase');
        $oUsrStoreData->init('d3hpuid');
        $oUsrStoreData->load($oxId);

        $oUsrStoreData->aDynValue = unserialize($oUsrStoreData->d3hpuid__oxpaymentdata->rawValue);
        $oUsrStoreData->aDynValue['oxuid'] = $oUsrStoreData->getFieldData('oxuid');

        return $oUsrStoreData;
    }

    /**
     * Returns id of user stored payment data
     *
     * @param $sPaymentId
     *
     * @return string
     */
    public function getUserHPStoreID($sPaymentId)
    {
        if (false == ($sUserID = $this->getSession()->getVariable("usr"))) {
            return '';
        }

        return oxDb::getDb()->getOne(
            "SELECT `oxid` FROM `d3hpuid` WHERE `oxuserid` = '$sUserID' AND `oxpaymentid` = '$sPaymentId'"
        );
    }
    //</editor-fold>

    /**
     * @return string
     */
    public function d3GetAfterStepTemplate()
    {
        $storeTemplate  = "payment_inc_storeduid.tpl";
        $iFrameTemplate = "heidelpay_order_iframe.tpl";
        if($this->d3CheckForMobileTheme()) {
            $storeTemplate  = "payment_inc_storeduid_mobile.tpl";
            $iFrameTemplate = "heidelpay_order_iframe_mobile.tpl";
        }

        $blUseHPStore = $this->getConfig()->getRequestParameter("usehpstore");
        $oBasket      = $this->getBasket();
        $sPaymentid   = $oBasket->getPaymentId();

        if ($this->hasUserHPStoreData($sPaymentid) && is_null($blUseHPStore) ) {
            return $storeTemplate;
        }

        return $iFrameTemplate;
    }

    /**
     * @return string
     */
    public function d3PayWithStoreData()
    {

        $oBasket      = $this->getBasket();
        $sPaymentid   = $oBasket->getPaymentId();

        $blUseHPStore = $this->getConfig()->getRequestParameter("usehpstore");
        if($this->hasUserHPStoreData($sPaymentid) && $blUseHPStore) {
            return $this->execute();
        }
        return "";
    }
}
