<?php

namespace app\api\controller\school;

use addons\epay\library\Service;
use addons\third\model\Third;
use app\common\model\school\classes\order\Order as OrderModel;
use Exception;

use think\Log;

/**
 * 课程支付接口
 */
class Pay extends Base
{

    protected $noNeedLogin = '*';
    protected $noNeedRight = '*';
    protected $model = null;

    /**
     * 初始化操作
     * @access protected
     */
    protected function _initialize()
    {

        $this->model = new OrderModel;
        parent::_initialize();
        $this->setUrlLock();
        //判断登录用户是否是员工
    }


    /**
     * @ApiTitle( 课程第三方支付)
     * @ApiSummary(课程第三方支付（微信等支付）)
     * @ApiRoute(/api/school/pay/payment)
     * @ApiMethod(POST)
     * @ApiParams(name = "order_no", type = "string",required=true,description = "订单id或订单号")
     * @ApiParams(name = "type", type = "string",required=true,description = "服务商:alipay=支付宝,wechat=微信")
     * @ApiParams(name = "platform", type = "string",required=true,description = "平台:web=PC网页支付,wap=H5手机网页支付,app=APP支付,scan=扫码支付,mp=微信公众号支付,miniapp=微信小程序支付")
     * @ApiParams(name = "openid", type = "string",required=false,description = "用户openid(非必填)")
     * @ApiReturn({
     *
     *})
     */
    public function payment()
    {
        $order_no = $this->request->post('order_no/s');
        $type = $this->request->post('type/s');
        $method = $this->request->post('platform/s');
        $openid = $this->request->post('openid/s', "");
        $platform = $method;
        try {
            //订单支付前校验
            $this->model->checkPay($order_no,$type);
            $order = OrderModel::where('order_no', $order_no)->find();
            $amount = $order["totalprice"];
        } catch (\Exception $e) {
            $this->error($e->getMessage());
        }





        if (!$amount || $amount < 0) {
            $this->error("支付金额必须大于0");
        }

        if (!$type || !in_array($type, ['alipay', 'wechat'])) {
            $this->error("支付类型不能为空");
        }

        if (in_array($method, ['miniapp', 'mp']) && !$openid) {

            // 微信公众号，小程序支付，必须有 openid
                    if (isset($openid) && $openid) {
                        // 如果传的有 openid
                    } else {
                        // 没有 openid 默认拿下单人的 openid
                        $oauth = Third::where([
                            'user_id' => $order->user_id,
                            'platform' => $type,
                            'apptype' => $platform
                        ])->find();

                        $openid = $oauth ? $oauth->openid : '';
                    }

                    if (!$openid) {
                        // 缺少 openid
                        $this->error("授权过期，请您重新授权登录");
                    }
        }

        //订单号
        $out_trade_no = $order_no;

        //订单标题
        $title = '课程订单['.$out_trade_no."]支付";

        //回调链接
        $notifyurl = $this->request->root(true) . '/api/school/pay/notifyx/paytype/' . $type. '/platform/' . $method;
        $returnurl = $this->request->root(true) . '/api/school/pay/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;

        $response = Service::submitOrder($amount, $out_trade_no, $type, $title, $notifyurl, $returnurl, $method, $openid);

        $this->success('查询成功', ["paydata"=>$response]);

//        return $response;
    }

    /**
     * @ApiTitle( 第三方支付支付成功回调)
     * @ApiSummary(第三方支付成功回调)
     * @ApiRoute(/api/school/pay/notifyx)
     * @ApiMethod(GET)
     * @ApiReturn({
     *
     *})
     */
    public function notifyx()
    {
        $paytype = $this->request->param('paytype');
        $platform = $this->request->param('platform');
        $pay = Service::checkNotify($paytype);
        if (!$pay) {
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
        }
        $payment = $paytype;
        // 获取回调数据，V3和V2的回调接收不同
        $data = Service::isVersionV3() ? $pay->callback() : $pay->verify();



        Log::write('notifyx-result:'. json_encode($data));

        $out_trade_no = $data['out_trade_no'];
        $out_refund_no = $data['out_biz_no'] ?? '';



        // 判断是否是支付宝退款（支付宝退款成功会通知该接口）
        if ($paytype == 'alipay'    // 支付宝支付
            && $data['notify_type'] == 'trade_status_sync'      // 同步交易状态
            && $data['trade_status'] == 'TRADE_CLOSED'          // 交易关闭
            && $out_refund_no                                   // 退款单号
        ) {
            // 退款回调

//            $this->refundFinish($out_trade_no, $out_refund_no,$platform);

            return $pay->success()->send();
        }






        // 判断支付宝微信是否是支付成功状态，如果不是，直接返回响应
        if ($payment == 'alipay' && $data['trade_status'] != 'TRADE_SUCCESS') {
            // 不是交易成功的通知，直接返回成功
            return $pay->success()->send();
        }
        if ($payment == 'wechat' && ($data['result_code'] != 'SUCCESS' || $data['return_code'] != 'SUCCESS')) {
            // 微信交易未成功，返回 false，让微信再次通知
            return false;
        }


        try {
            //微信支付V3返回和V2不同
            if (Service::isVersionV3() && $paytype === 'wechat') {
                $data = $data['resource']['ciphertext'];
                $data['total_fee'] = $data['amount']['total'];
            }

            \think\Log::record($data);

            $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
            $out_trade_no = $data['out_trade_no'];

            \think\Log::record("回调成功，订单号：{$out_trade_no}，金额：{$payamount}");

            //你可以在此编写订单逻辑

            // 支付成功流程
            //获取支付金额、订单号
            $pay_fee = $payment == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;

            //你可以在此编写订单逻辑
            $order = OrderModel::getNopayOrder($out_trade_no);

            if (!$order || $order["status"] != '0') {
                // 订单不存在，或者订单已支付
                return $pay->success()->send();
            }
            $notify = [
                'order_no' => $data['out_trade_no'],
                'transaction_id' => $payment == 'alipay' ? $data['trade_no'] : $data['transaction_id'],
                'notify_time' => date('Y-m-d H:i:s', strtotime($data['time_end'])),
                'buyer_email' => $payment == 'alipay' ? $data['buyer_logon_id'] : $data['openid'],
                'payment_json' => json_encode($data->all()),
                'pay_fee' => $pay_fee,
                'pay_type' => $payment,              // 支付方式
                'platform' => $platform,
            ];

            $this->model->paySuccess($order['order_no'],$notify,$pay_fee,true,true);



        } catch (Exception $e) {
            \think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
        }

        //下面这句必须要执行,且在此之前不能有任何输出
        if (Service::isVersionV3()) {
            return $pay->success()->getBody()->getContents();
        } else {
            return $pay->success()->send();
        }
    }

    /**
     * 支付返回，网页支付版本（小程序忽略）
     */
    public function returnx()
    {
        $paytype = $this->request->param('paytype');
        $out_trade_no = $this->request->param('out_trade_no');
        $pay = Service::checkReturn($paytype);
        if (!$pay) {
            $this->error('签名错误', '');
        }

        //你可以在这里定义你的提示信息,但切记不可在此编写逻辑
        $this->success("请返回网站查看支付结果", addon_url("epay/index/index"));
    }


     public function notifyRefund($callback)
    {
        $pay = $this->getPay();

        try {
            $data = $pay->verify(null, true); // 是的，验签就这么简单！

            $result = $callback($data, $pay);

            // Log::debug('Wechat notify', $data->all());
        } catch (\Exception $e) {
            // $e->getMessage();
        }

        return $result;
   }


        /**
     * 退款成功回调
     */
    public function notifyr()
    {
        Log::write('notifyreturn-comein:');

        $payment = $this->request->param('payment');
        $platform = $this->request->param('platform');

            $config = Service::getConfig('wechat');

            $notify_url = request()->domain() . '/api/school/pay/notifyr/payment/' . $payment . '/platform/' . $platform;

            $config['notify_url'] = $notify_url;
            $pay = \Yansongda\Pay\Pay::wechat($config);

        try {
            $data = $pay->verify(null, true); // 是的，验签就这么简单！

           Log::write('notifyr-result:' . json_encode($data));

           $out_refund_no = $data['out_refund_no'];
           $out_trade_no = $data['out_trade_no'];

                // 退款
           $this->refundFinish($out_trade_no, $out_refund_no,$platform);


           return $pay->success()->send();
            // Log::debug('Wechat notify', $data->all());
        } catch (\Exception $e) {
            Log::write('notifyreturn-error:' . $e->getMessage());
        }
        return $pay->success()->send();
    }


      private function refundFinish($out_trade_no, $out_refund_no,$platform) {

//        $order = Order::where('order_sn', $out_trade_no)->find();
//        $refundLog = \app\admin\model\shopro\order\RefundLog::where('refund_sn', $out_refund_no)->find();
//
//        if (!$order || !$refundLog || $refundLog->status != 0) {
//            // 订单不存在，或者订单已退款
//            return true;
//        }
//
//        $item = \app\admin\model\shopro\order\OrderItem::where('id', $refundLog->order_item_id)->find();
//
//        Db::transaction(function () use ($order, $item, $refundLog) {
//            \app\admin\model\shopro\order\Order::refundFinish($order, $item, $refundLog);
//        });
        \app\common\model\school\classes\order\ServiceOrder::refundSuccess($out_refund_no,true);
        return true;
    }



}