<?php

namespace app\api\controller;

use app\common\controller\Api;
use EasyWeChat\Factory;
use function GuzzleHttp\Promise\inspect;
use think\Db;
use app\admin\model\User;
use think\Log;
use fast\Http;
use think\Validate;
use Exception;
use function EasyWeChat\Kernel\Support\generate_sign;
/**
 * 支付接口
 */
class Pay extends Api
{
    protected $noNeedRight = ['*'];
    protected $uid = '';//token存贮uid
    protected $order_status = [];//订单状态
    public function _initialize()
    {
        parent::_initialize();
        $this->uid = $this->auth->getUserId();
    }

    /**
     * @ApiTitle    (充值支付)
     * @ApiSummary  (充值支付)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/pay/pay)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     *
     * @ApiParams   (name="order_id", type="inter", required=true, description="订单id")
     *
     */
    public function pay(){
        $rule = config('verify.path');
        if($this->request->isPost()){
            $order_id = $this->request->post('order_id');
            $openid = $this->getopenid();
            if(empty($openid)){
                $this->error(['code'=>2,'msg'=>'openid不能为空']);
            }
            $data = Db::name('toporder')->where('id',$order_id)->find();
            if($data){
                if($data['status'] == 2){
                    $this->error('该订单已支付过了');
                }else{
                    //创建支付对象
                    $config = config('verify.wx_pay');
                    $app = Factory::payment($config);
                    $result = $app->order->unify([
                        'body' => '山东航拍',
                        'out_trade_no' => $data['num'],//支付订单号
                        'total_fee' => $data['money']*100,//单位分
                        'notify_url' => $rule.'api/pay/payOrderNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
                        'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                        'openid' => $openid,
                    ]);
                    if($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS'){
                        $params = [
                            'appId'     => $config['app_id'],
                            'timeStamp' => time(),
                            'nonceStr'  => $result['nonce_str'], // 统一下单返回的随机字符串
                            'package'   => 'prepay_id='.$result['prepay_id'], // 统一下单Id
                            'signType'  => 'MD5', // 签名方法
                        ];
                        // 注意这里用的是商户平台的Key进行二次签名
                        $params['paySign'] = generate_sign($params, $config['key']);
                        $this->success('成功',$params);
                    }
                    $this->error($result['err_code_des']);
                }
            }else{
                $this->error('无效的订单');
            }
        }else{
            $this->error('请求方式错误');
        }
    }

    /**
     * @ApiTitle    (图片购买支付)
     * @ApiSummary  (图片购买支付)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/pay/picpay)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     *
     * @ApiParams   (name="order_id", type="inter", required=true, description="订单id")
     * @ApiParams   (name="type", type="inter", required=true, description="支付方式 1 为余额支付 2为微信支付")
     *
     */
    public function picpay(){
        $rule = config('verify.path');
        if($this->request->isPost()){
            $order_id = $this->request->post('order_id');
            $type = $this->request->post('type');
            if(empty($type)){
                $this->error(['code'=>2,'msg'=>'缺少必要参数']);
            }
            $openid = $this->getopenid();
            if(empty($openid)){
                $this->error(['code'=>2,'msg'=>'openid不能为空']);
            }
            $data = Db::name('order')->where('id',$order_id)->find();
            if($type == 1){
                if($data){
                    if($data['status'] == 2){
                        $this->error('该订单已支付过了');
                    }else{
                        $res = Db::name('user')
                            ->where('id',$data['user_id'])
                            ->find();
                        if($data['total'] > $res['money']){
                            $this->error(['code'=>2,'msg'=>'余额不足,请充值后重试']);
                        }
                        $money = $res['money'] - $data['total'];
                        // 启动事务
                        Db::startTrans();
                        try{
                            $arr = Db::name('user')->where('id',$data['user_id'])->update(['money'=>$money]);
                            $res = Db::name('order')->where('id',$order_id)->update(['status'=>2,'paytime'=>time()]);
                            if($res && $arr){
                                true;
                            }else{
                                $this->error('购买失败');
                            }
                            // 提交事务
                            Db::commit();
                        } catch (\Exception $e) {
                            dump($e->getMessage());
                            // 回滚事务
                            Db::rollback();
                        }
                    }
                }else{
                    $this->error('无效的订单');
                }
            }else{
                if($data){
                    if($data['status'] == 2){
                        $this->error('该订单已支付过了');
                    }else{
                        //创建支付对象
                        $config = config('verify.wx_pay');
                        $app = Factory::payment($config);
                        $result = $app->order->unify([
                            'body' => '山东航拍',
                            'out_trade_no' => $data['num'],//支付订单号
                            'total_fee' => $data['total']*100,//单位分
                            'notify_url' => $rule.'api/pay/picOrderNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
                            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                            'openid' => $openid,
                        ]);
                        if($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS'){
                            $params = [
                                'appId'     => $config['app_id'],
                                'timeStamp' => time(),
                                'nonceStr'  => $result['nonce_str'], // 统一下单返回的随机字符串
                                'package'   => 'prepay_id='.$result['prepay_id'], // 统一下单Id
                                'signType'  => 'MD5', // 签名方法
                            ];
                            // 注意这里用的是商户平台的Key进行二次签名
                            $params['paySign'] = generate_sign($params, $config['key']);
                            $this->success('成功',$params);
                        }
                        $this->error($result['err_code_des']);
                    }
                }else{
                    $this->error('无效的订单');
                }
            }
        }else{
            $this->error('请求方式错误');
        }
    }

    /**
     * @ApiTitle    (视频购买支付)
     * @ApiSummary  (视频购买支付)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/pay/videopay)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     *
     * @ApiParams   (name="order_id", type="inter", required=true, description="订单id")
     * @ApiParams   (name="type", type="inter", required=true, description="支付方式 1 为余额支付 2为微信支付")
     *
     */
    public function videopay(){
        $rule = config('verify.path');
        if($this->request->isPost()){
            $order_id = $this->request->post('order_id');
            $openid = $this->getopenid();
            if(empty($openid)){
                $this->error(['code'=>2,'msg'=>'openid不能为空']);
            }
            $type = $this->request->post('type');
            if(empty($type)){
                $this->error(['code'=>2,'msg'=>'缺少必要参数']);
            }
            $data = Db::name('order')->where('id',$order_id)->find();
            if($type == 1){
                if($data){
                    if($data['status'] == 2){
                        $this->error('该订单已支付过了');
                    }else{
                        $res = Db::name('user')
                            ->where('id',$data['user_id'])
                            ->find();
                        if($data['total'] > $res['money']){
                            $this->error(['code'=>2,'msg'=>'余额不足,请充值后重试']);
                        }
                        $money = $res['money'] - $data['total'];
                        // 启动事务
                        Db::startTrans();
                        try{
                            $arr = Db::name('user')->where('id',$data['user_id'])->update(['money'=>$money]);
                            $res = Db::name('order')->where('id',$order_id)->update(['status'=>2,'paytime'=>time()]);
                            if($res && $arr){
                                true;
                            }else{
                                $this->error('购买失败');
                            }
                            // 提交事务
                            Db::commit();
                        } catch (\Exception $e) {
                            dump($e->getMessage());
                            // 回滚事务
                            Db::rollback();
                        }
                    }
                }else{
                    $this->error('无效的订单');
                }
            }else{
                if($data){
                    if($data['status'] == 2){
                        $this->error('该订单已支付过了');
                    }else{
                        //创建支付对象
                        $config = config('verify.wx_pay');
                        $app = Factory::payment($config);
                        $result = $app->order->unify([
                            'body' => '山东航拍',
                            'out_trade_no' => $data['num'],//支付订单号
                            'total_fee' => $data['total']*100,//单位分
                            'notify_url' => $rule.'api/pay/videoOrderNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
                            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                            'openid' => $openid,
                        ]);
                        if($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS'){
                            $params = [
                                'appId'     => $config['app_id'],
                                'timeStamp' => time(),
                                'nonceStr'  => $result['nonce_str'], // 统一下单返回的随机字符串
                                'package'   => 'prepay_id='.$result['prepay_id'], // 统一下单Id
                                'signType'  => 'MD5', // 签名方法
                            ];
                            // 注意这里用的是商户平台的Key进行二次签名
                            $params['paySign'] = generate_sign($params, $config['key']);
                            $this->success('成功',$params);
                        }
                        $this->error($result['err_code_des']);
                    }
                }else{
                    $this->error('无效的订单');
                }
            }

        }else{
            $this->error('请求方式错误');
        }
    }

    //支付订单结果通知(无需调用)
    public function payOrderNotify(){
        $config = config('verify.wx_pay');
        $app = Factory::payment($config);
        $response = $app->handlePaidNotify(function($message, $fail){
            $data = Db::name('toporder')
                ->where('num',$message['out_trade_no'])
                ->find();
            //return_code 表示通信状态
            if ($message['return_code'] === 'SUCCESS') {

                if ($message['result_code'] === 'SUCCESS') {
                    //支付成功,更新订单状态
                    $toporder['status'] = 2;
                    $toporder['paytime'] = time();
                    $money = $data['money'];
                    // 启动事务
                    Db::startTrans();
                    try{
                        $res = Db::name('toporder')->where('num',$message['out_trade_no'])->update($toporder);
                        $arr = Db::name('user')->where('id',$data['user_id'])->find();
                        $list['money'] = $arr['money'] + $money;
                        $info = Db::name('user')->where('id',$data['user_id'])->update(['money'=>$list['money']]);
                        if($res && $info){
                            true;
                        }else{
                            $this->error(['code'=>2,'msg'=>'充值失败']);
                        }
                        // 提交事务
                        Db::commit();
                    } catch (\Exception $e) {
                        dump($e->getMessage());
                        // 回滚事务
                        Db::rollback();
                    }
                }else{
                    //支付失败
                    Db::name('toporder')->where('num',$message['out_trade_no'])->update(['status'=>1]);
                }
            }else{
                return $fail('通信失败,请稍后再通知我');
            }
            return true; // 返回处理完成
        });
        $response->send();
    }

    //图片支付订单结果通知(无需调用)
    public function picOrderNotify(){
        $config = config('verify.wx_pay');
        $app = Factory::payment($config);
        $response = $app->handlePaidNotify(function($message, $fail){
            //return_code 表示通信状态
            if ($message['return_code'] === 'SUCCESS') {
                if ($message['result_code'] === 'SUCCESS') {
                    //支付成功,更新订单状态
                    $toporder['status'] = 2;
                    $toporder['paytime'] = time();
                }else{
                    //支付失败
                    $toporder['status'] = 1;
                }
            }else{
                return $fail('通信失败,请稍后再通知我');
            }
            Db::name('order')->where('num',$message['out_trade_no'])->update($toporder);
            return true; // 返回处理完成
        });
        $response->send();
    }

    //视频支付订单结果通知(无需调用)
    public function videoOrderNotify(){
        $config = config('verify.wx_pay');
        $app = Factory::payment($config);
        $response = $app->handlePaidNotify(function($message, $fail){
            //return_code 表示通信状态
            if ($message['return_code'] === 'SUCCESS') {
                if ($message['result_code'] === 'SUCCESS') {
                    //支付成功,更新订单状态
                    $toporder['status'] = 2;
                    $toporder['paytime'] = time();
                }else{
                    //支付失败
                    $toporder['status'] = 1;
                }
            }else{
                return $fail('通信失败,请稍后再通知我');
            }
            Db::name('vorder')->where('num',$message['out_trade_no'])->update($toporder);
            return true; // 返回处理完成
        });
        $response->send();
    }

    //获取用户openid
    public function getopenid()
    {
        $user_id = $this->uid;
        $openid = Db::name('user')
            ->where('id',$user_id)
            ->field('openid')
            ->find();

        return $openid;
    }
}