<?php
namespace App\Core\Library;
require_once dirname(__DIR__, 3).'/vendor/autoload.php';
use PHPMailer\PHPMailer\PHPMailer;
use App\Core\Service\Logger;
use App\Config\Main;
class Mailer
{
    private static $mailer;
    private static $host;
    private static $username;
    private static $password;
    private static $port = 587;
    private static $enable_ssl = false;
    private static $verify_ssl = false;
    private static $base_path = "";
    public $email_from = '';
    public $email_to = [];
    public $email_cc = [];
    public $email_bcc = [];
    public $email_reply_to = [];
    public $attachments = [];
    public $phone_no = [];

    public function configure($host, $username, $password, $port = 587, $enable_ssl = false, $verify_ssl=false)
    {
        self::$host = $host;
        self::$username = $username;
        self::$password = $password;
        self::$port = $port;
        self::$enable_ssl = !empty($enable_ssl)?true:false;
        self::$verify_ssl = !empty($verify_ssl)?true:false;
        self::$base_path = Main::getBasePath();
        $this->initMailer();
    }

    private function initMailer()
    {
        self::$mailer = new PHPMailer(true);
        self::$mailer->isSMTP();
        self::$mailer->Host       = self::$host;
        self::$mailer->SMTPAuth   = true;
        self::$mailer->Username   = self::$username;
        self::$mailer->Password   = self::$password;
        self::$mailer->Port       = self::$port;
        self::$mailer->CharSet = 'UTF-8';
        self::$mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        if (self::$enable_ssl) {
            self::$mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
        } else {
            self::$mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        }
        self::$mailer->SMTPOptions = array('ssl' => array(
            'verify_peer' => !empty(self::$verify_ssl) ? true : false, 
            'verify_peer_name' => !empty(self::$verify_ssl) ? true : false, 
            'allow_self_signed' => true
        ));
        self::$mailer->setFrom(self::$mailer->Username, 'SAN ORDO');
    }

    private function setEmailRecipients(Array|String $data, String $type='to') {
        if(is_array($data)) {
            foreach ($data as $to) {
                if(is_array($to)) {
                    if(!empty($to['email_id']) && !empty($to['name'])) {
                        if($type == 'to') {
                            self::$mailer->addAddress($to['email_id'], $to['name']);
                            $this->email_to[] = $to['email_id']; 
                        } else if($type == 'cc') {
                            self::$mailer->addCC($to['email_id'], $to['name']);
                            $this->email_cc[] = $to['email_id']; 
                        } else if($type == 'bcc') {
                            self::$mailer->addBCC($to['email_id'], $to['name']);
                            $this->email_bcc[] = $to['email_id'];
                        } else if($type == 'reply_to') {
                            self::$mailer->addReplyTo($to['email_id'], $to['name']);
                            $this->email_reply_to[] = $to['email_id'];
                        }
                    }
                } else {
                    if($type == 'to') {
                        self::$mailer->addAddress($to);
                        $this->email_to[] = $to; 
                    } else if($type == 'cc') {
                        self::$mailer->addCC($to);
                        $this->email_cc[] = $to; 
                    } else if($type == 'bcc') {
                        self::$mailer->addBCC($to);
                        $this->email_bcc[] = $to; 
                    } else if($type == 'reply_to') {
                        self::$mailer->addReplyTo($to);
                        $this->email_reply_to[] = $to; 
                    }
                }
            }
        } else {
            if($type == 'to') {
                self::$mailer->addAddress($data);
                $this->email_to[] = $data;
            } else if($type == 'cc') {
                self::$mailer->addCC($data);
                $this->email_cc[] = $data;
            } else if($type == 'bcc') {
                self::$mailer->addBCC($data);
                $this->email_bcc[] = $data;
            } else if($type == 'reply_to') {
                self::$mailer->addReplyTo($data);
                $this->email_reply_to[] = $data; 
            }
        }
    }
    
    private function setEmailAttachments($data) {
        if(is_array($data)) {
            foreach ($data as $rkey => $file) {
                if(is_array($file)) {
                    if (!empty($file['path']) && !empty($file['name'])) {
                        self::$mailer->addAttachment(self::$base_path.'/'.$file['path'], $file['name']);
                        $this->attachments[] = $file['path'];
                    } else if (!empty($file['path'])) {
                        self::$mailer->addAttachment(self::$base_path.'/'.$file['path']);
                        $this->attachments[] = $file['path'];
                    }
                } else {
                    self::$mailer->addAttachment(self::$base_path.'/'.$file);
                    $this->attachments[] = $file;
                }
            }
        } else {
            Logger::error("Email attachment data must be an array", ['File' => __FILE__, 'Line'=>__LINE__]);
        }
    }

    public function sendEmail(Array $data)
    {
        try {
            $this->email_to = [];
            $this->email_cc = [];
            $this->email_bcc = [];
            $this->email_reply_to = [];
            $this->attachments = [];
            $this->phone_no = [];
            $email_sent = false;
            $email_resp = '';
            if(empty(self::$mailer)) {
                throw new \Exception("Mailer configuration not found");
            }
            self::$mailer->clearAllRecipients();
            self::$mailer->clearAttachments();
            if (empty($data['to'])) {
                throw new \Exception("Recipient's address is not found to sent email");
            }
            if (!is_array($data['to'])) {
                throw new \Exception("Recipient's address is not is proper array format");
            }
            if (empty($data['body'])) {
                throw new \Exception("Email body is not found to sent email");
            }
            if (empty($data['subject'])) {
                throw new \Exception("Email subject is not found to sent email");
            }
            $this->email_from = !empty($data['from']) ? $data['from'] : self::$username;
            self::setEmailRecipients($data['to'], 'to');
            if(!empty($data['cc'])) {
                self::setEmailRecipients($data['cc'], 'cc');
            }
            if(!empty($data['bcc'])) {
                self::setEmailRecipients($data['bcc'], 'bcc');
            }
            if(!empty($data['reply_to'])) {
                self::setEmailRecipients($data['reply_to'], 'reply_to');
            }
            if(!empty($data['attachments'])) {
                self::setEmailAttachments($data['attachments']);
            }
            self::$mailer->isHTML(true);
            self::$mailer->Subject = $data['subject'];
            self::$mailer->Body    = $data['body'];
            
            if (self::$mailer->send()) {
                $email_sent = true;
            } else {
                $email_sent = false;
                $email_resp = "Email could not be sent. Error: ".self::$mailer->ErrorInfo;
                
            }
            if($email_sent) 
                return ["status" => true, "data"=>"Email sent successfully"];
            else 
                return ["status" => false, "error"=>$email_resp];
        } catch (\Exception $e) {
            Logger::error($e->getMessage(), ['File' => $e->getFile(), 'Line'=>$e->getLine()]);
            return ["status" => false, "error"=>$e->getMessage()];
        }
    }
}
