<?php

namespace PWH_DCFH\App\Frontend\Request;

use PWH_DCFH\App\Frontend\Controllers\PWH_DCFH_Email_Handler;

if (!defined('ABSPATH')) exit;
if (!class_exists('PWH_DCFH_Confirmation_Email_Request')) {
    class PWH_DCFH_Confirmation_Email_Request
    {
        private static $instance = null;

        protected $post_request;

        protected $post_repository;

        protected $email_handler;

        public $confirmation_email_field_id;

        public $confirmation_email_subject;

        public $confirmation_email_from_name;

        public $confirmation_email_from;

        public $confirmation_email_message;

        public $attachments = [];

        /**
         * Class Constructor
         */
        private function __construct()
        {
            $this->post_request = new PWH_DCFH_Post_Request(false);
            $this->post_repository = PWH_DCFH_Post_Repository::instance();
            $this->email_handler = PWH_DCFH_Email_Handler::instance();
            if (pwh_dcfh_wp_helpers()::is_divi_4131_or_above()) {
                add_action('et_pb_contact_form_submit', [$this, 'maybe_divi_confirmation_email'], 10, 3);
            } else {
                add_action('phpmailer_init', [$this, 'register_phpmailer_action']);
                add_action('pwh_dcfh_confirmation_email', [$this, 'maybe_phpmailer_confirmation_email'], 10, 8);
            }
        }

        /**
         * Get Class Instance
         * @return PWH_DCFH_Confirmation_Email_Request|null
         */
        public static function instance()
        {
            if (self::$instance == null) {
                self::$instance = new PWH_DCFH_Confirmation_Email_Request();
            }

            return self::$instance;
        }

        /**
         * Retrieves The Request
         * @return PWH_DCFH_Post_Request
         */
        public function get_post_request()
        {
            return $this->post_request;
        }

        /**
         * Retrieves The Request
         * @return PWH_DCFH_Post_Repository
         */
        public function get_post_repository()
        {
            return $this->post_repository;
        }

        /**
         * Send Email To Customer Divi After Form Submit Hook
         *
         * @param $processed_fields_values
         * @param $et_contact_error
         * @param $contact_form_info
         *
         * @return void
         */
        public function maybe_divi_confirmation_email($processed_fields_values, $et_contact_error, $contact_form_info)
        {
            // Check Error Not Empty Return
            if (!empty($et_contact_error)) {
                return;
            }
            if (!$this->post_request->is_confirmation_email_enabled()) {
                return;
            }
            // Check Confirmation Email Enabled Return
            $this->send_email();
        }

        /**
         * Register PHPMAILER Action
         *
         * @param $phpmailer
         */
        public function register_phpmailer_action($phpmailer)
        {
            $phpmailer->action_function = 'pwh_dcfh_confirmation_email';
        }

        /**
         * Send Email To Customer with custom phpmailer hook
         *
         * @param $is_email_sent
         * @param $to
         * @param $cc
         * @param $bcc
         * @param $subject
         * @param $body
         * @param $from
         * @param $extra
         *
         * @return void|null
         */
        public function maybe_phpmailer_confirmation_email($is_email_sent, $to, $cc, $bcc, $subject, $body, $from, $extra)
        {
            if ($is_email_sent && did_action('phpmailer_init') == 1) {
                $this->send_email();
            }
        }

        /**
         * Send Email
         * @return void|null
         */
        private function send_email()
        {
            $to = $this->get_email();
            $subject = $this->get_email_subject();
            $message = $this->get_email_message();
            if (empty($to) || empty($subject) || empty($message)) {
                return;
            }
            $message = preg_replace("/\[attachments.+attachments]/", '', $message);
            $headers = $this->get_email_headers();
            $attachments = $this->get_email_attachments();
            wp_mail($to, $subject, $message, $headers, $attachments);
        }

        /**
         * Get Email
         * @return mixed
         */
        private function get_email()
        {
            return $this->get_post_request()->get_contact_email();
        }

        /**
         * Email Subject
         * @return string|null
         */
        public function get_email_subject()
        {
            $subject = $this->confirmation_email_subject;
            if (!empty($subject)) {
                return pwh_dcfh_email_merge_tags_handler()::get_merge_tags_values($subject, $this->get_post_request());
            }

            return null;
        }

        /**
         * Email Message
         * @return string $message
         */
        private function get_email_message()
        {
            $post_request = $this->get_post_request();
            $is_richtext = $this->post_repository->is_confirmation_message_richtext;
            $message = do_shortcode($this->confirmation_email_message);
            $message = html_entity_decode($message, ENT_QUOTES, 'utf-8');
            if (!$is_richtext) {
                $message = str_replace("</p>", "", $message);
                $message = str_replace("<p>", "\n", $message);
                $message = preg_replace("/<br \/>/mi", "", $message);
            }
            $message = pwh_dcfh_email_merge_tags_handler()::get_merge_tags_values($message, $post_request);
            if (preg_match('/%%dcfh_all_fields%%/i', $message)) {
                $message = str_replace("%%dcfh_all_fields%%", pwh_dcfh_email_merge_tags_handler()::get_all_fields_data($post_request, $is_richtext), $message);
            }

            return $message;
        }

        /**
         * Email Headers
         * @return array
         */
        private function get_email_headers()
        {
            $admin_emails_routing = $this->email_handler->get_admin_emails_routing();
            $admin_email = $this->get_post_repository()->module_admin_email;
            $email_from = empty($admin_email) ? get_bloginfo('admin_email') : $admin_email;
            $email_from_name = htmlspecialchars_decode(get_bloginfo('name'));
            if (!empty(trim($this->confirmation_email_from))) {
                $email_from = $this->confirmation_email_from;
            }
            if (!empty(trim($this->confirmation_email_from_name))) {
                $email_from_name = $this->confirmation_email_from_name;
            }
            $this->email_handler::instance()->set_from_email($email_from);
            $this->email_handler::instance()->set_from_name($email_from_name);
            if (!empty($admin_emails_routing)) {
                $email_from = end($admin_emails_routing);
            }
            $headers[] = sprintf('Reply-To: %1$s <%2$s>', $email_from_name, $email_from);
            if ($this->post_repository->is_confirmation_message_richtext) {
                $headers[] = 'Content-Type: text/html; charset=UTF-8';
            }

            return $headers;
        }

        /**
         * Email Attachments
         * @return array
         */
        private function get_email_attachments()
        {
            $attachments = [];
            $message = $this->get_email_message();
            preg_match_all("~\[attachments[^][]*]\s*(.+?)\[/attachments]~", $message, $matches);
            if (isset($matches[1][0]) && !empty($matches[1][0])) {
                $attachments_arr = explode(',', preg_replace('/\s*,\s*/', ',', $matches[1][0]));
                if (is_array($attachments_arr) && !empty($attachments_arr)) {
                    foreach ($attachments_arr as $attachment) {
                        $attachments[] = get_attached_file($attachment);
                    }
                }
                $attachments = array_filter($attachments, 'strlen');
            }

            return $attachments;
        }

    }
}