<?php
/** 
 * @package     VikRestaurants
 * @subpackage  core
 * @author      E4J s.r.l.
 * @copyright   Copyright (C) 2023 E4J s.r.l. All Rights Reserved.
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
 * @link        https://vikwp.com
 */

namespace E4J\VikRestaurants\Mail\Templates\Miscellaneous;

// No direct access
defined('ABSPATH') or die('No script kiddies please!');

use E4J\VikRestaurants\Mail\Mail;
use E4J\VikRestaurants\Mail\MailTemplateAware;

/**
 * Generic mail template to be fulfilled at runtime through an apposite callback.
 *
 * @since 1.10
 */
class RuntimeMailTemplate extends MailTemplateAware
{
    /**
     * An array of options.
     *
     * @var array
     */
    protected $options;

    /**
     * An array of arguments to be passed to the conditional texts dispatcher.
     * 
     * @var array
     */
    protected $eventArguments;

    /**
     * Class constructor.
     *
     * @param  array  $options  An array of options.
     */
    function __construct(array $options = [])
    {
        if (empty($options['subject']))
        {
            // the subject is mandatory
            throw new \InvalidArgumentException('Missing e-mail subject.', 400);
        }

        if (empty($options['lang']))
        {
            // always use default language in case it is not specified
            $options['lang'] = \VikRestaurants::getDefaultLanguage();
        }

        $this->options = $options;
    }

    /**
     * @inheritDoc
     */
    public function setFile($file)
    {
        // reset template buffer
        $this->options['template'] = '';

        // make sure the file exists
        if (\JFile::exists($file))
        {
            // start output buffering 
            ob_start();
            // include file to catch its contents
            include \JPath::clean($file);
            // internally save template contents
            $this->options['template'] = ob_get_contents();
            // clear output buffer
            ob_end_clean(); 
        }
    }

    /**
     * @inheritDoc
     */
    public function getTemplate()
    {
        return $this->options['template'] ?? '';
    }

    /**
     * @inheritDoc
     */
    public function shouldSend()
    {
        // always send the notification
        return true;
    }

    /**
     * @inheritDoc
     */
    protected function createMail(array &$args)
    {
        $args = array_merge($args, $this->eventArguments);

        // create mail instance
        return (new Mail)
            ->setSubject($this->options['subject'])
            ->setBody($this->getTemplate());
    }

    /**
     * Creates a template ID from the class name.
     * 
     * @return  string  An ID in the form "{group}.{alias}".
     */
    protected function getTemplateId()
    {
        if (!empty($this->options['id']))
        {
            // use the provided identifier
            return $this->options['id'];
        }

        if ((new \ReflectionClass($this))->isAnonymous())
        {
            // return a generic identifier for anonymous classes
            return 'runtime.generic';
        }

        // fallback to parent otherwise
        return parent::getTemplateId();
    }

    /**
     * Register a new argument to be passed to the conditional texts
     * as well as to the event dispatcher.
     * 
     * @param   mixed  $arg
     * 
     * @return  self
     */
    public function addEventArgument($arg)
    {
        $this->eventArguments[] = $arg;

        return $this;
    }
}
