<?php

namespace RTMCustomMails\ObjectSupport;

use RTMCustomMails\Rest\Model\ObjectSearchModel;
use RTMMailComposer\Model\EmailDocumentInterface;
use WordpressModels\Traits\AbstractSingletonTrait;

abstract class EmailObjectSupport implements EmailObjectSupportInterface
{

    use AbstractSingletonTrait;

    public function __construct(
        protected string $objectType
    )
    {
        add_filter('wrce_preview_object_selector_types', [$this, 'addAllowedObjectType']);
        add_filter('wrce_preview_object_selector_config', [$this, 'addSelectorSupport']);

        add_filter("wrce_preview_find_objects_$this->objectType", [$this, 'findObjects'], 10, 2);

        add_filter("wrce_email_allowed_variables/object_type=$this->objectType", [$this, 'getAllowedContextVariables']);
        add_filter("wrce_email_trigger_hook_options/object_type=$this->objectType", [$this, 'addTriggerHookOptions']);
        add_filter("wrce_email_condition_functions/object_type=$this->objectType", [$this, 'addConditionFunctions']);

        add_filter("wrce_allowed_attachments/object_type=$this->objectType", [$this, 'addDocumentSupport']);
    }

    /**
     * @return string
     */
    public function getObjectType(): string
    {
        return $this->objectType;
    }

    public function addAllowedObjectType(array $types): array
    {
        $types[] = $this->objectType;
        return $types;
    }

    /**
     * Add the object type to the selector config.
     *
     * @param array $config
     * @return array|array[]
     */
    public function addSelectorSupport(array $config): array
    {
        return $config + [$this->objectType => $this->getSelectorConfig()];
    }

    /**
     * The configuration for a search field.
     * @return array
     */
    protected abstract function getSelectorConfig(): array;

    /**
     * Get the allowed object variable names for this object type.
     *
     * @param $vars
     * @return array
     */
    public abstract function getAllowedContextVariables($vars = []): array;

    /**
     * Find objects of this object type.
     *
     * @param ObjectSearchModel[] $objects
     * @param string $search
     * @return array
     */
    public abstract function findObjects(array $objects, string $search): array;

    /**
     * Used for presetting the options in the object selector.
     *
     * @param int $amount
     * @return array
     */
    public abstract function getLatestObjects(int $amount = 20): array;

    /**
     * Add trigger hooks for this object type.
     *
     * @param array $options
     * @return array
     */
    public abstract function addTriggerHookOptions(array $options = []): array;

    /**
     * Add ExpressionLanguage condition functions for emails and sections for this object type.
     *
     * @param array $functionClasses
     * @return array
     */
    public abstract function addConditionFunctions(array $functionClasses = []): array;

    /**
     * Add document support for this object type.
     *
     * @param EmailDocumentInterface[] $documents
     * @return array
     */
    public function addDocumentSupport(array $documents = []): array
    {
        return $documents;
    }

}