<?php 
use SilverStripe\Control\Director;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;

class MessageHelper {
    public $notif;
    public $body;
    public $token;

    public function sendEmail() {
        try {
            $instance = $this->notif->Instance();
            //Server settings
            $mail->SMTPDebug = 0; // Enable verbose debug output
            $mail->isSMTP(); // Send using SMTP
            $mail->Host = $instance->SMTPHost; // Set the SMTP server to send through
            $mail->SMTPAuth = true; // Enable SMTP authentication
            $mail->Username = $instance->SMPTUsername; // SMTP username
            $mail->Password = $instance->SMPTPassword; // SMTP password
            $mail->SMTPSecure = "PHPMailer::ENCRYPTION_STARTTLS"; // Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` also accepted
            $mail->Port = $instance->SMPTPort;

            $mail->setFrom($instance->SMPTFromEmail, $instance->SMPTFromName);

            $to = explode(",", $notif->Recipients);
            foreach ($to as $addr) {
                if (self::checkValidEmail($addr)){
                    $mail->addAddress($addr); // Add a recipient
                }
            }

            // add email cc
            $cc = explode(",", $notif->CC);
            foreach ($cc as $addr) {
                if (self::checkValidEmail($addr)){
                    $mail->addCC($addr);
                }
            }


            // add email bcc
            $bcc = explode(",", $notif->BCC);
            foreach ($bcc as $addr) {
                if (self::checkValidEmail($addr)){
                    $mail->addBCC($addr);
                }
            }


            // add email attachment
            // if (!empty($attachment)) {
            //  if (is_array($attachment)) {
            //      foreach ($attachment as $attach) {
            //          $mail->addAttachment($attach);
            //      }
            //  } else
            //  $mail->addAttachment($attachment);
            // }

            // Content
            $mail->Subject = $this->notif->Subject;
            $mail->Body = $this->notif->Message;
            $mail->isHTML(true); // Set email format to HTML
            $mail->send();
        } catch (Exception $e) {
            throw new Exception("PHPMailer error: ".$e->getMessage());
        }
    }

    public function sendWA() {
        $rawRecipients = [];
        $formattedRecipients = [];

        if (strpos($this->notif->Recipients, ",")) {
            $rawRecipients = explode(",", $this->notif->Recipients);
        } else {
            $rawRecipients[] = $this->notif->Recipients;
        }

        foreach ($rawRecipients as $value) {
            $cek = $this->checkPhoneNumber($value);
            if ($cek == false) {
                continue;
            } else {
                $formattedRecipients[] = $cek;
            }
        }

        if ($this->notif->Instance()->InstanceWaType == "VenomWA") {
            $attachment = $this->notif->Attachment();
            $arrPhone = [];
            $arrMsg = [];

            $start = microtime(true);
            foreach ($formattedRecipients as $value) {
                if ($attachment->exists()) {
                    foreach ($attachment as $file) {
                        $temp = Director::getAbsFile($file->AbsoluteLink());
                        $pos_http = strpos($temp, 'http');
                        $temp = substr($temp, 0, $pos_http);
                        $attachment = $temp . 'public/assets/' . $file->FileFilename;
                        $this->body = [
                            'phone' => $value,
                            'attachment' => curl_file_create($attachment),
                            'text' => ""
                        ];

                        $arrBaru = $this->postVenomWA();
                        if(!empty($arrBaru)){
                            $arrPhone[] = $arrBaru['number'];
                            $arrMsg[] = $arrBaru['msg'];
                        }
                    }
                }

                $this->body = [
                    'phone' => $value,
                    'text' => $this->generateWABody(),
                   //'text' => "muatmuat notification",
                ];

		// Generate a random number between 1 and 10 seconds.
		$maxSleepTime = 4; // seconds
		$randomSleepTime = rand(1, $maxSleepTime);

		// Sleep for the specified number of seconds.
		sleep($randomSleepTime);
                
		$arrBaru = $this->postVenomWA();

                // CT::writeSimpleLog("sendwa ".$value.":".substr($this->notif->Message,0,180));
                
                if(!empty($arrBaru)){
                    $arrPhone[] = $arrBaru['number'];
                    $arrMsg[] = $arrBaru['msg'];
                }
            }
            
            //comment by dyah 28/10/2022
            // $time_end = microtime(true);
            // $LogFungsi = new LogFungsi();
            // $LogFungsi->NoRef = implode(',', $sendedRecipients);
            // $LogFungsi->NamaFungsi = "Kirim WA Ke Venom";
            // $LogFungsi->Waktu = $time_end - $start;
            // $LogFungsi->write();
            
            $sendedRecipients = array_diff($formattedRecipients, $arrPhone);
            
            //Unset ID and ClassName
            $notifdata = $this->notif->toMap();
            $notifdata['Recipients'] = implode(',', $sendedRecipients);
            $sended = new SendedMessageData();
            unset($notifdata['ID']);
            unset($notifdata['ClassName']);
            unset($notifdata['Status']);
            
            $sended->update($notifdata);
            $send_id = $sended->write();

            $json_log[] = [
                'wa' => [
                    $notifdata['Recipients'] => 'success'
                ]
            ];

            $log = new SendLogData();
            $log->SendID = $send_id;
            $log->json_log = json_encode($json_log);
            $log->write();
            if(!empty($arrPhone)){
                $phoneError = array_intersect($formattedRecipients, $arrPhone);
                $outbox = OutboxMessageData::get()->ByID($this->notif->ID);
                $outbox->Recipients = implode(',', $phoneError);
                $outbox->write();
                throw new Exception(implode(',', $arrPhone)." ".implode(',', $arrMsg));
            }

        } else if ($this->notif->Instance()->InstanceWaType == "ChatAPI") {
            $start = microtime(true);
            foreach ($formattedRecipients as $value) {
                $this->body = [
                    'phone' => $value,
                    'body' => $this->generateWABody(),
                ];

                $this->postChatAPI();
            }

            //comment by dyah 28/10/2022
            // $time_end = microtime(true);
            // $LogFungsi = new LogFungsi();
            // $LogFungsi->NoRef = implode(',', $formattedRecipients);
            // $LogFungsi->NamaFungsi = "Kirim WA Ke ChatAPI";
            // $LogFungsi->Waktu = $time_end - $start;
            // $LogFungsi->write();
        }
    }

    public function postChatAPI()
    {
        $url = $this->notif->Instance()->InstanceLink;

        $httpHeader = array('Content-Type:application/json');
        $this->body = json_encode($this->body);
        $this->body = str_replace("\\r\\n", "\\n", $this->body);
        $this->body = str_replace("\\n\\n", "\\n \\n", $this->body);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_POST, false);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->body);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);


        $output = curl_exec($ch);
        //var_dump($output);

        if ($error = curl_error($ch)) {
            curl_close($ch);
            throw new Exception("CURL error: ".$error);
        }

        $output = json_decode($output);
        // if (array_key_exists('error', $output)) {
        //  throw new Exception("VenomWA error: ".$output->error);
        // }

        curl_close($ch);
    }

    public function postVenomWA() {
        $url = $this->notif->Instance()->InstanceLink."sendFile";
        $authorization = "Authorization: Bearer " . $this->notif->Instance()->AuthToken;
        if (!array_key_exists("attachment", $this->body)) {
            $httpHeader = array('Content-Type:application/json');
            $url = $this->notif->Instance()->InstanceLink."sendText";
            $this->body = json_encode($this->body);
        }
        $httpHeader[] = $authorization;

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $this->body);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $httpHeader);


        $output = curl_exec($ch);
        // print_r(curl_exec($ch));die();

        if ($error = curl_error($ch)) {
            curl_close($ch);
            throw new Exception("CURL error: ".$error);
        }

        $arr = [];

        if ($output != null) {
            $output = json_decode($output);
            if (array_key_exists('error', $output)) {
                $arr['msg'] = "VenomWA error: ".$output->error;
                $this->body = json_decode($this->body);
                $arr['number'] = $this->body->phone;
                // throw new Exception("VenomWA error: ".$output->error);
            }
        }
        curl_close($ch);
        return $arr;
    }

    public function checkPhoneNumber($phone) {
        $noTelpIndo = str_split($phone);

        if (count($noTelpIndo) < 10) {
            return false;
        }

        if ($noTelpIndo[1] == '8' && $noTelpIndo[0] == '0') {
            $noTelpIndo[0] = '62';
            $str = implode('', $noTelpIndo);
            return $str;
        }

        return $phone;
    }

    public function generateWABody() {
        $body = "";
        if ($this->notif->Subject == null || $this->notif->Subject == "") {

        } else {
            $body .= "*".$this->notif->Subject."*".PHP_EOL;
        }

        $body .= $this->notif->Message;

        return $body;
    }

    static function checkValidEmail($email) {
        if ($email == "") {
            return false;
        }
        if (filter_val($email, FILTER_VALIDATE_EMAIL)) {
            return true;
        }
        return false;
    }
}
