<?php

defined('IN_WEB') or die('Include Error!');

/**
 * 兑换码
 */
class ModelExchangecode {
    /**
     * 生成兑换码
     * @param $rwd
     * @param $limit
     * @param $day
     * @param int $type
     * @param string $remake
     * @param string $userLimit
     * @return false|string
     * Created by: Owen
     * Created on: 2020/12/1 18:23
     */
    public function createCode($rwd, $limit,$day,$type=0,$remake = "",$userLimit = '') {
        if (!$limit ||!$day) {
            return json_encode(['code'=>-1]);
        }
        $tb = otable::exchangeCode();
        $createTime = time();
        $expire = strtotime($day);
        $code = $this->createExchangeCode();//生成兑换码
        if ($code === 0) {
            return json_encode(['code' => 2, 'num' => $code]);
        }
        oo::commonOprDb('api')->query("INSERT INTO {$tb}  VALUES( null, '{$code}', '{$rwd}', 0, 0, {$limit}, {$expire}, $type ,{$createTime}, 0,'{$remake}','{$userLimit}')");
        return json_encode(['code' => 1, 'num' => $code]);
    }


    /**
     * 使用兑换码
     * @param int $code
     * @param int $uid
     * @return array
     * Created by: Owen
     * Created on: 2020/12/1 18:25
     */
    public function exchange($code = 0 , $uid = 0) {
        if (empty($code) || empty($uid) || $code=='NaN') {
            return ['code' => -1, 'msg' => '参数异常'];
        }
        $errKey = okeys::exchangeErr($uid);
        $errTimes = (int)oo::commonOprRedis('usercache')->get($errKey);
        if ($errTimes >= 10) {
            return ['code' => -2, 'msg' => '错误次数太多了，请稍后重试'];
        }
        $tb = otable::exchangeCode();
        $ret = oo::commonOprDb('api')->getOne("SELECT * FROM {$tb} WHERE code = '{$code}' LIMIT 1", MYSQLI_ASSOC);
        if(empty($ret)){
            $errTimes += 1;
            oo::commonOprRedis('usercache')->setex($errKey, $errTimes,3600);
            return ['code' => -3, 'msg' => '错误的兑换码'];
        }
        $expireTime = $ret['expire'];
        $rwdNum     = $ret['rwdNum'];
        $limit      = $ret['limit'];
        $rwd        = $ret['rwd'];
        $userType   = $ret['usertype'];
        $userLimit  = $ret['userLimit']??'';
        if ($expireTime <= time()) {
            return ['code' => -4, 'msg' => '兑奖码已经过期'];
        }
        if ($rwdNum >= $limit) {
            return ['code' => -5, 'msg' => '超出可兑换数量'];
        }
        if(!empty($userLimit) && strpos($userLimit,"{$uid}") === false){
            return ['code' => errorCode::EXCHANGCODE_USER_LIMIT, 'msg' => '不在指定用户里'];
        }
        $mcKey = okeys::exchangecode($uid, $code);
        $hasReward = oo::commonOprRedis('usercache')->get($mcKey);
        if( $hasReward ){
            return ['code' => -6, 'msg' => '您已经兑换过一次了'];
        }
        if($userType == 1 || $userType == 2){
            $userInfo = oo::commonOprModel('member')->getUserInfo($uid);
            if($userType == 1 && $userInfo['isFb'] != 1){
                return ['code' => -7, 'msg' => '账号类型不一致'];
            }else if($userType == 2 && $userInfo['isFb'] != 0){
                return ['code' => -7, 'msg' => '账号类型不一致'];
            }
        }else if($userType == 3){
            if(!oo::commonOprModel('newvip')->checkVip($uid)){
                return ['code' => -7, 'msg' => '账号类型不一致'];
            }
        }
        $retReward = $this->reward($uid, $rwd);
        if( $retReward < 1 ){
            return ['code' => -7, 'msg' => '发奖失败'];
        }
		oo::commonOprRedis('usercache')->setex($mcKey, 1, 7*86400);
        $rwdNum += 1;
        oo::commonOprDb('api')->query("UPDATE {$tb} SET rwdNum = {$rwdNum} WHERE code = '{$code}' LIMIT 1");
        $nums = oo::commonOprDb('api')->affectedRows();
        if( $nums <= 0 ){
            oo::logs()->debug3(array('uid' => $uid, 'code' => $code, 'time' => time()), 'exchangeCode_error.log');
            return ['code' => -8, 'msg' => '更新数据库失败'];
        }
        $this->_addUidToCodeUidList($uid, $code, 15*86400);
        $info = oo::commonOprModel('member')->getUserAssetsInfo($uid);
        $info['coins'] = $info['money'];
        unset($info['money']);
        $data['code'] = 1;
        $data['msg'] = '兑换成功';
        $reward = $retReward;
        if($reward['coins'] > 0){
            $reward['props'][] = ["propsId"=>14,"num"=>$reward['coins']];
        }
        if($reward['spins'] > 0){
            $reward['props'][] = ["propsId"=>15,"num"=>$reward['spins']];
        }
        $data['data']['reward'] = $reward;
        $data['data']['info']   = $info;
        return $data;
    }

    /*
    *	发奖
    */
    protected function reward($uid, $reward){
        if( !$uid || !$reward ){
            return -1;
        }
        $rewardArr = json_decode($reward, TRUE);
        if( !is_array($rewardArr) ){
            return -2;
        }
        foreach ($rewardArr as $type => &$value) {
            switch ($type) {
                case 'coins':
                    if($rewardArr['coins'] == 0){
                        break;
                    }
                    oo::commonOprModel('member')->optProperty($uid,array('money'=>intval($rewardArr['coins'])),'+',110,'兑换码奖励金币');
                    break;
                case 'spins':
                    if($rewardArr['spins'] == 0){
                        break;
                    }
                    oo::commonOprModel('member')->optProperty($uid,array('spins'=>intval($rewardArr['spins'])),'+',110,'兑换码奖励体力');
                    break;
                case 'props':
                    foreach ($value as $key=>&$row){
                        oo::commonOprModel('member')->sendReward($uid, $row['propsId'], $row['num'],110,"兑换码奖励",[],$row);
                    }
                    break;
            }
        }
        return $rewardArr;
    }


    /**
     * @function getCodeUidList
     * @desc     获取已经领取兑换码的用户的数据
     * @param    string code 兑换码
     * @return    array uidList 已领奖的用户的uidList
     */
    public function getCodeUidList($code) {
        $mcKey = okeys::exchangecodelist($code);
        $data = oo::commonOprRedis('usercache')->get($mcKey);
        return $data;
    }

    /**
     * @function _addUidToCodeUidList
     * @desc     更新已经领取兑换码的用户的数据
     * @param    string code 兑换码
     * @param    int uid 用户uid
     * @param    int expire mcache失效的时间戳
     * @return  bool
     */
    protected function _addUidToCodeUidList($uid, $code, $expire) {
        $mcKey = okeys::exchangecodelist($code);
        $data = oo::commonOprRedis('usercache')->get($mcKey);
        if( empty($data) ){
            $saveData = json_encode( array($uid . "|" . time()) );
        }else{
            $data = json_decode($data, TRUE);
            $data[] = $uid . "|" . time();
            $saveData = json_encode($data);
        }
        oo::commonOprRedis('usercache')->setex($mcKey, $saveData, $expire);
    }


    /**
     *	创建兑换码
     *	6位数字
     */
    public function createExchangeCode()
    {
        $table = otable::exchangeCode();

        //删除过期的兑换码
        $clearTime = time() - 7 * 86400;
        $sql = "DELETE FROM {$table} WHERE expire<{$clearTime}";
        oo::commonOprDb('api')->query($sql);

        $sql = "Select `code` FROM {$table}";
        $ret = oo::commonOprDb('api')->getAll($sql, MYSQLI_ASSOC);

        $codeList = array_column($ret, 'code');

        $times = 0;
        while (1) {
            $randCode = "9" . rand(11111, 99999);
            if (!in_array($randCode, $codeList)) {
                return $randCode;
            }
            $times++;
            if ($times > 100) {
                return 0;
            }
        }
    }

}
