<?php /** @noinspection SqlDialectInspection */

namespace App\Jobs;

use App\Exceptions\ErrorReporting;
use App\Tools\Sms;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Foundation\Bus\Dispatchable;


class SendSms implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $sms;
    private $log_path = '';

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Sms $sms)
    {
        $this->sms = $sms;
        $this->log_path = $sms->log;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        try {
            $sms = $this->sms;
            $numb = $sms->msisdn;
            $source = $sms->sender;
            $message = $sms->message;

            if ($source == 'STANBICGH' || $source == 'STANBIC') {
                $source = 'Stanbic';
            }
            if ($numb == '233123456789') {
                exit;
            }

            if (substr($numb, 0, 3) == '024' | substr($numb, 0, 3) == '054' | substr($numb, 0, 3) == '055' | substr($numb, 0, 3) == '026' | substr($numb, 0, 3) == '056' | substr($numb, 0, 3) == '020' | substr($numb, 0, 3) == '050' | substr($numb, 0, 3) == '027' | substr($numb, 0, 3) == '057' | substr($numb, 0, 3) == '023') {
                $remove = substr($numb, 1);
                $numb = '233' . $remove;
            }

            $sender = $source;
            $msgs = $message;
            $submitdt = date('Y-m-d H:i:s');
            $destination = explode(',', $numb);
            $no_chars = strlen($msgs);
            $no_pages = $this->no_pages($no_chars);
            $sms_count = $no_pages;
            $cost = 0.0;
            $resellerCost = 0.0;
            $msisdn = preg_replace('/\D/', '', $numb);

            if (is_numeric($msisdn)) {
                if (substr($msisdn, 0, 1) == '1') {
                    $code = substr($msisdn, 0, 1);
                    $ccLength = strlen($code);
                } elseif (substr($msisdn, 0, 1) == '9') {
                    $code = substr($msisdn, 0, 1);
                    $ccLength = strlen($code);
                } elseif (substr($msisdn, 0, 2) == '44') {
                    $code = substr($msisdn, 0, 2);
                    $ccLength = strlen($code);
                } elseif (substr($msisdn, 0, 2) == '27') {
                    $code = substr($msisdn, 0, 2);
                    $ccLength = strlen($code);
                } else {
                    $code = substr($msisdn, 0, 3);
                    $ccLength = strlen($code);
                }
                $standard_len = $ccLength + $this->checkCode($code);
                $new_len = strlen($msisdn);
                if ($standard_len === $new_len) {
                    $userNetwork = $this->get_user_sms_network($sms->user_id, $msisdn);
                    $cost += ($no_pages * $userNetwork['sms_price']);
                    if (!empty($resellerId)) {
                        $resellerNetwork = $this->get_user_sms_network($resellerId, $msisdn);
                        $resellerCost += ($no_pages * $resellerNetwork['sms_price']);
                    }
                }
            }
            $resellerProfit = 0.0;
            if (!empty($resellerId) && !empty($resellerCost)) {
                $resellerProfit = $cost - $resellerCost;
            }

            $sql = "SELECT id, created_by FROM users WHERE id='{$sms->user_id}' LIMIT 1";
            $result = DB::select($sql);
            $user_array = $result[0];
            $created_by = $user_array->created_by;
            $resellerId = 0;
            if ($created_by != 'messenger') {
                $resSub = DB::select("SELECT id FROM users WHERE username='$created_by' LIMIT 1");
                if (!empty($resSub) && count($resSub) > 0) {
                    $resel_array = $resSub[0];
                    $resellerId = $resel_array->id;
                }
            }

            // no of recepients
            $tot_cost = $cost;
            $q1 = "SELECT new_bal, username FROM credits WHERE user_id = '{$sms->user_id}'";
            $result = DB::select($q1);
            $detail = $result[0];

            $curr_bal = $detail->new_bal;
            $user_sess = $detail->username;
            $myIds = $sms->user_id;
            $job_id = $this->sms->job_id;


            if ($curr_bal >= $tot_cost) {
                $count = 0;
                $number = $destination[$count];
                $msisdn = preg_replace('/\D/', '', $number);
                $id = uniqid('NS', true);

                if (is_numeric($msisdn)) {

                    if (substr($numb, 0, 1) == '1' || substr($numb, 0, 1) == '9') {
                        $code = substr($numb, 0, 1);
                        $ccLength = strlen($code);
                    } elseif (substr($numb, 0, 2) == '44' || substr($numb, 0, 2) == '96' || substr($numb, 0, 2) == '64' || substr($numb, 0, 2) == '27') {
                        $code = substr($numb, 0, 2);
                        $ccLength = strlen($code);
                    } else {
                        $code = substr($numb, 0, 3);
                        $ccLength = strlen($code);
                    }
                    $network = $this->which_network($msisdn);

                    $standard_len = $ccLength + $this->checkCode($code);

                    $new_len = strlen($msisdn);

                    if ($user_sess == 'stanbicgh' || $user_sess == 'Sammy') {
                        $userNetwork = $this->get_user_sms_network($sms->user_id, $msisdn);
                        $resp = $this->sendsms($id, $job_id, $user_sess, $msisdn, $sender, $sms_count, $userNetwork, $msgs, $submitdt, $created_by, $myIds);
                        $this->info($user_sess . ' | ' . $sms->msisdn . ' | ' . $sms->sender . ' | ' . $id . ' | ' . $resp);
                    } else {
                        if ($standard_len !== $new_len && $code !== '64') {
                            $sql = "INSERT INTO sms_log(id, job_id,user_id, username, msisdn, sender, sms_count, network, message,submit_date, status,created_by,response,originated,created_at)
                    VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
                            DB::insert($sql, [$id, $job_id, $myIds, $user_sess, $msisdn, $sender, $sms_count, $network, $msgs, $submitdt, 'FAILED', $created_by, '', 'mtnuser', date('Y-m-d H:i:s')]);
                            $this->error($user_sess . ' | ' . $sms->msisdn . ' | ' . $sms->sender . ' | Invalid Destination');
                            return;
                        } else {
                            $userNetwork = $this->get_user_sms_network($sms->user_id, $msisdn);
                            $resp = $this->sendsms($id, $job_id, $user_sess, $msisdn, $sender, $sms_count, $userNetwork, $msgs, $submitdt, $created_by, $myIds);
                            $this->info($user_sess . ' | ' . $sms->msisdn . ' | ' . $sms->sender . ' | ' . $id . ' | ' . $resp);
                        }
                    }
                }

                DB::update("UPDATE credits SET credit_used = credit_used + '$tot_cost', new_bal = new_bal - '$tot_cost' WHERE username = ?", [$user_sess]);
                //update reseller profit
                if (!empty($resellerId) && $resellerProfit > 0) {
                    DB::update("UPDATE credits SET credit_used = credit_used - '$resellerProfit', new_bal = new_bal + '$resellerProfit' WHERE user_id = '$resellerId'");
                }
            }
        } catch (\Throwable $t) {
            $this->error($t->getMessage());
            ErrorReporting::report($t);
        }
    }

    private function get_user_sms_network($userId, $msisdn) {
        $sms_network = [];
        $query = "SELECT * FROM networks";
        $res = DB::select($query);
        if (!empty($res) && count($res)>0) {
            foreach ($res as $network) {
                $prefixes = explode(',', $network->prefix);
                foreach ($prefixes as $prefix) {
                    $prefix = trim($prefix);
                    if (strpos($msisdn, $prefix) === 0) {
                        $network_id = $network->id;
                        $country_id = $network->country_id;
                        $query = "SELECT * from user_networks where user_id='$userId' and network_id='$network_id' and country_id='$country_id' LIMIT 0,1";
                        $res2 = DB::select($query);
                        if (!empty($res2) && count($res2)>0) {
                            $usr_price = $res2[0];
                            $sms_network = ['network_id' => $network_id, 'network' => $network->nice_name, 'sms_price' => $usr_price->sms_price];
                        } else {
                            $sms_network = ['network_id' => $network_id, 'network' => $network->nice_name, 'sms_price' => $network->sms_price];
                        }
                    }
                }

            }
        }
        if (!empty($sms_network))
            return $sms_network;
        $query = "select price from credits where user_id='$userId' limit 0,1";
        $res = DB::select($query);
        if (!empty($res) && count($res)>0) {
            $record = $res[0];
            return ['network_id' => null, 'network' => null, 'sms_price' => $record->price];
        }
        return ['network_id' => null, 'network' => null, 'sms_price' => null];
    }

    private function sendsms($id, $job_id, $user_sess, $msisdn, $sender, $sms_count, $userNetwork, $msgs, $submitdt, $created_by, $myid) {
        $network = $userNetwork['network'];
        $created_at = date('Y-m-d H:i:s');
        date_default_timezone_set('GMT');
        $submitdt = date('Y-m-d H:i:s');
        $msgs = urlencode($msgs);

        // remove carriage returns
        // ==========RUN DIRECT URL TOO===========

        $msgs = str_replace("%5Cr", '%20', $msgs);
        // remove new lines
        $msgs = str_replace("%5Cn", '%0A', $msgs);
        // remove carriage returns
        $msgs = str_replace("%5C", '%20', $msgs);
        // remove backslash returns

        $dlr = "https://bulk.deywuro.com/api/dlr-receiver-route?source=%P&destination=%p&SVC=%n&msgID=%F&msg=%a&msglen=%L&timestamp=%t&status=%d&smsc=%i&smsid=%I&dlrv=%d&MDS=%D&DLRS=%A&osms=%b&mid=" . $id;
        $from = urlencode($sender);
        $dlrEncode = urlencode($dlr);

        if($this->sms->flash == 'flash')
            $url = "http://esme.npontutechnologies.com:13014/cgi-bin/sendsms?username=mtnuser&password=O14ns0&to=" . $msisdn . "&from=" . $from . "&text=" . $msgs . "&dlr-mask=31&mclass=0&dlr-url=" . $dlrEncode;
//            $url = "http://esme.npontutechnologies.com:13014/cgi-bin/sendsms?username=mtnuser&password=O14ns0&to=" . $msisdn . "&from=" . $from . "&text=" . $msgs . "&dlr-mask=31&mclass=0";
        else
            $url = "http://esme.npontutechnologies.com:13014/cgi-bin/sendsms?username=mtnuser&password=O14ns0&to=" . $msisdn . "&from=" . $from . "&text=" . $msgs . "&dlr-mask=31&dlr-url=" . $dlrEncode;
//            $url = "http://esme.npontutechnologies.com:13014/cgi-bin/sendsms?username=mtnuser&password=O14ns0&to=" . $msisdn . "&from=" . $from . "&text=" . $msgs . "&dlr-mask=31";


        file_put_contents(storage_path('sms_log/kannel.log'), date('Y m d, H:i:s').' | Before Sending Request | '.$url. PHP_EOL. PHP_EOL, FILE_APPEND);

        try {
            $urloutput = file_get_contents($url);
        } catch (\Throwable $t) {
            file_put_contents(storage_path('sms_log/kannel.log'), date('Y m d, H:i:s').' | ERROR | '.$t->getMessage(). PHP_EOL. PHP_EOL, FILE_APPEND);
            $urloutput = $t->getMessage();
        }

        file_put_contents(storage_path('sms_log/kannel.log'), date('Y m d, H:i:s').' | After Sending Request | URL= '.$url.' | RESP= '.$urloutput. PHP_EOL. PHP_EOL, FILE_APPEND);

        $msgsd = urldecode($msgs);
        $sql = "INSERT INTO sms_log(id, job_id,user_id, username, msisdn, sender, sms_count, network, message,submit_date, status,created_by,response,originated,created_at)
                    VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        $returnInsert = DB::insert($sql,[$id, $job_id,$myid, $user_sess, $msisdn, $sender,$sms_count,$network,$msgsd,$submitdt,'PENDING',$created_by,$urloutput,'mtnuser',$created_at]);
        $this->info('INSERT='.$returnInsert.'|SQL='.$sql);
        return $urloutput;
    }

    private function which_network($msisdn) {
        $no = substr($msisdn, 3, 2);
        if ($no == '24' || $no == '54' || $no == '55') {
            $net = 'MTN';
        } elseif ($no == '20' || $no == '50') {
            $net = 'VODAFONE';
        } elseif ($no == '27' || $no == '57') {
            $net = 'TIGO';
        } elseif ($no == '26') {
            $net = 'AIRTEL';
        } elseif ($no == '23') {
            $net = 'GLO';
        } elseif ($no == '28') {
            $net = 'EXPRESSO';
        } else {
            $net = 'UNKNOWN';
        }

        return $net;
    }

    private function no_pages($no_chars) {

        if ($no_chars <= 160) {
            $no_pages = 1;
        }
        if ($no_chars > 160 && $no_chars <= 306) {
            $no_pages = 2;
        }
        if ($no_chars > 306 && $no_chars <= 459) {
            $no_pages = 3;
        }
        if ($no_chars > 459 && $no_chars <= 621) {
            $no_pages = 4;
        }
        if ($no_chars > 621) {
            $no_pages = 5;
        }

        return $no_pages;
    }

    private function checkCode($code) {
        if ($code == '246') {
            $msisdnLeng = 6;
            return $msisdnLeng;
        } elseif ($code == '238' || $code == '241' || $code == '239' || $code == '220') {
            $msisdnLeng = 7;
            return $msisdnLeng;
        } elseif ($code == '64' || $code == '229' || $code == '257' || $code == '237' || $code == '236' || $code == '235' || $code == '225' || $code == '243' || $code == '231' || $code == '223' || $code == '227' || $code == '228') {
            $msisdnLeng = 8;
            return $msisdnLeng;
        } elseif ($code == '242' || $code == '240' || $code == '254' || $code == '265' || $code == '250' || $code == '27' || $code == '221' || $code == '232' || $code == '211' || $code == '255' || $code == '256' || $code == '260' || $code == '233' || $code == '972') {
            $msisdnLeng = 9;
            return $msisdnLeng;
        } elseif ($code == '1' || $code == '234' || $code == '218' || $code == '263' || $code == '44' || $code == '96') {
            return $msisdnLeng = 10;
        } elseif ($code == '9') {
            return $msisdnLeng = 11;
        } else {
            $msisdnLeng = 10;
            return $msisdnLeng;
        }

    }


    private function info($text) {
        if(env('APP_ENV')=='local') {
            Log::info('INFO '.date('d-m-Y H:i:s').' || '.$text);
        } else
            file_put_contents($this->log_path,'INFO '.date('d-m-Y H:i:s').' || '.$text.PHP_EOL, FILE_APPEND);
//            \swoole_async_writefile($this->log_path, 'INFO '.date('d-m-Y H:i:s').' || '.$text.PHP_EOL, null, FILE_APPEND);
    }

    private function warn($text) {
        if(env('APP_ENV')=='local') {
            Log::info('WARN '.date('d-m-Y H:i:s').' || '.$text);
        } else
            file_put_contents($this->log_path,'WARN '.date('d-m-Y H:i:s').' || '.$text.PHP_EOL, FILE_APPEND);
//            \swoole_async_writefile($this->log_path, 'WARN '.date('d-m-Y H:i:s').' || '. $text.PHP_EOL, null, FILE_APPEND);
    }

    private function error($text) {
        if(env('APP_ENV')=='local') {
            Log::error('ERROR '.date('d-m-Y H:i:s').' || '.$text);
        } else
            file_put_contents($this->log_path,'ERROR '.date('d-m-Y H:i:s').' || '.$text.PHP_EOL, FILE_APPEND);
//            \swoole_async_writefile($this->log_path, 'ERROR '.date('d-m-Y H:i:s').' || '. $text.PHP_EOL, null, FILE_APPEND);
    }
}
