<?php 
use SilverStripe\Control\Director;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
//test eeee bbb ccc
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 = 31; // seconds
                // $randomSleepTime = rand(25, $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") {
            //untuk jenis ChatAPI

            $attachment = $this->notif->Attachment();
            $arrPhone = [];
            $arrMsg = [];

            // Waktu awal untuk mengukur durasi eksekusi
            $start = microtime(true);
            // Iterasi untuk setiap nomor penerima yang telah diformat
            foreach ($formattedRecipients as $value) {
                // Jika terdapat file attachment
                if ($attachment->exists()) {
                    foreach ($attachment as $file) {
                         // Persiapkan path file attachment
                        $temp = Director::getAbsFile($file->AbsoluteLink());
                        $pos_http = strpos($temp, 'http');
                        $temp = substr($temp, 0, $pos_http);
                        $attachment = $temp . 'public/assets/' . $file->FileFilename;
                        // Persiapkan data untuk dikirim
                        $this->body = [
                            'messaging_product'  => "whatsapp",
                            'to' => $value,                            
                            'attachment' => curl_file_create($attachment),
                            "template" => [
                                "name" => "hello_world",
                                "language" => [
                                    "code" => "en_US"
                                ]
                            ]    
                        ];

                        // Kirim pesan menggunakan fungsi postVenomWA (mungkin perlu revisi nama fungsi)
                        $arrBaru = $this->postWAapi();
                        // var_dump($arrBaru);die();
                        
                        // Tambahkan nomor dan pesan ke array jika ada hasil dari pengiriman
                        if(!empty($arrBaru)){
                            $arrPhone[] = $arrBaru['number'];
                            $arrMsg[] = $arrBaru['msg'];
                        }
                    }
                } else
                {
                    
                    /*
                     *   Start Rinda
                    */

                    // Persiapkan data untuk pengiriman tanpa attachment

                    $template = $this->notif->Subject;
                    if ($template == 'otp_muatmuat' || $template == 'muatmuat' ){
                        $this->body = [
                            "messaging_product" => "whatsapp",
                            "recipient_type" => "individual",
                            "to" => $value,
                            "type" => "template",
                            "template" => [
                                "name" => "otp_muatmuat",
                                "language" => [
                                    "code" => "id"
                                ],
                                "components" => [
                                    [
                                        "type" => "body",
                                        "parameters" => [
                                            [
                                                "type" => "text",
                                                "text" => $this->notif->Message,
                                            ],
                                        ],
                                    ],
                                    [
                                        "type" => "button",
                                        "sub_type" => "url",
                                        "index" => 0,
                                        "parameters" => [
                                            [
                                                "type" => "text",
                                                "text" => $this->notif->Message,
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ];
                    } else if ($template == 'muatmuatnotifikasi1'){
                        $this->body = [
                            "messaging_product" => "whatsapp",
                            "recipient_type" => "individual",
                            "to" => $value,
                            "type" => "template",
                            "template" => [
                                "name" => "muatmuatnotifikasi1",
                                "language" => [
                                    "code" => "id"
                                ],
                                "components" => [
                                    [
                                        "type" => "body",
                                        "parameters" => [
                                            [
                                                "type" => "text",
                                                "text" => $this->notif->Message,
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ];
                    }

                    /*
                     *   End Rinda
                    */
                

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

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

                    // Tambahkan nomor dan pesan ke array jika ada hasil dari pengiriman
                    if(!empty($arrBaru)){
                        $arrPhone[] = $arrBaru['number'];
                        $arrMsg[] = $arrBaru['msg'];
                    }
                }      
            }
            
            
            $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[] = [
                "success" => true,
                '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));
            }

            //mulai ditutup nandi
            /*$start = microtime(true);
            foreach ($formattedRecipients as $value) {
                $this->body = [
                    'phone' => $value,
                    'body' => $this->generateWABody(),
                ];

                $this->postChatAPI();
            }*/
            //akhir ditutup nandi

            //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 postWAapi() {
        $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;
            $this->body = json_encode($this->body);
        }
        $httpHeader[] = $authorization;
        $httpHeader[] = 'Content-Type:application/json';

        // Generate a random number between 1 and 10 seconds.
        $maxSleepTime = 2; // seconds
        $randomSleepTime = rand(5, $maxSleepTime);
        
                        // Sleep for the specified number of seconds.
        //-- by nandi sementara dioffkan karena sdh pakai wa business. kalau pakai venom bisa dikasih sleep

        //-- by nandi sleep($randomSleepTime);
        
        $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)) {
                if(is_object($output->error)){
                    $output->error = json_encode($output->error);
                }
                $arr['msg'] = "META errpr: ".$this->body." ".$output->error;
                $this->body = json_decode($this->body);
                $arr['number'] = $this->body->to;
                // throw new Exception("VenomWA error: ".$output->error);
            }
        }
        curl_close($ch);
        return $arr;
    }

    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;

        // Generate a random number between 1 and 10 seconds.
        $maxSleepTime = 2; // seconds
        $randomSleepTime = rand(5, $maxSleepTime);
        
                        // Sleep for the specified number of seconds.
        //-- by nandi ditutup semnetara karena sudah pakai api wa business
        //-- by nandi sleep($randomSleepTime);
        
        $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)) {
                if(is_object($output->error)){
                    $output->error = json_encode($output->error);
                }
                $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;
    }
}
