<?php

namespace Velis\Notification;

use Velis\App;
use Velis\Bpm\Workflow\Notification as WorkflowNotification;
use Velis\Mail\Mail;
use Velis\Mvc\View\Engine\EngineInterface;
use Velis\Notification;
use Velis\Notification\ContentModifier\StripTagsModifier;

/**
 * Mail notification renderer
 */
class MailRenderer
{
    protected EngineInterface $renderer;
    protected string $type;
    protected array $noReplyTemplates;
    protected bool $hideLogo;
    protected bool $showLoginButton;
    protected array $contentModifiers;

    public function __construct(
        EngineInterface $renderer,
        string $type,
        ?array $contentModifiers = [],
        ?array $noReplyTemplates = [],
        ?bool $hideLogo = false,
        ?bool $showLoginButton = false
    ) {
        $this->renderer = $renderer;
        $this->type = $type;
        $this->contentModifiers = $contentModifiers;
        $this->noReplyTemplates = $noReplyTemplates;
        $this->hideLogo = $hideLogo;
        $this->showLoginButton = $showLoginButton;
    }


    /**
     * Assigns variable to renderer
     *
     * @param string $key
     * @param mixed $value
     */
    public function __set($key, $value)
    {
        $this->renderer->assign($key, $value);
    }


    /**
     * Returns variable from renderer
     *
     * @param string $key
     * @return mixed
     */
    public function __get($key)
    {
        return $this->renderer->getVars($key);
    }


    /**
     * @param Mail $mail
     * @param $attachments
     * @param $layout
     * @return void
     * @throws SmartyException
     */
    public function setContent(Mail $mail, $attachments, $layout = 'default')
    {
        try {
            $mail->setContents(array(
                'body_text'   => $this->renderMessage($this->type, Notification::RENDER_TXT, $layout),
                'body_html'   => $this->renderMessage($this->type, Notification::RENDER_HTML, $layout),
                'attachments' => $attachments
            ));
        } catch (Exception $e) {
            error_log($e);
            throw $e;
        }
    }


    /**
     * Renders notification message
     *
     * @param string $messageTemplate
     * @param string $mode
     * @param string $layout
     * @return string
     * @throws SmartyException
     */
    protected function renderMessage(string $messageTemplate, string $mode, string $layout = 'default')
    {
        $smarty = clone $this->renderer;
        $smarty->assign("_rendererMode", $mode);

        if (in_array($messageTemplate, $this->noReplyTemplates) && !App::$config->layout->velisBrand) {
            $smarty->assign('noReply', true);
        }

        $smarty->assign('templateFilename', $messageTemplate . '.tpl');
        $smarty->assign('hideLogo', $this->hideLogo);
        $smarty->assign('showLoginButton', $this->showLoginButton);

        $layoutFile = $this->getTemplate($layout);

        if (in_array($mode, [Notification::RENDER_HTML, Notification::RENDER_HTML_BODY])) {
            $content = $smarty->fetch($layoutFile);
        } else {
            $modifier = new StripTagsModifier();
            $content = $modifier($smarty->fetch($layoutFile));
        }

        foreach ($this->contentModifiers as $modifier) {
            $content = $modifier($content, ['layout' => $layout]);
        }

        return $content;
    }


    /**
     * @param string $layout
     * @return string
     */
    public function getTemplate(string $layout = 'default'): string
    {
        if ($layout !== 'default') {
            $path = MODULE_PATH . 'Application/view/layout/notification-' . $layout . '.tpl';
            if (file_exists($path)) {
                return $path;
            }
        }

        return MODULE_PATH . 'Application/view/layout/notification.tpl';
    }
}
