<?php

namespace Server\payment\app;

use App\Services\AccountService;
use App\Utils\WeAccount;
use Server\payment\PaymentService;

class WechatController extends PaymentService {

    public function main(){
        global $_GPC, $_W;
        if (!empty($_GPC['params'])){
            $params = @json_decode(base64_decode($_GPC['params']), true);
            if (!empty($params)){
                $_GPC['tid'] = $params['tid'];
            }
        }
        $paylog = $this->queryBuild($params);
        if (empty($paylog)) return $this->error("找不到该支付记录");
        if($_GPC['done'] == '1') {
            if(!empty($paylog['status'])) {
                return $this->Notify('wechat', [
                    "out_trade_no"=>$paylog['uniontid']
                ],'return');
            }
        }
        if ($paylog['status']!=0){
            return $this->error("该订单".$this->states[$paylog['status']]);
        }
        pdo_update($this->tablePayLog, array('type'=>'wechat'), array('plid'=>$paylog['plid']));
        if ($this->is_weixin(true)){
            if (!empty($_W['openid']) && !is_numeric($_W['openid'])){
                pdo_update($this->tablePayLog, array("openid"=>$_W['openid'], "type"=>"wechat"), array('plid'=>$paylog['plid']));
                $paylog['openid'] = $_W['openid'];
                return $this->cash($paylog);
            }
            $ps = array(
                'tid' => $paylog['plid'],
                'uniontid' => $paylog['uniontid'],
                'user' => $_W['openid'],
                'fee' => $paylog['card_fee'],
                'title' => $params['title'] ? urlencode($params['title']) : $paylog['tag']
            );
            $ps['goods_tag'] = empty($params['goods_tag']) ? '' : $params['goods_tag'];
            $sl = base64_encode(json_encode($ps));
            $auth = sha1($sl . $_W['uniacid'] . $_W['config']['setting']['authkey']);
            $oauth_url = AccountService::OauthHost();
            if (!empty($oauth_url)) {
                $callback = $this->api("wechat/pay", array('auth'=>$auth, 'ps'=>$sl), 'app');
            }
            $account = WeAccount::createByUniacid($this->uniacid);
            if (!is_error($account)) {
                $forward = $account->getOauthUserInfoUrl(urlencode($callback), 'we7sid-'.$_W['session_id']);
                return redirect($forward);
            }
            return $account;
        }else{
            if (empty($this->configs['wechat']['h5_switch'])) return $this->error("暂未开放H5支付");
            $subjuct = $params['title'] ?: $paylog['tag'];
            if (empty($subjuct)) $subjuct = "在线支付{$paylog['fee']}元";
            $result = $this->WechatH5(array(
                "total_amount"=>$paylog['fee'],
                "out_trade_no"=>$paylog['uniontid'],
                "subject"=>$subjuct
            ));
            if (is_error($result)){
                return $this->error($result['message']);
            }
            if (isset($result['h5_url'])){
                pdo_update($this->tablePayLog, array('type'=>'wechat'), array('plid'=>$paylog['plid']));
                return '<title>微信支付</title><script type="text/javascript">window.top.location.href="'.$result['h5_url'].'"</script>';
            }
            return $this->error($result['message']);
        }
    }

    public function cash($paylog, $subject=""){
        if(empty($this->configs['wechat'])) {
            return $this->error('没有设定支付参数.');
        }

        if (empty($subject)){
            $subject = $paylog['tag'] ?: "在线支付";
        }
        $options = [
            "openid"=>$paylog['openid'],
            "subject"=>\Str::limit($subject, 26),
            "out_trade_no"=>$paylog['uniontid'],
            "total_amount"=>$paylog['fee']
        ];
        try {
            $wOpt = $this->WechatCreate($options);
        }catch (Exception $exception){
            return $this->error($exception->getMessage());
        }

        if (is_error($wOpt)) {
            return $wOpt;
        }
        if (empty($wOpt['package'])){
            return $this->error('发起支付失败');
        }
        $html = <<<EOF
        <script type="text/javascript">
            document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
                WeixinJSBridge.invoke('getBrandWCPayRequest', {
                    'appId' : '{$wOpt['appId']}',
                    'timeStamp': '{$wOpt['timeStamp']}',
                    'nonceStr' : '{$wOpt['nonceStr']}',
                    'package' : '{$wOpt['package']}',
                    'signType' : '{$wOpt['signType']}',
                    'paySign' : '{$wOpt['paySign']}'
                }, function(res) {
                    if(res.err_msg === 'get_brand_wcpay_request:ok') {
                        location.search += '&done=1';
                    } else {
                        console.log('启动微信支付失败, 请检查你的支付参数. 详细错误为: ' + res.err_msg);
                        history.go(-1);
                    }
                });
            }, false);
        </script>
EOF;
        return $html;
    }

    public function pay(){
        global $_GPC, $_W;
        $sl = $_GPC['ps'];
        $payopenid = trim($_GPC['payopenid']);
        $params = @json_decode(base64_decode($sl), true);
        $log = $this->getone($params['tid']);
        if($_GPC['done'] == '1') {
            $result =  $this->Notify('wechat', ["out_trade_no"=>$log['uniontid']], 'return');
            if (is_error($result)){
                return $this->error($result['message']);
            }
            if($result){
                return $this->success('支付成功');
            }else{
                return $this->error('支付失败，请重试');
            }
        }

        if(!empty($log) && $log['status'] != '0') {
            return $this->error('该订单已支付或已取消');
        }

        $auth = sha1($sl . $log['uniacid'] . $_W['config']['setting']['authkey']);
        if($auth != $_GPC['auth']) {
            return $this->error('参数传输错误.');
        }

        if (!empty($_GPC['code']) && empty($payopenid)) {
            $proxy_pay_account = WeAccount::createByUniacid($this->uniacid);
            $oauth = $proxy_pay_account->getOauthInfo($_GPC['code']);
            if (!empty($oauth['openid'])) {
                $payopenid = $oauth['openid'];
            }
        }

        if (empty($payopenid)){
            $payopenid = $_W['openid'];
        }

        if (empty($payopenid)){
            return $this->error('用户未授权');
        }

        $_W['uniacid'] = $log['uniacid'];
        $log['openid'] = $payopenid;
        pdo_update($this->tablePayLog, array("openid"=>$payopenid,'type'=>'wechat'), array('plid'=>$log['plid']));
        return $this->cash($log);
    }

    public function query(){
        global $_GPC;
        $result = $this->WechatQuery(trim($_GPC['out_trade_no']));
        if (is_error($result)) return $result;
        if ($result['trade_state']!='SUCCESS') return $this->error($result['trade_state_desc']."({$result['trade_state']})");
        try {
            $this->Notify('wechat', ['out_trade_no'=>$result['out_trade_no']]);
        }catch (Exception $exception){
            //Todo something
        }
        return $this->success("支付成功！", referer());
    }

    public function is_weixin($authorized=false){
        global $_W;
        if (empty($_SERVER['HTTP_USER_AGENT']) || strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') === false && strpos($_SERVER['HTTP_USER_AGENT'], 'Windows Phone') === false) {
            return false;
        }
        if ($authorized && $_W['account']['level']!=4) return false;
        return true;
    }

}
