<?php

/**
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * https://www.d3data.de
 *
 * @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
 * @author    D3 Data Development - Daniel Seifert <info@shopmodule.com>
 * @link      https://www.oxidmodule.com
 */

namespace D3\MailConfigChecker\Application\Controller\Admin;

use Assert\Assert;
use Assert\InvalidArgumentException;
use D3\MailConfigChecker\Application\Model\Constants;
use D3\MailConfigChecker\Application\Model\Exception\d3TranslatableLazyAssertionException;
use Exception;
use OxidEsales\Eshop\Application\Controller\Admin\AdminDetailsController;
use OxidEsales\Eshop\Application\Model\Shop;
use OxidEsales\Eshop\Core\Email;
use OxidEsales\Eshop\Core\Registry;

class MailConfigCheck extends AdminDetailsController
{
    protected $_sThisTemplate = '@'.Constants::OXID_MODULE_ID.'/admin/mailConfigCheck';
    protected string $testMailAddress;

    public function __construct()
    {
        parent::__construct();

        try {
            $infoMail = Registry::getConfig()->getActiveShop()->getFieldData( 'oxinfoemail' );
            Assert::that($infoMail)->email();
            $re                    = '/.*(@.*$)/m';
            $subst                 = "noreply$1";
            $this->testMailAddress = preg_replace($re, $subst, $infoMail);
        } catch (InvalidArgumentException) {
            $this->testMailAddress = 'test@example.tld';
        }

        $this->setSmtpCredentials();
    }

    protected function setSmtpCredentials(): void
    {
        $shop = Registry::getConfig()->getActiveShop();

        $this->addTplParam('smtpHost', $shop->getFieldData('oxsmtp'));
        $this->addTplParam('smtpUser', $shop->getFieldData('oxsmtpuser'));
    }

    public function render(): string
    {
        $this->checkDataAreSet();
        $this->addTplParam('shop', Registry::getConfig()->getActiveShop());
        $this->addTplParam('recipient', $this->testMailAddress);

        return parent::render();
    }

    protected function checkDataAreSet(): void
    {
        try {
            /** @var Shop $shop */
            $shop = Registry::getConfig()->getActiveShop();
            $lang = Registry::getLang();

            Assert::lazy()
                ->setExceptionClass(d3TranslatableLazyAssertionException::class)
                ->that($shop->getFieldData('oxsmtp'), $lang->translateString('SHOP_MAIN_SMTPSERVER'))
                ->notBlank($lang->translateString('D3_MAILCHECKER_ASSERTIONS_NOTSET'))
                ->regex('/.*:(587|2525)$/m', $lang->translateString('D3_MAILCHECKER_ASSERTIONS_NOPORT'))
                ->that($shop->getFieldData('oxsmtpuser'), $lang->translateString('SHOP_MAIN_SMTPUSER'))
                ->notBlank($lang->translateString('D3_MAILCHECKER_ASSERTIONS_NOTSET'))
                ->that($shop->getFieldData('oxsmtppwd'), $lang->translateString('SHOP_MAIN_SMTPPASSWORD'))
                ->notBlank($lang->translateString('D3_MAILCHECKER_ASSERTIONS_NOTSET'))
                ->that($shop->getFieldData('oxinfoemail'), $lang->translateString('SHOP_MAIN_INFOEMAIL'))
                ->email($lang->translateString('D3_MAILCHECKER_ASSERTIONS_NOTSET'))
                ->that($shop->getFieldData('oxorderemail'), $lang->translateString('SHOP_MAIN_ORDEREMAIL'))
                ->email($lang->translateString('D3_MAILCHECKER_ASSERTIONS_NOTSET'))
                ->that($shop->getFieldData('oxowneremail'), $lang->translateString('SHOP_MAIN_OWNEREMAIL'))
                ->email($lang->translateString('D3_MAILCHECKER_ASSERTIONS_NOTSET'))
                ->verifyNow();
        } catch (InvalidArgumentException $e) {
            Registry::getUtilsView()->addErrorToDisplay(nl2br($e->getMessage()));
        }
    }

    public function checkConfiguration(): void
    {
        $this->getCurrentMailer();
    }

    protected function getCurrentMailer(): void
    {
        try {
            $shop = Registry::getConfig()->getActiveShop();

            $mail = oxNew(Email::class);
            $mail->setRecipient(
                trim(Registry::getRequest()->getRequestEscapedParameter('recipient')) ?: $this->testMailAddress
            );
            $mail->setBody('.');
            $mail->setFrom($shop->getFieldData('oxowneremail'));

            $mail->set("SMTPDebug", true);  // don't set via iDebug = 6 because different handling
            $mail->setSmtp();

            ob_start();
            $mail->send();
            $communication = ob_get_contents();
            ob_end_clean();

            $re = '/(^|\<br\>)(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s)/m';
            $subst = "$1";
            $communication = preg_replace($re, $subst, $communication);
            $this->addTplParam('mailer', $mail->getMailer());
            $this->addTplParam('communication', $communication);
        } catch (Exception $e) {
            ob_end_clean();
            Registry::getUtilsView()->addErrorToDisplay($e);
        }

        restore_error_handler();
    }
}