<?php
namespace SabaiApps\Directories\Component\Contact;

use SabaiApps\Directories\Component\AbstractComponent;
use SabaiApps\Directories\Component\Display;
use SabaiApps\Directories\Component\Entity;

class ContactComponent extends AbstractComponent implements Display\IElements
{
    const VERSION = '1.2.81', PACKAGE = 'directories-pro';
    
    public static function interfaces()
    {
        return array('Payment\IFeatures');
    }
    
    public static function description()
    {
        return 'Allows visitors to send messages to content authors/owners through a contact form.';
    }
    
    public function displayGetElementNames(Entity\Model\Bundle $bundle)
    {
        if (!empty($bundle->info['is_taxonomy'])
            || !empty($bundle->info['parent'])
        ) return [];
        
        return array('contact_form');
    }
    
    public function displayGetElement($name)
    {
        return new DisplayElement\FormDisplayElement($this->_application, $name);
    }
    
    public function paymentGetFeatureNames()
    {
        return array('contact_form');
    }
    
    public function paymentGetFeature($name)
    {
        return new PaymentFeature\FormPaymentFeature($this->_application, $name);
    }
        
    public function onCorePlatformWordPressInit()
    {
        // Contact Form 7
        if (defined('WPCF7_VERSION')) {
            add_filter('wpcf7_form_hidden_fields', array($this, 'wpcf7FormHiddenFieldsFilter'));
            add_filter('wpcf7_mail_components', array($this, 'wpcf7MailComponentsFilter'));
            // Need to manually populate values for post special mail tags as they work when the form is inside the post content only.
            add_filter('wpcf7_special_mail_tags', [$this, 'wpcf7SpecialMailTagsFilter'], 10, 3);
        }
        
        // WPForms
        if (defined('WPFORMS_VERSION')) {
            add_action('wpforms_frontend_output', array($this, 'wpformsFrontendOutputAction'));
            add_filter('wpforms_entry_email_atts', array($this, 'wpformsEntryEmailAttsFilter'));
        }
        
        // Gravity Forms
        if (class_exists('\GFForms', false)) {
            add_filter('gform_pre_render', array($this, 'gformPreRenderFilter'));
            add_filter('gform_replace_merge_tags', array($this, 'gformReplaceMergeTagsFilter'));
        }
    }
    
    public function gformPreRenderFilter($form)
    {
        if ($entity = $this->_isDisplaying()) {
            array_push($form['fields'], \GF_Fields::create(array(
                'type' => 'html',
                'content' => '<input type="hidden" name="_drts_contact_entity_id" value="' . intval($entity->getId()) . '" />',
            )));   
        }
        return $form;
    }
    
    public function gformReplaceMergeTagsFilter($text)
    {
        $tag = '{drts_contact_recipients}';
        if (strpos($text, $tag) !== false) {        
            $text = str_replace($tag, ($recipients = $this->_isSending()) ? implode(',', $recipients) : '', $text);
        }
        return $text;
    }
    
    public function wpformsFrontendOutputAction()
    {
        if ($entity = $this->_isDisplaying()) {
            echo '<input type="hidden" name="_drts_contact_entity_id" value="' . intval($entity->getId()) . '" />';
        }
    }
    
    public function wpformsEntryEmailAttsFilter($email)
    {
        if ($recipients = $this->_isSending()) {
            $email['address'] = $recipients;
        }
        return $email;
    }
        
    public function wpcf7FormHiddenFieldsFilter($fields)
    {
        if ($entity = $this->_isDisplaying()) {
            $fields['_drts_contact_entity_id'] = $entity->getId();
        }
        return $fields;
    }
    
    public function wpcf7MailComponentsFilter($components)
    {
        if ($recipients = $this->_isSending()) {
            $components['recipient'] = implode(',', $recipients);
        }
        return $components;
    }

    public function wpcf7SpecialMailTagsFilter($output, $name, $html)
    {
        if (strpos($name, '_post_') === 0
            && ($entity = $this->_isSending(true))
            && ($post = $entity->post())
        ) {
            switch ($name) {
                case '_post_id':
                    return (string)$post->ID;
                case '_post_name':
                    return $post->post_name;
                case '_post_title':
                    return $html ? esc_html($post->post_title) : $post->post_title;
                case '_post_url':
                    return get_permalink($post->ID);
                case '_post_author':
                case '_post_author_email':
                    $user = new \WP_User($post->post_author);
                    return $name === '_post_author' ? $user->display_name : $user->user_email;
            }
        }
    }
    
    protected function _isDisplaying()
    {
        return (isset($GLOBALS['drts_entity'])
            && !$GLOBALS['drts_entity']->isTaxonomyTerm()
            && Display\Helper\RenderHelper::isRendering($GLOBALS['drts_entity']->getBundleName(), 'detailed')
            && $this->_application->Contact_Form_isEnabled($GLOBALS['drts_entity'])
        ) ? $GLOBALS['drts_entity'] : false;
    }
    
    protected function _isSending($returnEntity = false)
    {
        if (empty($_POST['_drts_contact_entity_id'])
            || (!$entity = $this->_application->Entity_Entity('post', $_POST['_drts_contact_entity_id']))
            || $entity->isTaxonomyTerm()
        ) return false;

        if ($returnEntity) return $entity;

        return ($recipients = $this->_application->Contact_Form_recipients($entity)) ? $recipients : false;
    }
    
    public function onEntityBundleSettingsFormFilter(&$form, $bundle, $submitValues)
    {
        if (!empty($bundle->info['is_taxonomy'])
            || !empty($bundle->info['parent'])
            || !empty($bundle->info['is_user'])
            || !empty($bundle->info['internal'])
        ) return;
        
        if ($this->_application->isComponentLoaded('Payment')
            && !empty($bundle->info['payment_enable'])
        ) return; // the setting is integrated with payment feature settings

        $value = empty($bundle->info['contact_form']) ? [] : $bundle->info['contact_form'];
        $recipient_options = $this->_application->getComponent('Contact')->getRecipientOptions($bundle);
        $form['contact_form'] = [
            '#title' => __('Contact Form', 'directories-pro'),
            '#tree' => true,
            '#weight' => 99,
            '#tab' => 'general',
            'recipients' => [
                '#title' => __('Contact form recipients', 'directories-pro'),
                '#type' => 'checkboxes',
                '#options' => $recipient_options[0],
                '#options_disabled' => $recipient_options[1],
                '#default_value' => isset($value['recipients']) ? $value['recipients'] : ['author'],
                '#horizontal' => true,
                '#columns' => 1,
            ],
        ];
    }
    
    public function onEntityBundleInfoUserKeysFilter(&$keys)
    {
        $keys[] = 'contact_form';
    }
    
    public function getRecipientOptions(Entity\Model\Bundle $bundle)
    {
        $options = [
            'author' => __('Post Author', 'directories-pro'),
            'site' => __('Site E-mail', 'directories-pro') . ' - ' . $this->_application->SiteInfo('email'),
        ];
        $email_field_options = $this->_application->Entity_Field_options($bundle, [
            'interface' => 'Field\Type\IEmail',
            'prefix' => __('Field - ', 'directories-pro'),
            'return_disabled' => true,
        ]);
        $options += $email_field_options[0];
        
        return [$options, array_keys($email_field_options[1])];
    }
}
