<?php
// +----------------------------------------------------------------------
// | OneThink [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2013 http://www.onethink.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://www.zjzit.cn>
// +----------------------------------------------------------------------

namespace Home\Controller;

use yidas\linePay\Client;

/**
 * 前台控制器
 */
class LineController extends HomeController
{
    protected $userid;
    protected $source = '';
    protected $unionid = '';
    //protected $payurl = 'https://sandbox-api-pay.line.me'; //Sandbox

    protected $payurl = 'https://api-pay.line.me';  //Production

    public function _initialize()
    {
        //记录日志
        $msg = '[' . date('Y-m-d H:i:s') . ']' . "\n";
        $msg .= ACTION_NAME . "\n";
        if ($_GET) {
            $msg .= 'GET:' . json_encode($_GET) . "\n";
        }
        if ($_POST) {
            $msg .= 'POST:' . json_encode($_POST) . "\n";
        }
        $msg .= "\n\n\n";

        file_put_contents('logs/line/' . date('Y-m-d') . '.log', $msg, FILE_APPEND);
    }

    public function index()
    {
        exit('index');

    }

    //处理line用户授权
    public function auth()
    {
        $code = $_GET['code'];
        if (!$code) {
            die('need code');
        }
        $jumpUrl = $_SESSION['orginUrl'] ? $_SESSION['orginUrl'] : U('Index/index');

        $url = 'https://api.line.me/oauth2/v2.1/token';
        $data = array();
        $data['grant_type'] = 'authorization_code';
        $data['code'] = $code;
        $data['redirect_uri'] = C('Line.redirect_uri');
        $data['client_id'] = C('Line.channel_id');
        $data['client_secret'] = C('Line.channel_secret');

        $data = http_build_query($data);

        $output = json_decode(httpPost($url, $data), true);
        //die($jumpUrl);

        if (!$output['id_token']) {
            die('auth fail,');
            redirect($jumpUrl);
        }

        $id_tokens = $output['id_token'];
        $token_arr = explode('.', $id_tokens);
        $token_data = base64_decode($token_arr[1]);
//        print_pre($token_data);
        $userInfo = json_decode($token_data, true);
//        print_pre($userInfo);
        $_SESSION['lineid'] = $userInfo['sub'];

//        print_pre($output);
        //        die();

        redirect($jumpUrl);

    }

    //选择付款页面
    public function pay($out_trade_no)
    {
//        die($out_trade_no);
        if (substr($out_trade_no, 0, 1) == 'f') {
            $obj_order = M('OrderCode');
        } else {
            $obj_order = M('Order');
        }

        $orderInfo = $obj_order->where(array('out_trade_no' => $out_trade_no))->find();
//        print_pre($orderInfo['body']);
        //        exit();

        $this->assign('orderInfo', $orderInfo);
        $this->meta_title = L('online_pay');
        $this->display();
    }

    //处理支付请求
    public function do_pay($out_trade_no)
    {
        $redir = C('ROOT_DOMAIN') . U('do_pay?out_trade_no=' . $out_trade_no);
//        die($_SESSION['lineid']);

        $this->unionid = getLineID($redir);

        if(!$this->unionid) {
            redirect(U("/Home/Index/bind.html"));
            exit;
        }

        $confirmUrl = C('ROOT_DOMAIN') . U('payReturn?orderId=' . $out_trade_no);
        $url = $this->payurl . '/v3/payments/request';
        $params = array(
            "productName" => "Laundry service" . '_' . date('Ymdhis'),
            "productImageUrl" => "http://img.qclive.cc/default.jpg",
            "amount" => 0.01,
            "currency" => "THB",
            "mid" => $this->unionid,
            "orderId" => $out_trade_no,
            "confirmUrl" => $confirmUrl,
            "capture" => "true",
        );

        if (substr($out_trade_no, 0, 1) == 'f') {
            $obj_order = M('OrderCode');
        } else {
            $obj_order = M('Order');
        }

        $orderInfo = $obj_order->where(array('out_trade_no' => $out_trade_no))->find();

//        print_pre($params);
        //        exit;

        $res = $this->line_request($url, $orderInfo, json_encode($params));
//        echo $res;
        //        file_put_contents('line.txt', $res);

        $res = json_decode($res, true);

//        die(json_encode($res));
        if ($res['returnCode'] == '0000') {
            $paymentUrl = $res['info']['paymentUrl']['web'];
            redirect($paymentUrl);
        } else {
            exit('error');
        }

        exit;

        print_pre($res);
    }

    private function lineSdk()
    {
        require_once $_SERVER['DOCUMENT_ROOT'] . '/vendor/autoload.php';
        $linePay = new Client(array(
            'channelId' => C('Line.pay_channel_id'),
            'channelSecret' => C('Line.pay_channel_secret'),
            'isSandbox' => false,
        ));
        return $linePay;
    }

    public function line_request($url, $orderInfo, $data = null)
    {
        $params = json_decode($data, 1);

        $body = json_decode($orderInfo['body'], 1);

//        [{"id":"1","num":"1","title":"coat 001","price":"100.00","cate":"1"}]

        $items = array();
        if ($body and is_array($body)) {
            foreach ($body as $b) {
                $items[] = array(
                    'id' => $b['id'],
                    'amount' => $b['price'] * $b['num'],
                    'name' => $b['title'],
                    'products' => array(
                        array(
                            'name' => $b['title'],
                            'quantity' => $b['num'],
                            'price' => $b['price'],
                            'imageUrl' => '',
                        ),
                    ),
                );
            }
        }

        if ($items) {
            $data = array(
                'amount' => $orderInfo['total_fee'],
                'currency' => 'THB',
                'orderId' => $orderInfo['out_trade_no'],
                'packages' => $items,
                'redirectUrls' => array(
                    'confirmUrl' => $params['confirmUrl'],
                    'cancelUrl' => MAIN_SITE . '/line-pay/cancel',
                ),
            );

//            print_pre($data);
            //            exit();
                   // print_pre($data);
                   // exit;

            $linePay = $this->lineSdk();
            $response = $linePay->request($data);
            if (!$response->isSuccessful()) {
//            throw new \Exception("Code {$response['returnCode']}: {$response['returnMessage']}");
                $this->assign('msg', "Code {$response['returnCode']}: {$response['returnMessage']}");
                $this->display('payFail');
                exit;
            }

            redirect($response->getPaymentUrl());
            exit;
        } else {
            $this->assign('msg', "Product not found.");
            $this->display('payFail');
            exit;
        }

        $curl = curl_init();
        die($url);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);

        $nonce = time();
//        echo(C('Line.pay_channel_secret') . '/v3/payments/request' . json_encode($data) . $nonce);
        $sign = base64_encode(hash_hmac('sha256', (C('Line.pay_channel_secret') . '/v3/payments/request' . json_encode($data) . $nonce), C('Line.pay_channel_secret')));
        $header = array(
            'Content-Type: application/json',
            'X-LINE-ChannelId: ' . C('Line.pay_channel_id'),
            'X-LINE-Authorization-Nonce: ' . $nonce,
            'X-LINE-Authorization: ' . $sign,
        );
//        die(C('Line.pay_channel_id'));
        //        $header = [
        //            'Content-Type'               => 'application/json',
        //            'X-LINE-ChannelId: ' . C('Line.pay_channel_id'),
        //            'X-LINE-Authorization-Nonce' => $nonce,
        //            'X-LINE-Authorizatione'      => $sign,
        //        ];

//        print_pre($header);

        file_put_contents('a.txt', json_encode($header));

        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

    //支付后 跳转的页面
    public function payReturn()
    {
        $this->meta_title = L('pay_result');

        $out_trade_no = I('orderId', '');
        $transactionId = I('transactionId', '');

        if (!$out_trade_no || !$transactionId) {
            $this->display('payFail');
        } else {
            if (substr($out_trade_no, 0, 1) == 'f') {
                $obj_order = M('OrderCode');
            } else if(substr($out_trade_no, 0, 1) == 'c') {
                $obj_order = M('OrderCharge');
            }else {
                $obj_order = M('Order');
            }

            $orderInfo = $obj_order->where(array('out_trade_no' => $out_trade_no))->find();

            if(substr($out_trade_no, 0, 1) == 'c') {
                $amount = $orderInfo['pay_fee'];
            }else {
                $amount = $orderInfo['total_fee'];
            }

            $linePay = $this->lineSdk();
//            $response = $linePay->details([
            //                "transactionId" => [$transactionId],
            //            ]);
            $response = $linePay->confirm($transactionId, array(
                "amount" => $amount,
                "currency" => 'THB',
            ));
            if (!$response->isSuccessful()) {
//                throw new \Exception("Code {$response['returnCode']}: {$response['returnMessage']}");
                $this->assign('msg', "Code {$response['returnCode']}: {$response['returnMessage']}");
                $this->display('payFail');
                exit;
            }
            $data = $response->getPayInfo();
            $res_amount = $data[0]['amount'];
            $res_orderId = $out_trade_no;
            update_pay_success($out_trade_no, $transactionId); // 修改订单支付状态
            update_pay_type($out_trade_no, 'linepay');
            if (substr($out_trade_no, 0, 1) == 'c') {
                member_charge($out_trade_no);
            }

            //@file_put_contents(dirname(__FILE__) . '/a.txt', $out_trade_no);

            if (substr($out_trade_no, 0, 1) == 's') {
               // @file_put_contents(dirname(__FILE__) . '/a.txt', $out_trade_no . " : s");
                $v = getAvlBox($out_trade_no, 'member'); //分配格子
               // @file_put_contents(dirname(__FILE__) . '/a.txt', $out_trade_no . " : s :" . $v);
                //                 check_baocang($out_trade_no);
            }

            $this->display('paySucc');
            exit;

            $url = $this->payurl . '/v3/payments/' . $transactionId . '/confirm';
            $params = array(
                "amount" => $orderInfo['pay_fee'],
                "currency" => "THB",
            );

            $res = $this->line_request($url, json_encode($params));
            $res = json_decode($res, true);
//             print_pre($res);exit;
            if ($res['returnCode'] == '0000') {
                $res_orderId = $res['info']['orderId'];
                $res_amount = $res['info']['payInfo']['amount'];
                if ($res_orderId == $out_trade_no) {
                    if (substr($out_trade_no, 0, 1) == 's') {
                        getAvlBox($out_trade_no, 'member'); //分配格子
                        //                 check_baocang($out_trade_no);
                    }

                    update_pay_success($out_trade_no, $transactionId); // 修改订单支付状态
                    update_pay_type($out_trade_no, 'linepay');

                    if (substr($out_trade_no, 0, 1) == 'c') {
                        member_charge($out_trade_no);
                    }

                    $this->display('paySucc');
                } else {
                    $this->display('payFail');
                }

            } else {
                $this->display('payFail');
            }
        }

    }

    //充值支付
    public function do_charge($out_trade_no = '')
    {
        $this->unionid = getLineID();

        $obj_order = M('OrderCharge');
        $map = array('out_trade_no' => $out_trade_no);
        $orderInfo = $obj_order->where($map)->find();

        $confirmUrl = C('ROOT_DOMAIN') . U('payReturn?orderId=' . $orderInfo['out_trade_no']);
        $url = $this->payurl . '/v3/payments/request';
        $params = array(
            "productName" => "Online recharge" . '_' . date('Ymdhis'),
            "productImageUrl" => C('DefaultPic'),
            "amount" => $orderInfo['pay_fee'],
            "currency" => "THB",
            "mid" => $this->unionid,
            "orderId" => $orderInfo['out_trade_no'],
            "confirmUrl" => $confirmUrl,
            "capture" => "true",
        );

        $res = $this->line_request_recharge($url, $orderInfo, json_encode($params));

        $res = json_decode($res, true);
        if ($res['returnCode'] == '0000') {
            $paymentUrl = $res['info']['paymentUrl']['web'];
            redirect($paymentUrl);
        }

    }


    public function line_request_recharge($url, $orderInfo, $data = null)
    {
        $params = json_decode($data, 1);

        $body = json_decode($orderInfo['body'], 1);

//        [{"id":"1","num":"1","title":"coat 001","price":"100.00","cate":"1"}]

        $items = array(
            'id' => $params['orderId'],
            'amount' => $params['amount'],
            'name' => $params['productName'],
            'products' => array(
                array(
                    'name' => $params['productName'],
                    'quantity' => '1',
                    'price' => $params['amount'],
                    'imageUrl' => '',
                ),
            ),
        );
        // if ($body and is_array($body)) {
        //     foreach ($body as $b) {
        //         $items[] = array(
        //             'id' => $b['id'],
        //             'amount' => $b['price'] * $b['num'],
        //             'name' => $b['title'],
        //             'products' => array(
        //                 array(
        //                     'name' => $b['title'],
        //                     'quantity' => $b['num'],
        //                     'price' => $b['price'],
        //                     'imageUrl' => '',
        //                 ),
        //             ),
        //         );
        //     }
        // }

        $data = array(
            "amount" => $params['amount'],
            "currency" => $params['currency'],
            "orderId" => $params['orderId'],
            "packages" => array(
                array(
                    "id" => 1,
                    "amount" => $params['amount'],
                    "name" => $params['productName'],
                    'products' => array(
                        array(
                            'name' => $params['productName'],
                            'quantity' => 1,
                            'price' => $params['amount'],
                            'imageUrl' => "",
                        ),
                    ),
                )
            ),
            "redirectUrls" => array(
                'confirmUrl' => $params['confirmUrl'],
                'cancelUrl' => MAIN_SITE . '/line-pay/cancel',
            )
        );





//            print_pre($data);
        //            exit();
               // print_pre($data);
               // exit;

        $linePay = $this->lineSdk();
        $response = $linePay->request($data);
        if (!$response->isSuccessful()) {
//            throw new \Exception("Code {$response['returnCode']}: {$response['returnMessage']}");
            $this->assign('msg', "Code {$response['returnCode']}: {$response['returnMessage']}");
            $this->display('payFail');
            exit;
        }

        redirect($response->getPaymentUrl());
        exit;

        $curl = curl_init();
        die($url);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);

        $nonce = time();
//        echo(C('Line.pay_channel_secret') . '/v3/payments/request' . json_encode($data) . $nonce);
        $sign = base64_encode(hash_hmac('sha256', (C('Line.pay_channel_secret') . '/v3/payments/request' . json_encode($data) . $nonce), C('Line.pay_channel_secret')));
        $header = array(
            'Content-Type: application/json',
            'X-LINE-ChannelId: ' . C('Line.pay_channel_id'),
            'X-LINE-Authorization-Nonce: ' . $nonce,
            'X-LINE-Authorization: ' . $sign,
        );
//        die(C('Line.pay_channel_id'));
        //        $header = [
        //            'Content-Type'               => 'application/json',
        //            'X-LINE-ChannelId: ' . C('Line.pay_channel_id'),
        //            'X-LINE-Authorization-Nonce' => $nonce,
        //            'X-LINE-Authorizatione'      => $sign,
        //        ];

       // print_pre($header);

        file_put_contents('a.txt', json_encode($header));

        if (!empty($data)) {
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        }
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        $output = curl_exec($curl);
        curl_close($curl);
        return $output;
    }

}
