<?php

namespace app\api\controller;

use app\admin\model\Order;
use app\common\controller\Api;
use EasyWeChat\Factory;
use think\Validate;
use function EasyWeChat\Kernel\Support\generate_sign;
use think\Log;
/**
 * 支付接口
 */
class Pay extends Api
{
    protected  $noNeedLogin = ['payOrderNotify','purchaseNotify'];
    protected $noNeedRight = ['*'];
    protected $uid = '';//token存贮uid
    protected $order_status = [];//订单状态
    public function _initialize()
    {
        parent::_initialize();
        $this->uid = $this->auth->getUserId();
        $this->order_status = config('verify.status');
    }

    /**
     * @ApiTitle    (支付订单)
     * @ApiSummary  (支付订单)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/pay/pay)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     *
     * @ApiParams   (name="openid", type="string", required=true, description="小程序openid")
     * @ApiParams   (name="order_sn", type="inter", required=true, description="订单号")
     *
     * @ApiParams   (name="receive_name", type="string", required=false, description="收货人")
     * @ApiParams   (name="receive_mobile", type="string", required=false, description="联系方式")
     * @ApiParams   (name="receive_address", type="string", required=false, description="收货地址")
     * @ApiParams   (name="leave_message", type="string", required=false, description="留言")
     * @ApiParams   (name="coupon_id", type="inter", required=false, description="优惠券id")
     *
     * @ApiParams   (name="discount_price", type="inter", required=false, description="优惠金额")
     * @ApiParams   (name="total_price", type="inter", required=false, description="实付总金额")
     *
     *
     */
    public function pay(){
        if($this->request->isPost()){
            $data = $this->request->post();
            $rule = config('verify.pay');
            $validate = new Validate($rule['rule'],$rule['msg']);
            if (!$validate->check($data)) {
                $this->error($validate->getError());
            }

            $order_sn = $data['order_sn'];
            $openid = $data['openid'];

            $ffg_host = config('verify.ffg_host');
            $status = $this->order_status;
            //支付订单
            $res = Common::findSoftWhereData('order',['uid'=>$this->uid,'order_sn'=>$order_sn,'status'=>$status[0]],'id,total_price');
            if(!$res){
                $this->error('无效的订单');
            }

            //检测库存
            $order_goods = Common::selectSoftWhereData('ogoods',['o_id'=>$res['id']],'id,g_id goods_id,style,goods_number');
            $check_stock = Common::checkPayStock($order_goods);
            if(!$check_stock){
                $this->error($check_stock);
            }


            $orderModel = new Order();
            $pay_order_sn = Common::genPayOrderSn('pay');//支付订单号
            //更新订单的支付订单号
            $arr = [];
            $arr['pay_order_sn'] = $pay_order_sn;
            if(isset($data['receive_name']) && !empty($data['receive_name'])){
                //收货人
                $arr['receive_name'] = $data['receive_name'];
            }
            if(isset($data['receive_mobile']) && !empty($data['receive_mobile'])){
                //收货电话
                $arr['receive_mobile'] = $data['receive_mobile'];
            }
            if(isset($data['receive_address']) && !empty($data['receive_address'])){
                //收货地址
                $arr['receive_address'] = $data['receive_address'];
            }
            if(isset($data['leave_message']) && !empty($data['leave_message'])){
                //留言
                $arr['leave_message'] = $data['leave_message'];
            }
            if(isset($data['coupon_id']) && !empty($data['coupon_id'])){
                //优惠券id
                $arr['coupon_id'] = $data['coupon_id'];
            }
            if(isset($data['discount_price']) && !empty($data['discount_price'])){
                //优惠价格
                $arr['discount_price'] = $data['discount_price'];
            }
            if(isset($data['total_price']) && !empty($data['total_price'])){
                //支付总金额
                $arr['total_price'] = $data['total_price'];
                //支付金额为0,直接更新为支付成功
                if($data['total_price'] == 0){
                    $arr['status'] = $status[2];
                    $res1 = $orderModel->where(['order_sn'=>$order_sn,'uid'=>$this->uid])->update($arr);
                    if($res1){
                        $res2 = Common::findSoftWhereData('order',['order_sn'=>$order_sn,'uid'=>$this->uid],'id order_id');
                        if($res2){
                            Common::paySuccess($pay_order_sn);
                            $this->success('成功',['order_id'=>$res2['order_id']]);
                        }else{
                            $this->error('未查到订单');
                        }
                    }else{
                        $this->error('失败');
                    }
                }
            }


            //创建支付对象
            $config = config('verify.wx_pay');
            $app = Factory::payment($config);
            $result = $app->order->unify([
                'body' => 'VIVAKOOL非凡谷商品',
                'out_trade_no' => $pay_order_sn,//支付订单号
//                'total_fee' => $res['total_price']*100,//单位分
                'total_fee' => 1,//单位分
                'notify_url' => $ffg_host.'/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']);

                $res1 = $orderModel->where(['order_sn'=>$order_sn,'uid'=>$this->uid])->update($arr);
                if($res1){
                    $res2 = Common::findSoftWhereData('order',['order_sn'=>$order_sn,'uid'=>$this->uid],'id order_id');
                    $this->success('成功',['data'=>$params,'order_id'=>$res2['order_id']]);
                }else{
                    $this->error('失败');
                }
            }
            $this->error($result['err_code_des']);
        }else{
            $this->error('请求方式错误');
        }
    }

    /**
     * 支付订单回调
     * @ApiInternal
     */
    public function payOrderNotify(){
        $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') {
                    //支付成功,更新订单号,销量增加1
                    Common::paySuccess($message['out_trade_no']);
                }elseif($message['result_code'] === 'FAIL') {
                    //支付失败
                }
            } else {
                return $fail('通信失败,请稍后再通知我');
            }
            return true; // 返回处理完成
        });
        $response->send();
    }

    /**
     * @ApiTitle    (立即购买)
     * @ApiSummary  (立即购买)
     * @ApiMethod   (POST)
     * @ApiRoute    (/api/pay/purchase)
     * @ApiHeaders  (name=token, type=string, required=true, description="请求的Token")
     *
     * @ApiParams   (name="receive_name", type="string", required=true, description="收货人")
     * @ApiParams   (name="receive_mobile", type="string", required=true, description="联系方式")
     * @ApiParams   (name="receive_address", type="string", required=true, description="收货地址")
     * @ApiParams   (name="openid", type="string", required=true, description="小程序openid")
     * @ApiParams   (name="goods_id", type="string", required=true, description="商品id(多个以逗号隔开,如:1,3,4)")
     * @ApiParams   (name="price", type="string", required=true, description="商品价格(多个以逗号隔开,如:100,10,200)")
     * @ApiParams   (name="goods_number", type="string", required=true, description="商品数量(多个以逗号隔开,如:10,10,10)")
     * @ApiParams   (name="style", type="string", required=true, description="商品款式(多个以逗号隔开,如:‘款式1,款式2,款式3’)")
     * @ApiParams   (name="leave_message", type="string", required=false, description="留言")
     * @ApiParams   (name="coupon_id", type="inter", required=false, description="优惠券id")
     *
     * @ApiParams   (name="total_goods_price", type="inter", required=true, description="商品总金额")
     * @ApiParams   (name="discount_price", type="inter", required=true, description="优惠金额")
     * @ApiParams   (name="total_expense_price", type="inter", required=true, description="运费总金额")
     * @ApiParams   (name="total_price", type="inter", required=true, description="实付总金额")
     */
    public function purchase(){
        if($this->request->isPost()){
            $data = $this->request->post();

            $rule = config('verify.purchase');
            $validate = new Validate($rule['rule'],$rule['msg']);
            if (!$validate->check($data)) {
                $this->error($validate->getError());
            }

            //检测库存
            $goods_id_s = explode(',',$data['goods_id']);
            $price_s = explode(',',$data['price']);
            $goods_number_s = explode(',',$data['goods_number']);
            $style_s = explode(',',$data['style']);
            //合并数组
            $key = ['goods_id','price','goods_number','style'];
            $res_goods = Common::array_merge_more($key,$goods_id_s,$price_s,$goods_number_s,$style_s);
            $check_stock = Common::checkPayStock($res_goods,$goods_id_s);
            if(!$check_stock){
                $this->error($check_stock);
            }

            //支付金额为0,直接更新为支付成功
            $pay_order_sn = Common::genPayOrderSn('pay');//支付订单号
            if($data['total_price'] == 0){
                //写入订单
                $status = config('verify.status');
                $res = Common::createOrder($data,$pay_order_sn,$this->uid,$status[2]);
                if($res){
                    Common::paySuccess($pay_order_sn);
                    $this->success('成功',['order_id'=>$res['order_id']]);
                }
            }


            //创建支付对象
            $config = config('verify.wx_pay');
            $app = Factory::payment($config);
            $ffg_host = config('verify.ffg_host');
            $result = $app->order->unify([
                'body' => 'VIVAKOOL非凡谷商品',
                'out_trade_no' => $pay_order_sn,//支付订单号
//                'total_fee' => $data['total_price']*100,//单位分
                'total_fee' => 1,//单位分
                'notify_url' => $ffg_host.'/api/pay/purchaseNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid' => $data['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']);
                //写入订单
                $res = Common::createOrder($data,$pay_order_sn,$this->uid);
                if($res){
                    $this->success('成功',['data'=>$params,'order_id'=>$res['order_id']]);
                }
                $this->error('创建订单失败');
            }
            $this->error($result['err_code_des']);
        }else{
            $this->error('请求方式错误');
        }
    }

    /**
     * 立即购买回调
     * @ApiInternal
     */
    public function purchaseNotify(){
        $config = config('verify.wx_pay');
        $app = Factory::payment($config);
        Log::info(1111);
        $response = $app->handlePaidNotify(function($message, $fail){

            Log::info($message);
            //return_code 表示通信状态
            if ($message['return_code'] === 'SUCCESS') {
                if ($message['result_code'] === 'SUCCESS') {
                    //支付成功,更新订单号,销量增加1
                    Common::paySuccess($message['out_trade_no']);
                }elseif($message['result_code'] === 'FAIL') {
                    //支付失败,好像有问题
                }
            } else {
                return $fail('通信失败,请稍后再通知我');
            }
            return true; // 返回处理完成
        });
        $response->send();
    }

}