<?php

namespace app\models\user;

use app\models\store\StoreRechargeCard;
use app\models\store\StoreRechargeCardBrokerage;
use crmeb\basic\BaseModel;
use crmeb\services\MiniProgramService;
use crmeb\services\WechatService;
use crmeb\traits\ModelTrait;

/**
 * TODO 用户充值
 * Class UserRecharge
 * @package app\models\user
 */
class UserRechargeCard extends BaseModel
{
    /**
     * 数据表主键
     * @var string
     */
    protected $pk = 'id';

    /**
     * 模型名称
     * @var string
     */
    protected $name = 'user_recharge_card';

    use ModelTrait;

    protected $insert = ['add_time'];

    protected function setAddTimeAttr()
    {
        return time();
    }

    /**
     * 创建充值订单
     * @param $uid
     * @param $price
     * @param string $recharge_type
     * @param int $paid
     * @return UserRecharge|bool|\think\Model
     */
    public static function addRecharge($uid, $card_id, $price, $give_price = 0, $paid = 0, $is_brokerage = 0, $parent_uid, $status, $mer_id = '')
    {
        $order_no = self::getNewOrderId($uid);
        if (!$order_no) return self::setErrorInfo('订单编号生成失败！');
        $add_time = time();
        return self::create(compact('uid', 'order_no', 'card_id', 'price', 'give_price', 'paid', 'add_time', 'is_brokerage', 'parent_uid', 'status', 'mer_id'));
    }

    /**
     * 生成充值订单号
     * @param int $uid
     * @return bool|string
     */
    public static function getNewOrderId($uid = 0)
    {
        if (!$uid) return false;
        $count = (int)self::where('uid', $uid)->where('add_time', '>=', strtotime(date("Y-m-d")))->where('add_time', '<', strtotime(date("Y-m-d", strtotime('+1 day'))))->count();
        return 'wx' . date('YmdHis', time()) . (10000 + $count + $uid);
    }

    /**
     * 充值js支付
     * @param $orderInfo
     * @param bool $mer_id
     * @return array|string
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function jsPay($orderInfo, $mer_id = false)
    {
        return MiniProgramService::jsPay(WechatUser::uidToOpenid($orderInfo['uid']), $orderInfo['order_no'], $orderInfo['price'], 'user_recharge_card', '用户充值', '', 'JSAPI', [], $mer_id);
    }

    /**
     * //TODO用户充值成功后
     * @param $orderNo
     */
    public static function rechargeSuccess($orderNo)
    {
        $order = self::where('order_no', $orderNo)->where('paid', 0)->find();
        if (!$order) return false;
        $user = User::getUserInfo($order['uid']);
        $price = bcadd($order['price'], $order['give_price'], 2);
        $received_price = bcmul($price, (1-$order['refund_percent']), 2);
        // ============================支付完成=============================
        // 更改订单状态
        self::where('id', $order['id'])->update(['paid' => 1, 'pay_time' => time()]);
        // 创建用户账单表记录
        $mark = '成功充值余额' . floatval($order['price']) . '元' . ($order['give_price'] ? ',赠送' . $order['give_price'] . '元' : '');
        UserBill::income('用户余额充值', $order['uid'], 'now_money', 'recharge', $order['price'], $order['id'], $user['now_money'], $mark, 1, $order['mer_id']);
        // 更改用户余额
        User::edit(['now_money' => bcadd($user['now_money'], $price, 2)], $order['uid'], 'uid');
        // ============================充值返现=============================
        // 判断是否返现充值
        if($order['is_brokerage']){
            // ======================================给自己返佣==========================================
            $card_brokerage = StoreRechargeCardBrokerage::where(['cid' => $order['card_id'], 'role' => 1])->find();
            $recharge_card = StoreRechargeCard::where('id', $order['card_id'])->find();
            $refund_no = UserBrokerage::getNewRefundNo();
            $refund_data['pay_price'] = $order['price'];
            $refund_data['refund_price'] = number_format($order['price'] * $card_brokerage['scale'] / 100, 2);
            $refund_data['refund_price'] = number_format($refund_data['refund_price'] * (100 - $recharge_card['poundage']) / 100, 2);
            $refund_data['refund_id'] = $refund_no;
            // 微信支付给自己退款
            $res = MiniProgramService::payOrderRefund($order['order_no'], $refund_data, $order['mer_id']);
            // (需要判断微信退款是否成功)
            if($res){
                // 更改订单状态
                $refund_price = bcadd($order['refund_price'], $refund_data['refund_price'], 2);
                $refund_percent = $order['refund_percent'] + $card_brokerage['scale'];
                self::where('id', $order['id'])->update(['refund_price' => $refund_price, 'refund_percent' => $refund_percent]);
                // 创建用户返佣记录
                UserBrokerage::addUserBrokerage($order['uid'], $order['card_id'], $order['id'], 0, $refund_no, 1, $refund_data['refund_price'], $card_brokerage['scale'], $recharge_card['poundage'], $order['mer_id']);
            }
            // =====================================给推荐人返佣=======================================
            // 初始化
            $bool = true;
            // 判断是否有上级id
            if(!$order['parent_uid']) $bool = false;
            if($order['parent_uid'] == $order['uid']) $bool = false;
            if(!$order['status'] === 1) $bool = false;
            $parent_orderInfo = self::getParentOrderInfo($order);
            $parent_order = self::getParentOrder($order);
            $parent_recharge_card = StoreRechargeCard::where('id', $parent_order['card_id'])->find();
            // 循环判断返现比例处于哪一级
            $brokerageScale = StoreRechargeCardBrokerage::where('cid', $order['card_id'])->where('role', 2)->order('level asc')->select();
            if($parent_orderInfo && $brokerageScale && $bool){
                // 判断上级是否有下级返现记录
                if(empty($parent_orderInfo)){
                    $i = 0;
                }else{
                    $count = $brokerageScale[0]['num'];
                    if($parent_orderInfo[4] < $count){
                        $i = 0;
                    }else{
                        $i = 0;
                        $count = $brokerageScale[$i]['num'];
                        while($count <= $parent_orderInfo[4]){
                            if($i >= count($brokerageScale)){
                                $bool = false;
                                break;
                            }
                            $i++;
                            $count += $brokerageScale[$i]['num'];
                        }
                        if($i >= count($brokerageScale)){
                            $bool = false;
                        }
                    }

                    if(isset($brokerageScale[$i]) && $parent_orderInfo[0] + $brokerageScale[$i]['scale'] > 100){
                        $bool = false;
                    }
                }
                if($bool){
                    $recharge_card = StoreRechargeCard::where('id', $order['card_id'])->find();
                    $refund_no = UserBrokerage::getNewRefundNo();
                    $parent_refund_data['pay_price'] = $parent_order['price'];
                    $parent_refund_data['refund_price'] = $parent_order['price'] * $brokerageScale[$i]['scale'] / 100;
                    $parent_refund_data['refund_price'] = $parent_refund_data['refund_price'] * (1 - $parent_recharge_card['poundage']);
                    $parent_refund_data['refund_id'] = $refund_no;
                    // 微信支付给邀请人退款
                    $res = MiniProgramService::payOrderRefund($parent_order['order_no'], $parent_refund_data, $parent_order['mer_id']);
                    if($res){
                        // 更改订单状态
                        $refund_price = bcadd($parent_order['refund_price'], $parent_refund_data['refund_price'], 2);
                        $refund_percent = $parent_order['refund_percent'] + $brokerageScale[$i]['scale'];
                        self::where('id', $parent_order['id'])->update(['refund_price' => $refund_price, 'refund_percent' => $refund_percent]);
                        // 创建用户返佣记录
                        UserBrokerage::addUserBrokerage($parent_order['uid'], $parent_order['card_id'], $order['id'], $parent_order['id'], $refund_no, 2, $parent_refund_data['refund_price'], $brokerageScale[$i]['scale'], $parent_recharge_card['poundage'], $parent_order['mer_id']);
                    }
                }else{
                    self::where('id', $parent_order['id'])->update(['status' => 2]);
                }
            }
        }
        return true;
    }

    /**
     * 获取用户和推荐人返佣信息
     */
    public static function getParentOrderInfo($order)
    {
        if(!$parentOrder = self::getParentOrder($order)) return self::setErrorInfo('推荐人订单不存在');
        list($brokerageSelf, $brokerageOther, $countSelf, $countOther) = UserBrokerage::getUserOrderBrokerageInfo($parentOrder);
        $totalPercent = 0;
        foreach($brokerageOther as $k => $v){
            $totalPercent += $v['refund_percent'];
        }
        return [$totalPercent, $brokerageSelf, $brokerageOther, $countSelf, $countOther];
    }

    /**
     * 获取邀请人最近的一条充值订单记录
     */
    public static function getParentOrder($order)
    {
        $model = new self;
        $model = $model->where('uid', $order['parent_uid']);
        $model = $model->where('card_id', $order['card_id']);
        $model = $model->where('paid', 1);
        $model = $model->where('is_brokerage', 1);
        $model = $model->where('status', 1);
        $model = $model->where('mer_id', $order['mer_id']);
        $model = $model->order('add_time desc');
        return $model->find();
    }

    /**
     * 获取用户充值记录
     */
    public static function getUsereRechargeCardList($where)
    {
        $model = self::setWhere($where, null, 'a', 'u.nickname')->join('user u', 'u.uid=a.uid')->join('store_recharge_card r', 'r.id=a.card_id')->field(['a.*', 'u.nickname', 'u.avatar', 'r.title as card_title']);
        $list = $model->page($where['page'], $where['limit'])->select();
        $list = count($list) ? $list->toArray() : [];
        foreach ($list as &$item) {
            $item['_pay_time'] = $item['pay_time'] ? date('Y-m-d H:i:s', $item['pay_time']) : '暂无';
            $item['_add_time'] = $item['add_time'] ? date('Y-m-d H:i:s', $item['add_time']) : '暂无';
            $item['paid_type'] = $item['paid'] ? '已支付' : '未支付';
            $item['_recharge_type'] = $item['is_brokerage'] ? '返现充值' : '普通充值';
            $item['received_price'] = bcadd($item['price'], $item['give_price'], 2);
        }
        $count = self::setWhere($where, null, 'a', 'u.nickname')->join('user u', 'u.uid=a.uid')->join('store_recharge_card r', 'r.id=a.card_id')->count();
        return compact('list', 'count');
    }

    /**
     * 设置查询条件
     * @param $where
     * @param null $model
     * @param string $alias
     * @param string $join
     * @return $this
     */
    public static function setWhere($where, $model = null, $alias = '', $join = '')
    {
        $model = is_null($model) ? new self() : $model;
        if ($alias) {
            $model = $model->alias('a');
            $alias .= '.';
        }
        if (isset($where['data']) && $where['data']) $model = self::getModelTime($where, $model, "{$alias}add_time");
        if (isset($where['paid']) && $where['paid'] != '') $model = $model->where("{$alias}paid", $where['paid']);
        if (isset($where['nickname']) && $where['nickname']) $model = $model->where("{$alias}uid|{$alias}order_no" . ($join ? '|' . $join : ''), 'LIKE', "%$where[nickname]%");
        if (isset($where['mer_id']) && $where['mer_id']) $model = $model->where("{$alias}mer_id", $where['mer_id']);
        if (isset($where['uid']) && $where['uid']) $model = $model->where("{$alias}uid", $where['uid']);
        return $model->order("{$alias}add_time desc");
    }
}