<?php
namespace app\models\order;
use app\models\system\SystemStoreMember;
use app\models\system\SystemUserLevel;
use app\models\user\User;
use app\models\user\UserLevel;
use app\models\user\WechatUser;
use crmeb\basic\BaseModel;
use crmeb\services\AlipayService;
use crmeb\services\MiniProgramService;
use crmeb\services\SystemConfigService;
use crmeb\services\WechatService;
use crmeb\repositories\PaymentRepositories;
use crmeb\traits\ModelTrait;
use app\models\user\UserBill;
use think\facade\Log;

class Level extends BaseModel
{
    use ModelTrait;
    /**
     * 数据表主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 模型名称
     * @var string
     */
    protected $name = 'order_level';
    protected $insert = ['addtime'];
    protected static $payType = ['weixin' => '微信支付', 'yue' => '余额支付', 'ali' => '支付宝支付'];

    /**
     * 生成订单唯一id
     * @param $uid 用户uid
     * @return string
     */
    public static function getNewOrderId()
    {
        list($msec, $sec) = explode(' ', microtime());
        $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
        $orderId = 'lv' . $msectime . mt_rand(10000, 99999);
        while (self::be(['order_id' => $orderId])) $orderId = 'lv' . $msectime . mt_rand(10000, 99999);
        return $orderId;
    }

    /**
     * 创建订单
     * @param $uid
     * @param $level_id
     * @param $payType
     * @param $mark
     * @return Level|bool|\think\Model
     */
    public static function createLevelOrder($uid, $level_id, $payType,$spread_uid=0,$store_id=0)
    {
        Level::where('uid',$uid)->where('paid',0)->delete();
        self::beginTrans();
        try {
            if (!array_key_exists($payType, self::$payType)) return self::setErrorInfo('选择支付方式有误!', true);
            $userInfo = User::getUserInfo($uid);
            if (!$userInfo) return self::setErrorInfo('用户不存在!', true);
            $levelInfo = SystemUserLevel::get(['id' => $level_id, 'is_del' => 0]);
            if (!$levelInfo) return self::setErrorInfo('等级不存在', true);
            list($where['uid'],$where['level_id'],$where['pay_type'],$where['paid']) = [$uid,$level_id,$payType,0];
            $info = self::where($where)->find();
            if($info)
            {
                $order_id = self::getNewOrderId();
                self::edit(['pay_price'=>$levelInfo->money,'order_id'=>$order_id],$info['id']);
                $info['pay_price'] = $levelInfo->money;
                $info['order_id'] = $order_id;
                return $info;
            }
            $orderInfo = [
                'uid' => $uid,
                'order_id' => self::getNewOrderId(),
                'level_id' => $level_id,
                'paid' => 0,
                'is_del' => 0,
                'pay_price' => $levelInfo->money,
                'pay_type' => $payType,
                'body'     => '开通会员-'.$levelInfo->name,
                'addtime'  => time(),
                'spread_uid'=>$spread_uid,
                'store_id'=>$store_id,
            ];

            $order = self::create($orderInfo);
            if (!$order) return self::setErrorInfo('订单生成失败!');
            self::commitTrans();
            return $order;
        } catch (\PDOException $e) {
            self::rollbackTrans();
            return self::setErrorInfo('生成订单时SQL执行错误错误原因:' . $e->getMessage());
        } catch (\Exception $e) {
            self::rollbackTrans();
            return self::setErrorInfo('生成订单时系统错误错误原因:' . $e->getMessage());
        }
    }
    public static function paySuccess($orderId, $paytype = 'weixin')
    {
        $order = self::where('order_id', $orderId)->find()->toArray();
        $user = User::where('uid', $order['uid'])->find();
        if (!$user) return false;
        $res1 = self::where('order_id', $orderId)->update(['paid' => 1, 'pay_type' => $paytype, 'paytime' => time()]);//订单改为支付
        self::backBrokerage($order);
        $res2 = UserLevel::setUserLevel($order['uid'], $order['level_id'],1);
        Log::write($res2?'1':'0'.'-2', 'error');
        $res = $res1 && $res2 ;
        if($order['level_id']==1) {
            SystemStoreMember::setstorecardno($order['uid'], $order['store_id']);
        }
        $info = SystemUserLevel::find($order['level_id']);
        $user = User::where('uid',$order['uid'])->find();
        User::where('uid',$order['uid'])->inc('consumer',$order['pay_price'])->update();
        UserBill::income('开通'.$info['name'].'赠送消费券',$order['uid'],'consumer','system_add_consumer',$order['pay_price'],$info['id'],bcadd($user['consumer'],$order['pay_price'],2),"开通".$info['name']."赠送消费券".$order['pay_price']);
        if($user['spread_uid']>0 && $order['level_id']==1)
        {
            $sp_user = User::where('uid',$user['spread_uid'])->find();
            $spread_consumer = sys_config('spread_consumer');
            User::where('uid',$user['spread_uid'])->inc('consumer',$spread_consumer)->update();
            UserBill::income('推荐会员赠送消费券',$user['spread_uid'],'consumer','spread_add_consumer',$spread_consumer,$info['id'],bcadd($sp_user['consumer'],$spread_consumer,2),"推荐会员赠送消费券".$spread_consumer);
        }
        //User::setSpreadLevel($order['spread_uid'],$order['uid']);
        return false !== $res;
    }
    /**
     * TODO 小程序JS支付
     * @param $orderId
     * @param string $field
     * @return array|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function jsPay($orderId, $field = 'order_id')
    {
        if (is_string($orderId))
            $orderInfo = self::where($field, $orderId)->find();
        else
            $orderInfo = $orderId;
        if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
        if ($orderInfo['paid']) exception('支付已支付!');
        if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
        $openid = WechatUser::getOpenId($orderInfo['uid']);
        return MiniProgramService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级');
    }
    /**
     * 微信app支付
     * @param $orderId
     * @param string $field
     * @return array|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function appPay($order,$field = 'order_id')
    {
        if(is_string($order))
            $orderInfo = self::where($field,$order)->find();
        else
            $orderInfo = $order;
        if(!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
        if($orderInfo['paid']) exception('支付已支付!');
        //if($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
        if($orderInfo['pay_price']==0) self::jsPayPrice($order,$orderInfo['uid']);
        $openid = WechatUser::uidToOpenid($orderInfo['uid'],'openid');
        $wechat = SystemConfigService::more(['weixin_open_appid', 'weixin_open_appsecret']);
        $payment = SystemConfigService::more(['pay_weixin_mchid', 'pay_weixin_client_cert', 'pay_weixin_client_key', 'pay_weixin_key', 'pay_weixin_open']);

        $config = array(
            'appid' => $wechat['weixin_open_appid'],			//填写高级调用功能的app id
            'appsecret' => $wechat['weixin_open_appsecret'], 		//填写高级调用功能的app secret
            'mchid' => $payment['pay_weixin_mchid'],			//商户id
            'key' => $payment['pay_weixin_key'], 			//填写你设定的key
            'sslcert_path' => $payment['pay_weixin_client_cert'],
            'sslkey_path' => $payment['pay_weixin_client_key'],
            'transfer_rsa_public_path' => '',	//企业转账到银行卡rsa公钥证书文件路径
        );
        $wechatpay = new \JiaLeo\Payment\Wechatpay\AppPay($config);
        $pay_data = [
            'body' =>self::getSubstrUTf8('充值VIP',30), //内容
            'attach' =>'user_level', //商家数据包
            'out_trade_no' => $orderInfo['order_id'], //商户订单号
            'total_fee' =>bcmul($orderInfo['pay_price'],100,0), //支付价格(单位:分)
            'notify_url' => sysConfig('site_url') . '/api/wechat/notify', //后台回调地址
        ];

        $url = $wechatpay->handle($pay_data);
        return $url;
    }
    public static function alipay($orderId, $field = 'order_id')
    {
        if (is_string($orderId))
            $orderInfo = self::where($field, $orderId)->find();
        else
            $orderInfo = $orderId;
        if ($orderInfo['paid']) exception('支付已支付!');
        if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
        $alipay = SystemConfigService::more(['alipay_app_id', 'alipay_pub_key','alipay_private_key','alipay_key']);
        $notifyUrl = sys_config('site_url') . '/api/alipay/notify';
        $aliPay = new AlipayService();
        $aliPay->setAppid($alipay['alipay_app_id']);
        $aliPay->setNotifyUrl($notifyUrl);
        $aliPay->setRsaPrivateKey($alipay['alipay_private_key']);
        $aliPay->setTotalFee($orderInfo['pay_price']);
        $aliPay->setOutTradeNo($orderInfo['order_id']);
        $aliPay->setOrderName('支付会员');
        $aliPay->setPassbackParams(['attach' =>'user_level']);
        $orderStr = $aliPay->getOrderStr();
        return $orderStr;
    }

    /**
     * 微信公众号JS支付
     * @param $orderId
     * @param string $field
     * @return array|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function wxPay($orderId, $field = 'order_id')
    {
        if (is_string($orderId))
            $orderInfo = self::where($field, $orderId)->find();
        else
            $orderInfo = $orderId;
        if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
        if ($orderInfo['paid']) exception('支付已支付!');
        if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
        $openid = WechatUser::uidToOpenid($orderInfo['uid'], 'openid');
        return WechatService::jsPay($openid, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级');
    }

    /**
     * 微信h5支付
     * @param $orderId
     * @param string $field
     * @return array|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function h5Pay($orderId, $field = 'order_id')
    {
        if (is_string($orderId))
            $orderInfo = self::where($field, $orderId)->find();
        else
            $orderInfo = $orderId;
        if (!$orderInfo || !isset($orderInfo['paid'])) exception('支付订单不存在!');
        if ($orderInfo['paid']) exception('支付已支付!');
        if ($orderInfo['pay_price'] <= 0) exception('该支付无需支付!');
        return WechatService::paymentPrepare(null, $orderInfo['order_id'], $orderInfo['pay_price'], 'user_level','会员升级' , '', 'MWEB');
    }


    /**
     * 余额支付
     * @param $order_id
     * @param $uid
     * @param string $formId
     * @return bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function yuePay($order_id, $uid, $formId = '')
    {
        $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->find();
        if (!$orderInfo) return self::setErrorInfo('订单不存在!');
        if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
        $userInfo = User::getUserInfo($uid);
        if ($userInfo['now_money'] < $orderInfo['pay_price'])
            return self::setErrorInfo(['status' => 'pay_deficiency', 'msg' => '余额不足' . floatval($orderInfo['pay_price'])]);
        self::beginTrans();
        $res1 = false !== User::bcDec($uid, 'now_money', $orderInfo['pay_price'], 'uid');
        $res2 = UserBill::expend('会员升级', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '余额支付' . floatval($orderInfo['pay_price']) . '元升级' . SystemUserLevel::where(['id' => $orderInfo['level_id']])->value('name'));

        $res3 = self::paySuccess($order_id, 'yue');//余额支付成功
        try {
            PaymentRepositories::yuePayProduct($userInfo, $orderInfo);
        } catch (\Exception $e) {
            self::rollbackTrans();
            return self::setErrorInfo($e->getMessage());
        }
        $res = $res1 && $res2 && $res3;
        self::checkTrans($res);
        return $res;
    }

    public static function jsPayPrice($order_id, $uid, $formId = '')
    {
        $orderInfo = self::where('uid', $uid)->where('order_id', $order_id)->where('is_del', 0)->find();
        if (!$orderInfo) return self::setErrorInfo('订单不存在!');
        if ($orderInfo['paid']) return self::setErrorInfo('该订单已支付!');
        $userInfo = User::getUserInfo($uid);
        self::beginTrans();
        $res1 = UserBill::expend('会员升级', $uid, 'now_money', 'pay_product', $orderInfo['pay_price'], $orderInfo['id'], $userInfo['now_money'], '微信支付' . floatval($orderInfo['pay_price']) . '元升级' . SystemUserLevel::where(['id' => $orderInfo['level_id']])->value('name'));
        $res2 = self::paySuccess($order_id, 'weixin', $formId);//微信支付为0时
        $res = $res1 && $res2;
        self::checkTrans($res);
        return $res;
    }
    /**
     * TODO 一级返佣
     * @param $orderInfo
     * @return bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function backBrokerage($levelInfo, bool $open = true)
    {

        $userInfo = User::getUserInfo($levelInfo['uid']);
        //TODO 当前用户不存在 没有上级 或者 当用用户上级时自己  直接返回
        if (!$userInfo || !$userInfo['spread_uid'] || $userInfo['spread_uid'] == $levelInfo['uid']) return true;
        $sp_user = User::where('uid',$levelInfo['spread_uid'])->find();
        $spread_consumer = sys_config('spread_consumer');
        User::where('uid',$levelInfo['spread_uid'])->inc('consumer',$spread_consumer)->update();
        UserBill::income('推荐会员赠送消费券',$levelInfo['spread_uid'],'consumer','spread_add_consumer',$spread_consumer,$levelInfo['id'],bcadd($sp_user['consumer'],$spread_consumer,2),"推荐会员赠送消费券".$spread_consumer);
        return true;
    }

    /**
     * TODO 二级推广
     * @param $orderInfo
     * @return bool
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function backBrokerageTwo($levelInfo, bool $open = true)
    {
        //TODO 获取购买商品的用户
        $userInfo = User::getUserInfo($levelInfo['uid']);
        //TODO 获取上推广人
        $userInfoTwo = User::getUserInfo($userInfo['spread_uid']);
        //TODO 上推广人不存在 或者 上推广人没有上级  或者 当用用户上上级时自己  直接返回
        if (!$userInfoTwo || !$userInfoTwo['spread_uid'] || $userInfoTwo['spread_uid'] == $levelInfo['uid']) return true;
        //TODO 获取后台分销类型  1 指定分销 2 人人分销
        if (!User::be(['uid' => $userInfoTwo['spread_uid']])) return true;

        $brokeragePrice =  bcmul($levelInfo['pay_price'],sys_config('vip_two_brokerage')/100,2);
        //TODO 返佣金额小于等于0 直接返回不返佣金
        if ($brokeragePrice <= 0) return true;
        //TODO 获取上上级推广员信息
        $spreadUserInfoTwo = User::getUserInfo($userInfoTwo['spread_uid']);
        //TODO 获取上上级推广员返佣之后余额
        $balance = bcadd($spreadUserInfoTwo['brokerage_price'], $brokeragePrice, 2);
        $mark = '二级推广人' . $userInfo['nickname'] . '开通会员' . floatval($levelInfo['pay_price']) . '元,奖励推广佣金' . floatval($brokeragePrice)."元";
        $open && self::beginTrans();
        //TODO 添加返佣记录
        $res1 = UserBill::income('获得推广佣金', $userInfoTwo['spread_uid'], 'now_money', 'brokerage', $brokeragePrice, $levelInfo['id'], $balance, $mark);
        //TODO 添加用户余额
        $res2 = self::bcInc($userInfoTwo['spread_uid'], 'brokerage_price', $brokeragePrice, 'uid');
        $res = $res1 && $res2;
        $open && self::checkTrans($res);
        return $res;
    }
    /**
     * 获取会员升级订单
     */
    public static function orderlist($where)
    {
        $model = new self;
        if(isset($where['data']) && $where['data'] !='') $model = $model->getModelTime($where,$model,"addtime");
        if(isset($where['paid']) && $where['paid'] >-1)  $model = $model->where('paid',$where['paid']);
        if(isset($where['key']) && $where['key'] !='') $model = $model->where('order_id','like',"%".$where['key']."%");
        $model = $model->order('id desc');
        return self::page($model, function ($v) {
            $info = User::where('uid',$v['uid'])->find();
            $v['nickname'] = $info['nickname'];
            $v['avatar'] = $info['avatar'];
        }, $where);
    }

}