<?php

namespace App\Http\Service;


use App\Http\Dao\GameDao;
use App\Http\Dao\GameUserDao;
use App\Http\Dao\OrderDao;
use App\Http\Manager\SdkManager;
use App\Utils\Rsa;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use RuntimeException;
use WpOrg\Requests\Requests;

class PayService
{

    private $orderDao;

    public function __construct()
    {
        $this->orderDao = new OrderDao();
    }

    /**
     * 创建订单,返回订单号
     * @param array $params
     * @return array
     */
    public function createOrder(array $params): array
    {
        $model = DB::table("app_order");
        // 查询cp订单号是否有重复情况
        $orderInfo = $model->where(['cp_order_id' => $params['cp_order_id'], 'appid' => $params['app_id']])->first();
        if ($orderInfo) {
            return error("禁止重复下单");
        }
        // 检查参数
        if (!is_numeric($params['money']) || $params['money'] < 1) {
            return error("订单金额的格式类型不正确");
        }
        if (empty($params['app_id']) || empty($params['money']) || empty($params['uid'])) {
            return error("提交参数异常!");
        }
        //获取游戏表配置
        $gameInfo = DB::table("app_games_config")
            ->where(['app_id' => $params['app_id']])->first();
        if (is_null($gameInfo)) {
            return error('该游戏配置不存在,app_id:' . $params['app_id']);
        }
        // 获取渠道表配置
        $verInfo = DB::table("app_ver_game as avg")
            ->leftJoin('app_ver as av', 'avg.ver', '=', 'av.ver_class')
            ->where(['app_id' => $params['app_id']])->first();
        if (is_null($verInfo)) {
            return error('该游戏渠道没配置,app_id:' . $params['app_id']);
        }
        // 查找融合用户信息
        $userInfo = DB::table('app_member')->where(['uid' => $params['uid']])->first();
        // 入库
        $orderId = $this->createOrderId();
        $insertData = [
            'uid' => $params['uid'],
            'order_id' => $orderId,
            'cp_order_id' => $params['cp_order_id'],
            'veruniqid' => $userInfo->veruniqid,
            'ver' => $verInfo->ver_code,
            'appid' => $params['app_id'],
            'server_id' => $params['server_id'],
            'server_name' => $params['server_name'],
            'role_id' => $params['role_id'],
            'money' => $params['money'],
            'role_name' => htmlspecialchars($params['role_name']),
            'role_level' => $params['role_level'],
            'subject' => $params['pname'],
            'extra_info' => $params['extend'] ?? '',
            'currency_type' => $params['currency_type'] ?? 'CNY',
            'create_time' => date('Y-m-d H:i:s')
        ];
        $model->insert($insertData);
        // 走一下渠道的下单接口,如果部分渠道没有,则返回空
        $sdkManager = new SdkManager();
        $channel_order_id = $sdkManager->createOrder($verInfo, $gameInfo, $params);
        if($channel_order_id){
            $model->where(['order_id'=>$orderId])->update(['channel_order_id'=>$channel_order_id]);
        }
        return success('success',['order_id' => $channel_order_id ?: $orderId]);
    }

    /**
     * 生成订单号
     * @return int
     */
    private function createOrderId(): string
    {
        $datestr = date('YmdHis');
        list($usec, $sec) = explode(" ", microtime());
        $ustr = (float)$usec*1000000;
        $ustr = (string)$ustr;
        $datestr .= $ustr;
        $pfix = env('APIORDER_FIX','');
        return $pfix.$datestr;
    }

    /**
     * 二次确认订单,通过则返回订单状态
     * @param array $params
     * @return array
     */
    public function confirmOrder(array $params)
    {
        $orderInfo = DB::table('app_order')->where(['order_id' => $params['order_id'], 'status' => 0])->first();
        if (is_null($orderInfo)) {
            return error('订单状态异常,请重新下单!');
        }
        // 参数校验
        if ($orderInfo->money != $params['money'] || $orderInfo->uid != $params['uid']) {
            return error('订单金额异常!');
        }
        return success('success',['order_id' => $orderInfo->order_id,'status'=>$orderInfo->status]);
    }

    /**
     * 渠道回调,带 appid + 渠道号 参数
     * @param array $params
     * @return array
     */
    public function verBack(array $params)
    {
        //获取游戏表配置
        $gameInfo = DB::table("app_games_config")
            ->where(['app_id' => $params['app_id']])->first();
        if (is_null($gameInfo)) {
            return error('该游戏配置不存在,app_id:' . $params['app_id']);
        }
        // 获取渠道表配置
        $verInfo = DB::table("app_ver_game as avg")
            ->leftJoin('app_ver as av', 'avg.ver', '=', 'av.ver_class')
            ->where(['app_id' => $params['app_id'], 'ver_code' => $params['ver']])->first();
        if (is_null($verInfo)) {
            return error('该游戏渠道没配置,ver_code:' . $params['ver']);
        }
        // 渠道标识就是类名称
        $sdkManager = new SdkManager();
        // 返回渠道订单号+订单金额[单位元]
        $payInfo = $sdkManager->pay($verInfo, $gameInfo, $params);
        if (!isset($payInfo['order_id']) && !isset($payInfo['money'])) {
            return $payInfo['result'];
        }
        $orderModel = DB::table('app_order');
        // 更新回调时间+金额
        $orderModel->where(['order_id' => $payInfo['order_id']])->update(['status' => 1, 'amount'=>$payInfo['money'],'channel_order_id'=>$payInfo['channel_order_id'],'dateline' => time()]);
        // 保存回调日志
        DB::table('app_callback_log')->insert([
            'order_id' => $payInfo['order_id'],
            'requrl' => request()->fullUrl(),
            'reqparams' => var_export(request()->post(),true),
            'reqresult' => var_export($payInfo,true),
            'reqtime' => time(),
        ]);
        // 获取订单信息
        $orderInfo = $orderModel->where(['order_id' => $payInfo['order_id']])->first();
        // 通知CP发货,组装post参数,并签名
        $post_params = [
            'order_id' => $orderInfo->order_id,
            'good_name' => $orderInfo->subject,
            'cp_order_id' => $orderInfo->cp_order_id,
            'uid' => $orderInfo->uid,
            'money' => $orderInfo->money,
            'app_id' => $orderInfo->appid,
            'service_id' => $orderInfo->server_id,
            'service_name' => $orderInfo->server_name,
            'role_id' => $orderInfo->role_id,
            'role_name' => $orderInfo->role_name,
            'time' => time(),
            'pay_status' => $orderInfo->status,
            'extend' => $orderInfo->extra_info,
        ];
        ksort($params);
        $signStr = http_build_query($params)."&paykey=".$gameInfo->paykey;
        $params['sign'] = md5($signStr);
        $response = Requests::post($gameInfo->send_url,['Accept' => 'application/json'],$post_params)->body;
        $response_arr = json_decode($response,true);
        if($response_arr['code'] === 200) {
            $orderModel->where(['order_id' => $payInfo['order_id']])->update(['gstatus' => 1]);
        }
        // 返回渠道要求返回的提示 成功|失败
        return $payInfo['result'];
    }

}