<?php

/**
 * class d3_payment_heidelpay
 */
class d3_payment_heidelpay extends d3_payment_heidelpay_parent
{

    /**
     * Bool-Wert fuer das Handling von vorhandenen Kreditkarten-Kunden-Registrierungsdaten in Schritt3
     *
     * @var bool
     */
    protected $sHeidelpayFieldsForPayment;

    /**
     * Initiate and register module classes
     * intitiate reference number
     * reset payment success
     *
     * @return void
     */
    public function init()
    {
        parent::init();

        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;
        }

        $settings = oxNew('d3_d3heidelpay_models_settings_heidelpay', d3_cfg_mod::get('d3heidelpay'));
        oxRegistry::set('d3_d3heidelpay_models_settings_heidelpay', $settings);

        /** @var d3_d3heidelpay_models_factory $oFactory */
        $oFactory         = oxNew('d3_d3heidelpay_models_factory', d3_cfg_mod::get('d3heidelpay'));
        $this->d3HeidelpaySetErrorMessage($oFactory);
        $oFactory->initReferenceNumber();

        $oHeidelpayViewConfig = oxNew(
            'd3_d3heidelpay_models_viewconfig',
            d3_cfg_mod::get('d3heidelpay'),
            oxRegistry::get('oxRegistry'),
            $oFactory
        );
        $this->addTplParam('oHeidelpayViewConfig', $oHeidelpayViewConfig);

        $oFactory->resetPaymentSuccess();

        $paymentId = oxRegistry::getSession()->getBasket()->getPaymentId();
        if (empty($paymentId)) {
            return;
        }

        $payment = oxNew('oxPayment');
        if (false == $payment->load($paymentId)) {
            return;
        }

        $oHeidelPaySettings = oxNew(
            'd3_d3heidelpay_models_settings_heidelpay',
            d3_cfg_mod::get('d3heidelpay')
        );

        try {
            if ($oHeidelPaySettings->isAssignedToHeidelPayment($payment)) {
                oxRegistry::getSession()->deleteVariable('sess_challenge');
            }
        } catch (d3_d3heidelpay_models_payment_exception_PaymentNotReferencedToHeidelpayException $exception) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->log(
                d3log::INFO,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'payment is not referenced to heidelpay',
                'paymentid: ' . $payment . PHP_EOL . 'Exception: ' . $exception->getMessage()
            );
        }
    }

    /**
     * Injects the Trusted Shops Excellence protection into the current session
     *
     * @return bool true if TSprotection is set, false if it was removed
     */
    public function setTsProtection()
    {
        $oBasket = $this->getSession()->getBasket();
        if (oxRegistry::getConfig()->getRequestParameter('bltsprotection')) {
            $sTsProductId = oxRegistry::getConfig()->getRequestParameter('stsprotection');
            $oBasket->setTsProductId($sTsProductId);
            oxRegistry::getSession()->setVariable('stsprotection', $sTsProductId);

            return true;
        }
        oxRegistry::getSession()->deleteVariable('stsprotection');
        $oBasket->setTsProductId(null);

        return false;
    }

    /**
     * Injects the Trusted Shops Excellence protection into the POST superglobal
     *
     * @return mixed
     */
    public function validatePayment()
    {
        $oBasket = $this->getSession()->getBasket();
        if ($oBasket->getTsProductId()) {
            $_POST['bltsprotection'] = true;
            $_POST['stsprotection']  = $oBasket->getTsProductId();
        }

        $return = parent::validatePayment();

        if (empty($return) || false === stristr($return, 'order')) {
            return $return;
        }

        $paymentId = $this->getD3PaymentId();

        $payment = oxNew('oxPayment');
        $payment->load($paymentId);

        $heidelPaySettings = oxNew('d3_d3heidelpay_models_settings_heidelpay', d3_cfg_mod::get('d3heidelpay'));
        if (false == $heidelPaySettings->isAssignedToHeidelPayment($payment)) {
            return $return;
        }

        $heidelPayment = $heidelPaySettings->getPayment($payment);
        if ($heidelPayment instanceof d3_d3heidelpay_models_payment_invoice_secured
                || $heidelPayment instanceof d3_d3heidelpay_models_payment_invoice_unsecured
                || $heidelPayment instanceof d3_d3heidelpay_models_payment_directdebit_secured
        ) {
            $birthdate = $this->getConfig()->getRequestParameter('d3birthdate');

            if ($this->d3ValidateBirthdateInput($birthdate, $paymentId)) {
                // log message
                d3_cfg_mod::get('d3heidelpay')->d3getLog()->log(
                    d3log::WARNING,
                    __CLASS__,
                    __FUNCTION__,
                    __LINE__,
                    'birthdate is empty but required',
                    'user didn\'t set the birthdate for invoice payment. input: ' . var_export($birthdate, true)
                );
                $this->_sPaymentError = 1;

                return null;
            }

            $this->getUser()->assign(
                array('oxbirthdate' => $birthdate[$paymentId])
            );

            $this->getUser()->save();

            return $return;
        }

        if (($heidelPayment instanceof d3_d3heidelpay_models_payment_easycredit
                || $heidelPayment instanceof d3_d3heidelpay_models_payment_przelewy24
                || $heidelPayment instanceof d3_d3heidelpay_models_payment_ideal
                || $heidelPayment instanceof d3_d3heidelpay_models_payment_paypal
                || $heidelPayment instanceof d3_d3heidelpay_models_payment_directdebit_secured
                || $heidelPayment instanceof d3_d3heidelpay_models_payment_invoice_secured
            ) && false == oxRegistry::getConfig()->getRequestParameter('paymentid')
        ) {
            return false;
        }

        if ($heidelPayment instanceof d3_d3heidelpay_models_payment_easycredit) {
            return $this->handleD3HeidelpayEasyCredit($paymentId);
        }

        return $return;
    }

    /**
     * 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'"
        );
    }

    /**
     * @param oxPayment $oPayment
     * @param string    $sTemplate
     *
     * @return string
     */
    public function d3GetPaymentFormTemplateName(oxPayment $oPayment, $sTemplate = '')
    {
        if (empty($sTemplate)) {
            $sTemplate = d3_cfg_mod::get('d3heidelpay')->getMappedThemeId();
        }

        $sTemplate = strtolower($sTemplate);

        /** @var d3_d3heidelpay_models_viewconfig $oHeidelpayViewConfig */
        $oHeidelpayViewConfig = oxNew(
            'd3_d3heidelpay_models_viewconfig',
            d3_cfg_mod::get('d3heidelpay'),
            oxRegistry::get('oxRegistry'),
            oxNew('d3_d3heidelpay_models_factory', d3_cfg_mod::get('d3heidelpay'))
        );
        $oHeidelPaySettings   = $oHeidelpayViewConfig->getSettings();
        $return               = $this->d3GetDefaultPaymentFormTemplateName($oPayment);
        if ($oHeidelPaySettings->isAssignedToHeidelPayment($oPayment)) {
            $oHeidelPayment = $oHeidelPaySettings->getPayment($oPayment);
            if ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_creditcard
                || $oHeidelPayment instanceof d3_d3heidelpay_models_payment_debitcard
            ) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_cards.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_directdebit
                || $oHeidelPayment instanceof d3_d3heidelpay_models_payment_directdebit_secured
            ) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_debitnote.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_sofortueberweisung) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_sofort.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_giropay) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_giropay.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_ideal) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_ideal.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_eps) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_eps.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_billsafe) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_billsafe.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_paypal) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_paypal.tpl";
//            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_postfinance) {
//                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_postfinance.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_przelewy24) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_przelewy24.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_masterpass) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_masterpass.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_easycredit) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_easycredit.tpl";
            } elseif ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_invoice_secured
                || $oHeidelPayment instanceof d3_d3heidelpay_models_payment_invoice_unsecured
            ) {
                $return = "d3_d3heidelpay_views_{$sTemplate}_tpl_payment_invoice.tpl";
            }
        }

        return $return;
    }

    /**
     * @param oxPayment $oPayment
     *
     * @return string
     */
    public function d3GetDefaultPaymentFormTemplateName(oxPayment $oPayment)
    {
        $sPaymentId = $oPayment->getId();

        if ($sPaymentId == "oxidcashondel") {
            return "page/checkout/inc/payment_oxidcashondel.tpl";
        } elseif ($sPaymentId == "oxidcreditcard") {
            return "page/checkout/inc/payment_oxidcreditcard.tpl";
        } elseif ($sPaymentId == "oxiddebitnote") {
            return "page/checkout/inc/payment_oxiddebitnote.tpl";
        } else {
            return "page/checkout/inc/payment_other.tpl";
        }
    }

    /**
     * @param oxPayment $oPayment
     *
     * @return bool
     * @throws d3_d3heidelpay_models_payment_exception_PaymentNotReferencedToHeidelpayException
     */
    public function d3IsHeidelpayPaymentMethode(oxPayment $oPayment)
    {
        /** @var d3_d3heidelpay_models_viewconfig $oHeidelpayViewConfig */
        $oHeidelpayViewConfig = oxNew(
            'd3_d3heidelpay_models_viewconfig',
            d3_cfg_mod::get('d3heidelpay'),
            oxRegistry::get('oxRegistry'),
            oxNew('d3_d3heidelpay_models_factory', d3_cfg_mod::get('d3heidelpay'))
        );
        $oHeidelPaySettings   = $oHeidelpayViewConfig->getSettings();
        if ($oHeidelPaySettings->isAssignedToHeidelPayment($oPayment)) {
            $oHeidelPayment = $oHeidelPaySettings->getPayment($oPayment);
            if ($oHeidelPayment instanceof d3_d3heidelpay_models_payment_abstract) {
                return true;
            }

            return false;
        }

        return false;
    }

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

        return $blIsMobile;
    }

    /**
     * @return string
     */
    public function render()
    {
        $mReturn = parent::render();

        $this->addTplParam('blD3HeidelpayEasycreditNotChecked', $this->isEasyCreditConsentNotConfirmed());
        $this->addTplParam(
            'blD3HeidelpayAllowEasyCredit',
            $this->isHeidelpayEasycreditAllowed(oxRegistry::getSession()->getBasket())
        );
        $this->addTplParam('blD3HeidelpayAllowPostFinance', $this->isPaymentAllowedForCountryAndCurrency('CH', 'CHF'));
        $this->addTplParam('blD3HeidelpayAllowPrzelewy24', $this->isPaymentAllowedForCountryAndCurrency('PL', 'PLN'));
        $this->addTplParam('blD3HeidelpayAllowIdeal', $this->isPaymentAllowedForCountryAndCurrency('NL', 'EUR'));
        $this->addTplParam('blD3HeidelpayHasSameAdresses', $this->d3HeidelpayHasSameAdresses());

        return $mReturn;
    }

    /**
     * @param $sCountryIsoAlpha2
     * @param $sCurrencyName
     *
     * @return bool
     */
    public function isPaymentAllowedForCountryAndCurrency($sCountryIsoAlpha2, $sCurrencyName)
    {
        $sCountryId = $this->getUser()->getFieldData('oxcountryid');

        /** @var $oCountry oxcountry * */
        $oCountry = oxNew('oxcountry');
        if ($oCountry->load($sCountryId) && $oCountry->getFieldData('oxisoalpha2') == $sCountryIsoAlpha2 //
            && $this->getActCurrency()->name == $sCurrencyName
        ) {
            return true;
        }

        return false;
    }

    protected function d3HeidelpayHasSameAdresses()
    {
        $oDelAdress = null;
        if (false == ($soxAddressId = oxRegistry::getConfig()->getRequestParameter('deladrid'))) {
            $soxAddressId = oxRegistry::getSession()->getVariable('deladrid');
        }
        if (false == $soxAddressId) {
            return true;
        }
        $oUser      = $this->getUser();
        $oDelAdress = oxNew('oxaddress');
        $oDelAdress->load($soxAddressId);

        //get delivery country name from delivery country id
        if ($oDelAdress->oxaddress__oxcountryid->value && $oDelAdress->oxaddress__oxcountryid->value != -1) {
            $oCountry = oxNew('oxcountry');
            $oCountry->load($oDelAdress->oxaddress__oxcountryid->value);
            $oDelAdress->oxaddress__oxcountry = clone $oCountry->oxcountry__oxtitle;
        }

        $userAdress = array(
            $oUser->getFieldData('oxfname'),
            $oUser->getFieldData('oxlname'),
            $oUser->getFieldData('oxcompany'),
            $oUser->getFieldData('oxstreet'),
            $oUser->getFieldData('oxstreetnr'),
            $oUser->getFieldData('oxzip'),
            $oUser->getFieldData('oxcity')
        );

        $deliverAdress = array(
            $oDelAdress->getFieldData('oxfname'),
            $oDelAdress->getFieldData('oxlname'),
            $oDelAdress->getFieldData('oxcompany'),
            $oDelAdress->getFieldData('oxstreet'),
            $oDelAdress->getFieldData('oxstreetnr'),
            $oDelAdress->getFieldData('oxzip'),
            $oDelAdress->getFieldData('oxcity')
        );


        if ($userAdress == $deliverAdress) {
            return true;
        }

        return false;
    }

    public function d3GetMessageTemplateName()
    {
        $sTheme    = 'd3_d3heidelpay_views_tpl_messages.tpl';
        $sTemplate = d3_cfg_mod::get('d3heidelpay')->getMappedThemeId();

        if ($sTemplate != 'azure' && $sTemplate != 'mobile') {
            $sTheme = "d3_d3heidelpay_views_{$sTemplate}_tpl_messages.tpl";
        }

        return $sTheme;
    }

    /**
     * @return mixed
     */
    protected function getD3PaymentId()
    {
        $paymentId = oxRegistry::getConfig()->getRequestParameter('paymentid');
        if (empty($paymentId)) {
            $paymentId = $this->getSession()->getVariable('paymentid');
        }

        return $paymentId;
    }

    /**
     * @param $birthdate
     * @param $paymentId
     *
     * @return bool
     */
    protected function d3ValidateBirthdateInput($birthdate, $paymentId)
    {
        return empty($birthdate)
            || empty($birthdate[$paymentId])
            || empty($birthdate[$paymentId]['day'])
            || empty($birthdate[$paymentId]['month'])
            || empty($birthdate[$paymentId]['year']);
    }

    /**
     * @return bool
     */
    protected function isEasyCreditConsentNotConfirmed()
    {
        return (bool)$this->getConfig()->getRequestParameter('d3heidelpayeasycreditnotchecked');
    }

    protected function handleD3HeidelpayEasyCredit($paymentId)
    {
        $easycreditTransactionIds = $this->getConfig()->getRequestParameter(
            'd3heidelpayEasycreditTransactionLogid'
        );

        if (false == is_array($easycreditTransactionIds) || empty($easycreditTransactionIds[$paymentId])) {
            return 'payment?d3heidelpayeasycreditnotchecked=1';
        }

        $transactionlog = oxNew('d3transactionlog', oxNew('d3_d3heidelpay_models_transactionlog_reader_heidelpay'));
        if (false == $transactionlog->load($easycreditTransactionIds[$paymentId])) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->log(
                d3log::ERROR,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'could not load d3transactionlog',
                'd3transactionlogid: ' . var_export($easycreditTransactionIds[$paymentId], true)
            );

            return 'payment?paymenterror=-99';
        }

        /** @var d3_d3heidelpay_models_transactionlog_reader_heidelpay $response */
        $response    = $transactionlog->getTransactiondata();
        $redirectUrl = $response->getRedirecturl();

        if (empty($redirectUrl)) {
            d3_cfg_mod::get('d3heidelpay')->d3getLog()->log(
                d3log::ERROR,
                __CLASS__,
                __FUNCTION__,
                __LINE__,
                'redirect url is empty:' . $redirectUrl,
                var_export($response, true)
            );

            return 'payment?paymenterror=-99';
        }

        d3_cfg_mod::get('d3heidelpay')->d3getLog()->log(
            d3log::INFO,
            __CLASS__,
            __FUNCTION__,
            __LINE__,
            'redirect customer to url:' . $redirectUrl,
            $redirectUrl
        );
        oxRegistry::getConfig()->pageClose();
        oxRegistry::getUtils()->redirect($redirectUrl, false, 302);

        return '';
    }

    public function isHeidelpayEasycreditAllowed(oxBasket $oxBasket)
    {
        $oxPrice = $oxBasket->getPrice();
        $price   = $oxPrice->getPrice();

        $basketUser = $oxBasket->getBasketUser();
        $possiblePSFields = array('oxfname', 'oxlname', 'oxstreet', 'oxstreetnr', 'oxcity');

        $isNotPackstation = true;
        foreach ($possiblePSFields as $field) {
            if (false === stristr(strtolower($basketUser->getFieldData($field)), 'packstation')) {
                continue;
            }
            $isNotPackstation = false;
        }

        return ($this->isPaymentAllowedForCountryAndCurrency('DE', 'EUR')
            && ($price >= 200 && 3000 >= $price) && $isNotPackstation);
    }

    /**
     * @param $oFactory
     *
     */
    protected function d3HeidelpaySetErrorMessage($oFactory)
    {
        $oldReference = $oFactory->getReferenceNumber();
        if ($oldReference) {
            $oTransAction = $oFactory->getLatestTransactionByReference($oldReference);
            if ($oTransAction instanceof d3transactionlog) {
                /** @var d3_d3heidelpay_models_transactionlog_reader_heidelpay $reader */
                $reader = $oTransAction->getTransactiondata();
                if ($reader->getResult() != "ACK") {
                    $string      = 'd3heidelpay_' . $reader->getReturncode();
                    $translation = oxRegistry::getLang()->translateString($string);

                    if ($translation === $string) {
                        d3_cfg_mod::get('d3heidelpay')->d3getLog()->log(
                            d3log::ERROR,
                            __CLASS__,
                            __FUNCTION__,
                            __LINE__,
                            'Translation not found: ' . $string,
                            $string
                        );
                        $translation = oxRegistry::getLang()->translateString('d3heidelpay_execute_error');
                    }

                    $exception = oxNew('oxException', $translation);
                    oxRegistry::get("oxUtilsView")->addErrorToDisplay($exception);
                }
            }
        }
    }
}
