<?php
declare (strict_types=1);

namespace app\api\controller\v1;
// +----------------------------------------------------------------------
// | [ WE CAN DO IT MORE SIMPLE  ]
// +----------------------------------------------------------------------
// | Copyright (c) 2018-2020 rights reserved.
// +----------------------------------------------------------------------
// | Author: TABLE ME
// +----------------------------------------------------------------------
// | Date: 2020-08-31 15:05
// +----------------------------------------------------------------------
use app\BaseController;
use app\model\api\Member;
use app\model\api\Order;
use app\model\api\PayTrade;
use app\model\api\Recharge;
use app\Request;
use EasyWeChat\Factory;
use library\lib\weixina;
use library\services\UtilService;
use think\db\exception\DbException;
use think\db\exception\PDOException;
use think\Exception;
use think\facade\Db;

class Weixin extends BaseController
{
    public function test()
    {
        $user1 = Db::name("member")->where('i_uid',1655)
            ->where('regtime', 'between', [1614528000, 1617206400])
            ->where('last_con_time','<>',0)
            ->column('uid');
        $user2 = Db::name("member")->where('i_uid',1655)
            ->where('regtime', 'between', [1617206400, 1619798400])
            ->where('last_con_time','<>',0)
            ->column('uid');
        $user = array_merge($user1,$user2);
        $order = Db::name("order_info")->alias('s')->join('order o',"o.id = s.o_id")->where('s.uid', 'in', $user)
            ->where('o.pay_time', 'between', [1617206400, 1619798400])->count();
        dump($order);
    }

    /**
     * @param Request $request
     */
    public function result(Request $request)
    {
        $state = trim($request->get('state'));
        $code = trim($request->get('code'));
        if (empty($state)) {
            exit('error');
        }
        $weixinA = new weixina;
        $data = $weixinA->oauth_reuslt($code);
        if (!empty($data['access_token'])) {
            $userInfo = $weixinA->userinfo($data['access_token']);
            $userInfo['access_token'] = $data['access_token'];
            $userInfo['expires_in'] = $data['expires_in'];
            $userInfo['time'] = time();
            cookie("weix_userinfo", serialize($userInfo));
            $url = setParam(cookie('w_url'), ['data' => json_encode($userInfo, \JSON_UNESCAPED_UNICODE)]);
            redirect($url)->send();
        } else {
            exit('微信授权登录失败，关闭页面重新，重新扫描！');
        }
    }

    public function pay(Request $request)
    {
        [$orderId, $from] = UtilService::getMore([
            ['order_id', '', 'empty', '参数错误'],
            ['from', '', 'empty', '参数错误'],
        ], $request, true);
        $order = Order::where('order_id', $orderId)->find();
        if (empty($order)) {
            return app('json')->fail('找不到订单信息');
        }
        //订单已付款
        if (!empty($order['is_pay'])) {
            return app('json')->fail('订单已经支付成功');
        }
        $config = [
            // 必要配置
            'app_id' => 'wxa9130b2090dfb130',
            'mch_id' => '1582297191',
            'key' => 'fgwhdf323gewdsd83ewewhd56wrr333g',   // API 密钥
            'notify_url' => '',
        ];
        $app = Factory::payment($config);
        if ($from == 'weixin') {
            $result = $app->order->unify([
                'body' => '支付订单',
                'out_trade_no' => $order['order_id'],
                'total_fee' => $order['all_price'] * 100,
                'notify_url' => 'https://api.lipinwawa.com/api/weixin/notify', // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                'openid' => 'olkUP6fDbDSQKjidMQyeQ_0TO3XE',
            ]);
            $jssdk = $app->jssdk;
            $jsConfig = $jssdk->bridgeConfig($result['prepay_id'], false);
            $json['result'] = $jsConfig;
            $json['type'] = 'WECHAT_PAY';
        } else {
            $result = $app->order->unify([
                'body' => '支付订单',
                'out_trade_no' => $order['order_id'],
                'total_fee' => $order['all_price'] * 100,
                'notify_url' => 'https://api.lipinwawa.com/api/weixin/notify', // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                'trade_type' => 'MWEB' // 请对应换成你的支付方式对应的值类型
            ]);
            $jssdk = $app->jssdk;
            $jsConfig = $jssdk->bridgeConfig($result['prepay_id'], false);
            $json['result'] = $jsConfig;
            $json['type'] = 'WECHAT_H5_PAY';
        }
        return app('json')->success($json);
    }

    public function recharge(Request $request)
    {
        [$money, $from, $code] = UtilService::getMore([
            ['money', '', 'empty', '请选择充值金额'],
            ['from', '', 'empty', '参数错误'],
            ['code', '']
        ], $request, true);
        try {
            Recharge::beginTrans();
            $recharge = new Recharge();
            $d = [];
            $d['order_id'] = 'RE' . time() . sprintf('%04d', rand(0, 1000)) . $request->user['uid'];
            $d['v'] = $money;
            $d['status'] = '0';
            $d['time'] = time();
            $d['sassid'] = $request->site['sassid'];
            $d['uid'] = $request->user['uid'];
            $recharge->insert($d);
            //生成支付凭证
            (new PayTrade)->mkTrade([
                'out_trade_no' => $d['order_id'],
                'uid' => $request->user['uid'],
                'tag' => 'wxpay',
                'type' => 'recharge',
                'money' => $money,
                'content' => '会员充值' . $d['v'] . '元',
                'sassid' => $request->site['sassid'],
            ]);
            Recharge::commitTrans();
            $config = [
                // 必要配置
                'app_id' => 'wxa9130b2090dfb130',
                'mch_id' => '1582297191',
                'key' => 'fgwhdf323gewdsd83ewewhd56wrr333g',   // API 密钥
                'notify_url' => '',
            ];
            $app = Factory::payment($config);
            if ($from == 'weixin') {
                if ($code) {
                    $weixinA = new weixina;
                    $token = $weixinA->oauth_reuslt($code);
                    $openid = $token['openid'];
                    (new Member)->where('uid', $request->user['uid'])->save(['openid' => $openid]);
                } else {
                    $openid = $request->user['openid'];
                }
                $result = $app->order->unify([
                    'body' => '充值余额',
                    'out_trade_no' => $d['order_id'],
                    'total_fee' => $money * 100,
                    'notify_url' => 'https://api.lipinwawa.com/api/weixin/notify', // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                    'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
                    'openid' => $openid,
                ]);
                $jssdk = $app->jssdk;
                $jsConfig = $jssdk->bridgeConfig($result['prepay_id'], false);
                $json['result'] = $jsConfig;
                $json['type'] = 'WECHAT_PAY';
            } else {
                $result = $app->order->unify([
                    'body' => '充值余额',
                    'out_trade_no' => $d['order_id'],
                    'total_fee' => $money * 100,
                    'notify_url' => 'https://api.lipinwawa.com/api/weixin/notify', // 支付结果通知网址，如果不设置则会使用配置里的默认地址
                    'trade_type' => 'MWEB' // 请对应换成你的支付方式对应的值类型
                ]);
                $json['result'] = $result;
                $json['type'] = 'WECHAT_H5_PAY';
            }
            return app('json')->success($json);
        } catch (DbException $db) {
            Recharge::rollbackTrans();
            return app('json')->fail("充值失败，请联系客服人员");
        }
    }

    /**
     * @throws \Exception
     */
    public function notify()
    {
        // 获取微信回调的数据
        $notifiedData = file_get_contents('php://input');
        //XML格式转换
        $xmlObj = simplexml_load_string($notifiedData, 'SimpleXMLElement', LIBXML_NOCDATA);
        $xmlObj = json_decode(json_encode($xmlObj), true);
        // 当支付通知返回支付成功时
        if ($xmlObj['return_code'] == "SUCCESS" && $xmlObj['result_code'] == "SUCCESS") {
            try {
                $data['appid'] = $xmlObj['appid'];
                $data['bank_type'] = $xmlObj['bank_type'];
                $data['cash_fee'] = $xmlObj['cash_fee'];
                $data['fee_type'] = $xmlObj['fee_type'];
                $data['is_subscribe'] = $xmlObj['is_subscribe'];
                $data['mch_id'] = $xmlObj['mch_id'];
                $data['nonce_str'] = $xmlObj['nonce_str'];
                $data['openid'] = $xmlObj['openid'];
                $data['out_trade_no'] = $xmlObj['out_trade_no'];
                $data['result_code'] = $xmlObj['result_code'];
                $data['return_code'] = $xmlObj['return_code'];
                $data['sign'] = $xmlObj['sign'];
                $data['time_end'] = $xmlObj['time_end'];
                $data['total_fee'] = $xmlObj['total_fee'];
                $data['trade_type'] = $xmlObj['trade_type'];
                $data['transaction_id'] = $xmlObj['transaction_id'];
                $res = Db::name('wx_notify')->insertGetId($data);
                if ($res) {
                    $payTrade = new PayTrade();
                    $data2 = $payTrade->where('out_trade_no', $xmlObj['out_trade_no'])->find();
                    if (empty($data2)) {
                        echo 'SUCCESS';
                        exit;
                    }
                    if ($data2['status'] == 1) {
                        echo 'SUCCESS';
                        exit;
                    }
                    if ($data2['type'] == 'recharge') {
                        $recharge = new Recharge();
                        $recharge->rechargeSuccess($xmlObj['out_trade_no']);
                    }
                    $payTrade->where('id', $data2['id'])->save(['status' => 1, 'pay_time' => time()]);
                    echo 'SUCCESS';
                    exit;
                }
            } catch (Exception $e) {
                @file_put_contents('error.txt', '[' . date('Y-m-d') . ']Exception:' . json_encode(['Msg' => $e->getMessage(), 'File' => $e->getFile(), 'Line' => $e->getLine(), 'Trance' => $e->getTrace()]) . PHP_EOL, FILE_APPEND);
            } catch (DbException $e) {
                @file_put_contents('error.txt', '[' . date('Y-m-d') . ']DbException:' . json_encode(['Msg' => $e->getMessage(), 'File' => $e->getFile(), 'Line' => $e->getLine(), 'Trance' => $e->getTrace()]) . PHP_EOL, FILE_APPEND);
            } catch (\Exception $e) {
                @file_put_contents('error.txt', '[' . date('Y-m-d') . ']\Exception:' . json_encode(['Msg' => $e->getMessage(), 'File' => $e->getFile(), 'Line' => $e->getLine(), 'Trance' => $e->getTrace()]) . PHP_EOL, FILE_APPEND);
            }
        }
    }

}
