<?php

/**
 * @package Pulsa Online w38s.com
 * @version 3.7.0
 * @author Samsul Bahri (0818118061 / achunk17@gmail.com)
 * @link http://w38s.com
 * @link http://facebook.com/achunks
 * @license http://w38s.com/lisensi
 * @copyright 2015 - 2018
 */

defined('BASEPATH') or exit('No direct script access allowed');

class Fondasms extends CI_Controller
{
    protected $smsg_config = array();
    protected $events = null;

    public function index()
    {
        if ($this->system->get_set('maintenance') == 'on') {
            return $this->display_output(array('error' => array('message' =>
                        'Situs sedang dalam maintenance')));
        }

        $this->smsg_config = json_decode($this->system->get_set('fondasms'), true);

        if (!$this->is_validated($this->smsg_config['password'])) {
            return $this->display_output(array('error' => array('message' =>
                        'Password Salah')), 'HTTP/1.1 401 Unauthorized');
        }

        if ($this->system->set['smsg_aktif'] <= (time() - 60)) {
            $this->db->where('set_key', 'smsg_aktif');
            $this->db->set('set_val', time());
            $this->db->update('setelan');
        }

        $action = $this->input->post('action');
        $this->load->model('mtrx');

        if ($action == 'test') {
            return $this->display_output(array());
        }
        if ($action == 'incoming') {
            $this->incoming_sms();
        }
        if ($action == 'send_status') {
            $this->send_status();
        } else {
            $this->mtrx->sms_remind_trx();
            $this->send_sms();
        }
        $this->display_output(array('events' => $this->events));
    }

    protected function incoming_sms()
    {
        if ($this->input->get('disabled_inbox')) {
            return;
        }

        $message_type = $this->input->post('message_type');
        $pesan = $this->input->post('message');
        $timestamp = (int)substr($this->input->post('timestamp'), 0, 10);
        $from = $this->input->post('from');

        if ($message_type != 'sms')
            return;

        $this->db->where('in_from', $from);
        $this->db->where('in_message', $pesan);
        $this->db->where('in_timestamp >', ($timestamp - 300));
        if ($this->db->count_all_results('sms_masuk'))
            return;

        $us_phone = substr($from, 0, 3) == '+62' ? '0' . substr($from, 3) : $from;
        $this->db->select('us_id');
        $this->db->where('us_phone', $us_phone);
        $q = $this->db->get('users');
        if ($q->num_rows() == 1) {
            $us = $q->row();
            $this->db->insert('sms_masuk', array(
                'in_uid' => 'user.' . $us->us_id,
                'in_from' => $from,
                'in_message' => $pesan,
                'in_timestamp' => $timestamp,
                ));
            $last_id = $this->db->insert_id();
            $this->load->model('smstrx_model');
            $this->smstrx_model->proses_pesan($from, $pesan, $last_id);
            return;
        }
        return $this->proses_inbox($from, $pesan, $timestamp);
    }

    protected function proses_inbox($from, $message, $timestamp)
    {
        $trx_in_process = $this->mtrx->get_trx_in_process(array('sms', 'otomax_api_sms'));

        if ($trx_in_process) {
            foreach ($trx_in_process as $trx) {
                if ($trx->tr_status != 'dalam_proses')
                    continue;

                $nomor = $trx->tr_id_plgn ? $trx->tr_id_plgn : $trx->tr_no_hp;
                if (strpos($message, $nomor) !== false) {
                    $status = $this->mtrx->cek_status($message, $trx->sv_regex_sukses, $trx->
                        sv_regex_gagal);
                    if ($status == 'sukses') {
                        $this->db->where('in_trx_id', $trx->tr_id)->delete('sms_masuk');
                        $inbox = array(
                            'in_trx_id' => $trx->tr_id,
                            'in_type' => 'sms',
                            'in_from' => $from,
                            'in_message' => $message,
                            'in_timestamp' => $timestamp,
                            );
                        $this->db->insert('sms_masuk', $inbox);
                        $this->mtrx->set_sukses($trx, $message);
                        return;
                    }
                    if ($status == 'gagal') {
                        $this->db->where('in_trx_id', $trx->tr_id)->delete('sms_masuk');
                        $inbox = array(
                            'in_trx_id' => $trx->tr_id,
                            'in_type' => 'sms',
                            'in_from' => $from,
                            'in_message' => $message,
                            'in_timestamp' => $timestamp,
                            );
                        $this->db->insert('sms_masuk', $inbox);
                        $trx->sv_gateway = 'sms';
                        $this->mtrx->set_gagal($trx, $message);
                        return;
                    }
                }
            }
        }
        if ($this->smsg_config['inbox'] == 'all') {
            $this->db->insert('sms_masuk', array(
                'in_type' => 'sms',
                'in_from' => $from,
                'in_message' => $message,
                'in_timestamp' => $timestamp,
                ));
        }
    }

    protected function send_status()
    {
        $sid = explode('.', $this->input->post('id'));
        if ($this->input->post('error') == 'Timeout while attempting to send message') {
            return;
        }
        if ($this->input->post('error')) {
            $this->events = array(array(
                    'event' => 'cancel',
                    'id' => $this->input->post('id'),
                    ));
        }
        if ($sid[0] == 'sms') {
            $this->db->where('out_id', $sid[1]);
            $this->db->where('out_status', '-');
            $this->db->update('sms_keluar', array(
                'out_status' => $this->input->post('status'),
                'out_error' => $this->input->post('error'),
                'out_send_date' => time(),
                ));
            $rows = $this->db->affected_rows();
            if ($this->input->post('error') && $rows) {
                $sms = $this->db->where('out_id', $sid[1])->get('sms_keluar')->row();
                $this->db->insert('notifikasi', array(
                    'us_id' => '0',
                    'nf_admin' => '1',
                    'nf_judul' => 'Gagal Mengirim SMS',
                    'nf_teks' => "No Tujuan: " . $sms->out_to . "\r\nPesan: " . $sms->out_message .
                        "\r\nKesalahan: " . $this->input->post('error'),
                    'nf_link' => '',
                    'nf_tanggal' => time(),
                    ));
            }
        } elseif ($sid[0] == 'isi') {
            $this->db->select('transaksi.*, voucher.vo_kode_fisik, voucher.vo_kode_trx, server.*, ' .
                'users.us_username, users.us_name, users.us_email, users.us_phone, users.us_balance, ' .
                'users.us_data, users.us_telegram_id');
            $this->db->from('transaksi');

            $this->db->join('server', 'server.sv_id = transaksi.sv_id', 'LEFT');
            $this->db->join('voucher', 'voucher.vo_id = transaksi.vo_id', 'LEFT');
            $this->db->join('users', 'users.us_id = transaksi.us_id', 'LEFT');

            $this->db->where('transaksi.tr_id', $sid[1]);
            $this->db->where('transaksi.tr_status', '-');
            $query = $this->db->get();
            if (!$query->num_rows())
                return;

            $trx = $query->row();

            if (!$trx->sv_regex_sukses || !$trx->sv_regex_gagal)
                $status = 'sukses';
            else
                $status = 'dalam_proses';

            $status = $this->input->post('error') ? 'gagal' : $status;

            if ($status == 'gagal') {
                $inbox = array(
                    'in_trx_id' => $trx->tr_id,
                    'in_type' => 'sms',
                    'in_from' => $trx->sv_nama,
                    'in_message' => 'Trx #' . $trx->tr_id . ' ' . ($trx->vo_kode_trx ? $trx->
                        vo_kode_trx : $trx->vo_kode) . '.' . ($trx->tr_id_plgn ? $trx->tr_id_plgn : $trx->
                        tr_no_hp) . ' tidak diproses karena gagal mengirim SMS. (Error: ' . $this->
                        input->post('error') . ')',
                    'in_timestamp' => time(),
                    );
                $this->db->insert('sms_masuk', $inbox);
                $trx->sv_gateway = 'sms';
                $this->mtrx->set_gagal($trx, $inbox['in_message']);
            } elseif ($status == 'sukses') {
                $inbox = array(
                    'in_trx_id' => $trx->tr_id,
                    'in_type' => 'sms',
                    'in_from' => $trx->sv_nama,
                    'in_message' => 'Trx #' . $trx->tr_id . ' ' . ($trx->vo_kode_trx ? $trx->
                        vo_kode_trx : $trx->vo_kode) . '.' . ($trx->tr_id_plgn ? $trx->tr_id_plgn : $trx->
                        tr_no_hp) . ' SUKSES',
                    'in_timestamp' => time(),
                    );
                $this->db->insert('sms_masuk', $inbox);
                $this->mtrx->set_sukses($trx, $inbox['in_message']);
            } else {
                $this->db->where('tr_id', $trx->tr_id);
                $this->db->set('tr_status', 'dalam_proses');
                $this->db->update('transaksi');
            }
        }
    }

    protected function send_sms()
    {
        $disabled_trx = $this->input->get('disabled_trx') ? true : false;
        $accept_sms = $this->input->get('accept_sms');

        if (strpos($accept_sms, '.') !== false)
            $accept_sms = explode('.', $accept_sms);

        if (!$disabled_trx)
            $sms = $this->sms_trx();
        else
            $sms = array();

        $this->db->where('out_type', 'sms');
        $this->db->where('out_status', '');
        $this->db->order_by('out_id', 'ASC');
        $this->db->limit(10);
        $query = $this->db->get('sms_keluar');
        if ($query->num_rows()) {
            foreach ($query->result() as $outbox) {
                $to = $outbox->out_to;
                if (substr($to, 0, 3) == '628')
                    $to = '08' . substr($to, 3);

                if (is_array($accept_sms) && !in_array(substr($to, 0, 4), $accept_sms))
                    continue;

                $sms[] = array(
                    'id' => "sms." . $outbox->out_id,
                    'to' => $to,
                    'message' => $outbox->out_message,
                    );
                $this->db->where('out_id', $outbox->out_id);
                $this->db->set('out_status', '-');
                $this->db->update('sms_keluar');
            }
        }
        if ($sms) {
            $this->events = array(array(
                    'event' => 'send',
                    'messages' => $sms,
                    ));
        }
        /* else {
        $this->events = null;
        }*/
    }

    protected function sms_trx()
    {
        $sms = array();
        $pending_trx = $this->mtrx->get_pending_trx(array('sms', 'otomax_api_sms'));

        if (!$pending_trx)
            return $sms;

        foreach ($pending_trx as $trx) {
            if ($trx->vo_kode_fisik) {
                $this->mtrx->trx_voucher_fisik($trx);
            } else {
                if ($trx->sv_gateway == 'otomax_api_sms' && (int)$trx->tr_retry == 0)
                    continue;
                $sms[] = array(
                    'id' => "isi." . $trx->tr_id,
                    'to' => $trx->sv_sms_center,
                    'priority' => 1,
                    'message' => $this->mtrx->get_format_trx($trx),
                    );
                $this->db->where('sv_id', $trx->sv_id);
                $this->db->set('sv_saldo', $trx->sv_saldo - $trx->tr_harga2);
                $this->db->update('server');
                $this->mtrx->set_proses($trx);
            }
        }
        return $sms;
    }
    protected function compute_signature($url, $data, $password)
    {
        ksort($data);
        $input = $url;
        foreach ($data as $key => $value)
            $input .= ",$key=$value";
        $input .= ",$password";
        return base64_encode(sha1($input, true));
    }

    protected function is_validated($correct_password)
    {
        if ($this->input->get('p') && $this->input->get('p') == $correct_password) {
            return true;
        }
        $signature = @$_SERVER['HTTP_X_REQUEST_SIGNATURE'];
        if (!$signature) {
            return false;
        }
        $is_secure = (!empty($_SERVER['HTTPS']) and filter_var($_SERVER['HTTPS'],
            FILTER_VALIDATE_BOOLEAN));
        $protocol = $is_secure ? 'https' : 'http';
        $full_url = $protocol . "://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
        $correct_signature = $this->compute_signature($full_url, $_POST, $correct_password);
        return $signature === $correct_signature;
    }

    protected function display_output($data = array(), $header = '')
    {
        if ($header)
            $this->output->set_header($header);
        $this->output->set_content_type('application/json', 'utf-8');
        $this->output->set_output(json_encode($data));
        $this->output->_display();
        exit();
    }


}
