<?php

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

class Wechat_lib
{
    protected $ci;
    private $wechat_config;
    private $wechat_host;

    public function __construct()
    {
        $this->ci =& get_instance();
        $this->ci->config->load("wechat", true);
    }

    public function response_to_wx($response_arr=null)
    {
        if ($response_arr===null) {
            echo "";
        }
        $response_body = $this->to_xml($response_arr);
        echo $response_body;
        return false;
    }

    /**
     * 转发到微信客服
     * @param string $text
     * @param string $to_user
     * @param string $from_operator
     */
    public function response_customer_service($text=null, $to_user=null, $from_operator=null)
    {
        $content_arr = $text===null ? null :
        array(
            "ToUserName" => $to_user,
            "FromUserName" => $from_operator,
            "CreateTime" => time(),
            "MsgType" => "transfer_customer_service",
            "Content" => $text
        );

        return $this->response_to_wx($content_arr);
    }

    public function response_text($text=null, $to_user=null, $from_operator=null)
    {
        $content_arr = $text===null ? null :
        array(
            "ToUserName" => $to_user,
            "FromUserName" => $from_operator,
            "CreateTime" => time(),
            "MsgType" => "text",
            "Content" => $text
        );

        return $this->response_to_wx($content_arr);
    }
    /**
     * 开发者认证token
     * @param array $input:微信的GET请求数据
     */
    public function auth_signature($input, $token)
    {
        $s = $input["signature"];
        $t = $input["timestamp"];
        $n = $input["nonce"];
        $e = $input["echostr"];
        $tmpArr = array($t, $n, $token);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode( $tmpArr );
        $tmpStr = sha1( $tmpStr );
        // $ee = 'V3xwtddYXPES064KgVh0uxqfPVV2qDK1HvfX7PIRvxR';
        ob_clean();
        if( $s == $tmpStr ){
            echo $e;
        }else{
            echo "";
        }
        return false;
    }

    public function call_wechat($wechat_host, $url, $get_data=array(), $post_data=null)
    {
        $this->wechat_host = $wechat_host;
        $this->wechat_config = $this->ci->config->item($wechat_host, 'wechat');
        if ( false === array_key_exists('code', $get_data)) {
            $access_token = $this->get_access_token();
            $get_data = array_merge($get_data, array("access_token" => $access_token) );
        }
        $url = $this->ci->config->item('url_domain', 'wechat') . $url . "?" . http_build_query($get_data);
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 20);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        if ($post_data !== null) {
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
        }
        $output = curl_exec($curl);
        if (curl_errno($curl)) {
            log_message('error', "curl error code: ".curl_error($curl)."; curl postBodyString: ".$post_data);
        } else {
            $httpStatusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            if (200 !== $httpStatusCode) {
                log_message('error', "Request html Status Code: ".$httpStatusCode."; curl postBodyString: ".$post_data);
            }
            $output_arr = json_decode($output, true);
            if (false !== stripos($output, "errcode")
                && 0 !== intval($output_arr['errcode'])
            ) {
                log_message('error','wechat reponse error:' . var_export($output, 1));
                curl_close($curl);
                return null;
            }
        }
        curl_close($curl);
        return $output;
    }

    private function get_access_token()
    {
        $url = $this->ci->config->item('url_domain', 'wechat') . "/cgi-bin/token?grant_type=client_credential&appid=" . $this->wechat_config['app_id'] . "&secret=" . $this->wechat_config['app_secret'];
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_TIMEOUT, 20);
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $output = curl_exec($curl);
        if (curl_errno($curl)) {
            log_message('error', "curl error code: ".curl_error($curl));
        } else {
            $httpStatusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
            if (200 !== $httpStatusCode) {
                log_message('error', "Request html Status Code: ".$httpStatusCode);
            }
            $output_arr = json_decode($output, true);
            if (false !== stripos($output, "errcode")
                && 0 !== intval($output_arr['errcode'])
            ) {
                log_message('error','wechat reponse error:' . var_export($output, 1));
                curl_close($curl);
                return null;
            }
        }
        curl_close($curl);
        $access_token_arr = json_decode($output, true);
        return $access_token_arr['access_token'];
    }

    /**
     * 发送文本消息给已关注用户
     * 当用户和公众号产生特定动作的交互时, 允许在48小时内调用此接口发送消息给用户
     * 允许的<特定动作>
     * * 用户发送信息
     * * 点击自定义菜单（仅有点击推事件、扫码推事件、扫码推事件且弹出“消息接收中”提示框这3种菜单类型是会触发客服接口的）
     * * 关注公众号
     * * 扫描二维码
     * * 支付成功
     * * 用户维权
     * @param [type] $wechat_host
     * @param 用户openid $to_user
     * @param 文本内容 $text
     */
    public function send_text_customer($wechat_host, $to_user, $text)
    {
        $url = "/cgi-bin/message/custom/send";
        $post = array(
            "touser" => $to_user,
            "msgtype" => "text",
            "text" => array(
                 "content" => $text
            )
        );
        return $this->call_wechat($wechat_host, $url, [], json_encode($post, JSON_UNESCAPED_UNICODE));
    }

    /**
     * 已下单未支付
     * @param [type] $wechat_host
     * @param [type] $openid
     * @param array $order
     */
    public function push_book_ok($wechat_host, $openid, $order=array())
    {
        $this->ci->load->model('Wechat_service_model');
        $url = "/cgi-bin/message/template/send";
        $order_detail_path = "/order" . "/" .$order['orderTour'][0]['coli'] . "/" . $order['orderTour'][0]['orderId'];
        $post = array(
            "touser" => $openid,
            "template_id" => 'eSnnOFczriQFJSPy4q7797iKi4HCh6im5vP8iLlIHAU',
            "url" => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7e605820faf98a05&redirect_uri=http%3A%2F%2Ftrippest.mycht.cn%2Fapi%2Findex.php%2Fwechat-mp%2Flogin-now%2Ftrippest%3Fl%3D' . urlencode($order_detail_path) . '&response_type=code&scope=snsapi_base&state=detail#wechat_redirect',
            "topcolor" => '#173177',
            "data" => array(
                "first" => array(
                    "value" => 'Thanks for booking with Trippest. Click to follow up the payment now.',
                    "color" => '#173177'
                ),
                "OrderID" => array(
                    "value" => 'Booking Reference # ' . $order['orderTour'][0]['orderId'],
                    "color" => '#173177'
                ),
                "PkgName" => array(
                    "value" => $order['orderTour'][0]['tourName'],
                    "color" => '#173177'
                ),
                "TakeOffDate" => array(
                    "value" => 'Tour Date ' . date('M.d, Y', strtotime($order['orderTour'][0]['startDate'])),
                    "color" => '#173177'
                ),
                "Remark" => array(
                    "value" => 'For more information…',
                    "color" => '#173177'
                )
            ),
        );
        $this->call_wechat($wechat_host, $url, [], json_encode($post, JSON_UNESCAPED_UNICODE));
        $push_arr = array(
            "wp_wu_id" => $order['wechat']['wu_id'],
            "wp_msgtype" => "template",
            "wp_content" => json_encode($post['data'], JSON_UNESCAPED_UNICODE),
            "wp_templateid" => $post['template_id'],
            "wp_templatename" => "旅游订单待支付",
            "wp_createtime" => date('Y-m-d H:i:s'),
            "wp_wc_id" => $order['wechat']['wc_id']
        );
        $this->ci->Wechat_service_model->insert_wechat_push($push_arr);
        return true;
    }

    /**
     * 行程即将开始
     * 导游司机等调度信息
     * @param [type] $wechat_host
     * @param [type] $openid
     * @param array $order
     */
    public function push_arrangement($wechat_host, $openid, $order=array())
    {
        $this->ci->load->model('Wechat_service_model');
        $url = "/cgi-bin/message/template/send";
        $order_detail_path = "/order" . "/" .$order['orderTour'][0]['coli'] . "/" . $order['orderTour'][0]['orderId'];
        $post = array(
            "touser" => $openid,
            "template_id" => 'wqfkOjDe5VpJn1hYC2lhO3w2qQ96o-a1ylt0wl9-1JE',
            "url" => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7e605820faf98a05&redirect_uri=http%3A%2F%2Ftrippest.mycht.cn%2Fapi%2Findex.php%2Fwechat-mp%2Flogin-now%2Ftrippest%3Fl%3D' . urlencode($order_detail_path) . '&response_type=code&scope=snsapi_base&state=detail#wechat_redirect',
            "topcolor" => '#173177',
            "data" => array(
                "first" => array(
                    "value" => 'Booking Reference # ' . $order['orderTour'][0]['orderId'],
                    "color" => '#173177'
                ),
                "keyword1" => array(
                    "value" => $order['orderTour'][0]['tourName'],
                    "color" => '#173177'
                ),
                "keyword2" => array(
                    "value" => 'Start Date: ' . $order['orderTour'][0]['startDate'],
                    "color" => '#173177'
                ),
                "remark" => array(
                    "value" => 'Tap this card to find more details.', // TODO: Guide:北京禹昭Helen, Mobile:15333241912
                    "color" => '#173177'
                )
            ),
        );
        $this->call_wechat($wechat_host, $url, [], json_encode($post, JSON_UNESCAPED_UNICODE));
        $push_arr = array(
            "wp_wu_id" => $order['wechat']['wu_id'],
            "wp_msgtype" => "template",
            "wp_content" => json_encode($post['data'], JSON_UNESCAPED_UNICODE),
            "wp_templateid" => $post['template_id'],
            "wp_templatename" => "行程即将开始",
            "wp_createtime" => date('Y-m-d H:i:s'),
            "wp_wc_id" => $order['wechat']['wc_id']
        );
        $this->ci->Wechat_service_model->insert_wechat_push($push_arr);
        return true;
    }

    public function push_wechat_paid($wechat_host, $payment=array(), $order=array() )
    {
        $this->ci->load->model('Wechat_service_model');
        $url = "/cgi-bin/message/template/send";
        $order_detail_path = "/order" . "/" .$order['orderTour'][0]['coli'] . "/" . $order['orderTour'][0]['orderId'];
        bcscale(2);
        $total_fee = bcdiv($payment['total_fee'], $this->ci->config->item('currency_unit', 'wechat'));
        $post = array(
            "touser" => $payment['openid'],
            "template_id" => '2ar2YEdmcylhGJr2e6C9SLresnCWMLfDK8RPr2caj04',
            "url" => 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx7e605820faf98a05&redirect_uri=http%3A%2F%2Ftrippest.mycht.cn%2Fapi%2Findex.php%2Fwechat-mp%2Flogin-now%2Ftrippest%3Fl%3D' . urlencode($order_detail_path) . '&response_type=code&scope=snsapi_base&state=detail#wechat_redirect',
            "topcolor" => '#173177',
            "data" => array(
                "first" => array(
                    "value" => 'Payment successful and your booking is confirmed.',
                    "color" => '#173177'
                ),
                "keyword1" => array(
                    "value" => $order['orderTour'][0]['leader'],
                    "color" => '#173177'
                ),
                "keyword2" => array(
                    "value" => 'BR# ' . $order['orderTour'][0]['orderId'],
                    "color" => '#173177'
                ),
                "keyword3" => array(
                    "value" => 'Total payment ' . $payment['fee_type'] . $total_fee,
                    "color" => '#173177'
                ),
                "keyword4" => array(
                    "value" => $order['orderTour'][0]['tourName'],
                    "color" => '#173177'
                ),
                "remark" => array(
                    "value" => 'You’ll receive a notice about guides/driver info at the night before tour started.',
                    "color" => '#173177'
                )
            ),
        );
        $this->call_wechat($wechat_host, $url, [], json_encode($post, JSON_UNESCAPED_UNICODE));
        $push_arr = array(
            "wp_wu_id" => $order['wechat']['wu_id'],
            "wp_msgtype" => "template",
            "wp_content" => json_encode($post['data'], JSON_UNESCAPED_UNICODE),
            "wp_templateid" => $post['template_id'],
            "wp_templatename" => "支付成功",
            "wp_createtime" => date('Y-m-d H:i:s'),
            "wp_wc_id" => $order['wechat']['wc_id']
        );
        $this->ci->Wechat_service_model->insert_wechat_push($push_arr);
        return true;
    }

    /**
     * 格式化参数格式化成url参数
     */
    public function to_url_params($xml_arr)
    {
        $buff = "";
        foreach ($xml_arr as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 输出xml字符
     * @throws WxPayException
    **/
    function to_xml($arr)
    {
        if(!is_array($arr) || count($arr) <= 0)
        {
            return false;
        }

        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    /**
     * 将xml转为array
     * @param string $xml
     * @throws WxPayException
     */
    function from_xml($xml)
    {
        if(!$xml){
            return false;
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }


}

/* End of file Wechat_lib.php */
