<?php

namespace Hura8\System;

use Hura8\Components\Template\Controller\TemplateController;
use Hura8\Interfaces\iEmail;
use Hura8\System\Controller\SettingController;
use Provider\Adman;
use Swift_Mailer;
use Swift_Message;
use Swift_SmtpTransport;


class Email implements iEmail {

    protected $config = [
        "mail_method" => "",
        "from_name"   => "",
        "from_email"  => "",
        "reply_to"    => "",
        "subject"    => "",
        "content"    => "",
    ];

    /* @var SettingController $objSettingController */
    protected $objSettingController;

    //construct
    public function __construct() {
        // default
        if(defined("MAIL_METHOD"))  $this->config["mail_method"] = MAIL_METHOD;
        if(defined("MAIL_NAME"))    $this->config["from_name"]   = MAIL_NAME;
        if(defined("MAIL_ADDRESS")) $this->config["from_email"] = MAIL_ADDRESS;

        if(!$this->config["from_name"]) $this->config["from_name"] = str_replace('www.', '', $_SERVER['HTTP_HOST']);

        $this->objSettingController = new SettingController();

        $email_settings  = $this->objSettingController->getList([
            'email_from_default',
        ]);

        $email_from = (isset($email_settings['email_from_default']) && $email_settings['email_from_default']) ? $email_settings['email_from_default'] : '' ;
        if($email_from && self::validate_email($email_from) && $email_from != MAIL_ADDRESS) {
            $this->setUp([
                "from_email"  => $email_from,
            ]);
        }
    }

    public function setUp(array $config)
    {
        // over-ride default config
        if(sizeof($config)) {
            foreach ($config as $key => $value) {
                $this->config[$key] = $value;
            }
        }
    }

    public function send(array $to_emails, $subject, $content, array $key_values = [])
    {
        if(!$this->checkConfig()) return [
            'status'  => 'error',
            'message' => "Config errors: ".\json_encode($this->config),
        ];

        // send email using a template in email/
        $this->config['subject'] = TemplateController::parse(null, $subject, $key_values);
        $this->config['content'] = TemplateController::parse(null, $content, $key_values);

        try {
            switch ($this->config["mail_method"]){
                case "huraserver";
                    $result = $this->sendEmailFromHura($to_emails);
                    break;
                case "queue";
                    $result = $this->addQueue($to_emails);
                    break;
                case "adman";
                    $result = $this->sendFromAdman($to_emails);
                    break;
                case "smtp";
                    $result = $this->sendFromSmtp($to_emails);
                    break;
                default;
                    $result = null;
            }
        }catch (\Exception $exception) {
            $result = "Error: ".$exception->getMessage();
        }

        if($result) {
            $this->log(array_merge($this->config, [
                'to_emails' => $to_emails,
                'result' => $result,
            ]));
        }

        return $result;
    }

    protected function checkConfig() {
        return (
            $this->config["mail_method"]
            && $this->config["from_name"]
            && $this->config["from_email"]
            && self::validate_email($this->config["from_email"])
        );
    }

    protected function addQueue(array $to_emails){
        // todo:
        /*foreach($to_email_list as $single_email){
            $this->createQueue(array(
                "message_id"    => 0,
                "from_email"    => $from_mail,
                "from_name"     => $from_name,
                "reply_to"      => $reply_to_email,
                "to_email"      => $single_email,
                "to_name"       => $to_name,
                "subject"       => $title,
                "content"       => $content,
                "source"        => "",
            ));
        }*/
        return true;
    }

    protected function sendFromAdman(array $to_emails){
        if(!defined("ADMAN_API_KEY") ||  ADMAN_API_KEY == '') return 'ADMAN_API_KEY not set';
        if(!defined("ADMAN_USER_DOMAIN") ||  ADMAN_USER_DOMAIN == '') return 'ADMAN_USER_DOMAIN not set';

        $recipients = array_map(function ($email){
            return [
                'to_email'          => $email,
                'to_name'           => '',
                'personal_settings' => array(),
            ];
        }, $to_emails);

        $payload =  array(
            'message' =>  array(
                'from_email'    => $this->config['from_email'],
                'from_name'     => $this->config['from_name'],
                'reply_to_email' => $this->config['reply_to'],
                'subject'       => $this->config['subject'],
                'settings'      => array(),
                'schedule_go_time_utc' => 0,
                'content_html' => $this->config['content'],
                'content_plain' => '',
            ),
            'recipients' => $recipients
        );

        return Adman::send(ADMAN_USER_DOMAIN, ADMAN_API_KEY, $payload);
    }


    protected function sendFromSmtp(array $to_emails){

        if(!SMTP_HOST || !SMTP_USERNAME || !SMTP_PASSWORD) {
            return 'Smtp credentials not set';
        }

        // https://swiftmailer.symfony.com/docs/introduction.html
        // Create the Transport
        $transport = (new Swift_SmtpTransport(SMTP_HOST, SMTP_PORT, SMTP_SECURE))
            ->setUsername(SMTP_USERNAME)
            ->setPassword(SMTP_PASSWORD)
        ;
        $transport->setTimeout(10);

        // Create the Mailer using your created Transport
        $mailer = new Swift_Mailer($transport);

        // Create a message
        $message = (new Swift_Message())
            ->setSubject($this->config['subject'])
            ->setFrom($this->config['from_email'], $this->config['from_name'])
            ->setTo($to_emails)
            ->setBody($this->config['content'], 'text/html')
        ;

        // Send the message
        return $mailer->send($message);
    }


    protected function sendEmailFromHura(array $to_emails){
        $rebuild_to_emails = [];
        $max_email_allow = 3;
        $counter = 0;
        foreach ($to_emails as $email) {
            if(self::validate_email($email)) {
                $counter += 1;
                if($counter >= $max_email_allow) break;
                $rebuild_to_emails[] = ['email' => $email, 'name' => ''];
            }
        }

        if(!sizeof($rebuild_to_emails)) {
            return [
                'status' => 'error',
                'message' => 'Error. No valid emails to be sent',
            ];
        }

        $data = [
            'title'         => $this->config['subject'],
            'content'       => $this->config['content'],
            'to_emails'     => $rebuild_to_emails,
            'from_email'    => $this->config['from_email'],
            'from_name'     => $this->config['from_name'],
            'reply_to_email' => $this->config['reply_to'],
            'reply_to_name' => '',
            'client_id'     => CLIENT_ID,
            'domain'        => CURRENT_DOMAIN,
        ];

        // protect
        $msg_hash = sha1(serialize($data).'asdas32');
        $data['msg_hash'] = $msg_hash;

        $headers = [];

        return curl_post(HURAMAIL_RECEIVE_ENDPOINT, $data, $headers);
    }

    protected function createQueue(array $config) {
        // todo:
    }

    //email log after sending an email and remove from queue
    protected function log(array $log_content){
        /*$db = ConnectDB::getInstance('');
        $db->insert(
            'email_log',
            [
                'payload' => \json_encode($log_content),
                'create_time' => CURRENT_TIME,
            ]
        );*/
    }

    //validate email
    public static function validate_email($email){
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    }

}
