<?php

/**
 * Notes:流水处理
 * User: wsc
 * Time: 2020/6/10 18:48
 * Class ModelCurrency
 */
class ModelCurrency{
    private $attrType;
    public function __construct()
    {
        $this->attrType = oo::cfg('attr');
    }


    /**
     * Notes:
     * User: wsc
     * Time: 2020/7/8 15:35
     * @param $uid    -用户id
     * @param $type   -类型 如"money","spins",...
     * @param $t      + 或 -
     * @param $count  -变化值
     * @param $num    -最终数量
     * @param $rid    -来源id 明显见 config/common/config.reason.php
     * @param $reason -原因可扩展具体
     */
    public function log($uid,$type,$t,$count,$num,$rid,$reason){
        $userlevelInfo = oo::commonOprModel("member")->getUserLevel($uid);//获取用户信息
        $data = [
            'uid'=>$uid,
            'type'=>$type,
            'num'=>(int)$count,
            'crease'=>$t,
            'reason'=>$reason,
            'last_num'=>(int)$num,
            'rid'=>(int)$rid,
            'levelId'=>(int)$userlevelInfo['levelId'],
            'time'=>time()
        ];
        if($type=='money'){
            if($t=="+"){
                oo::commonOprModel('steal')->toJoinQueue($uid,$userlevelInfo['levelId'],$num);
                $this->setUserDayData($uid,'obtain_coin',$count);
            }else{
                oo::commonOprModel('steal')->toOutQueue($uid,$userlevelInfo['levelId'],$num);
                $this->setUserDayData($uid,'cost_coin',$count);
            }
        }else if($type=='shield'){
            oo::commonOprModel('member')->checkAttackShieldByUid($uid,true);
        }else if($type=='spins'){
            if($t=="+"){
                $this->setUserDayData($uid,'obtain_spin',$count);
            }else{
                $this->setUserDayData($uid,'cost_spin',$count);
            }
        }
        $key = okeys::assetsLog(date("YmdH"));
        oo::commonOprRedis('Statistics')->lPush($key,json_encode($data));//流水入队
        $userlevelInfo['levelId'] > 1 && $this->coinsValueSta($data);

        $whileList = oo::commonOprRedis('common')->sMembers(okeys::slotWhileList());
        if($rid==999&&in_array($uid,$whileList)){//白名单后台发放不记录数数统计

            return ;
        }
        //数数事件-消耗发放
        $filtration =[1,2,3,4,5,9,10,11,30,50,81,82,86,87,205,208,213,214,217,219,221,353];
        $payfilt =[300,301,302,304,304,305,310,311,312,313,314,330,410,450,451,452,453,454];
        $other =[1003,1011,1012,1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,2002];
        $filtration = array_merge($filtration,$payfilt,$other);
        if(!in_array($rid,$filtration)){
            if($t=="+"){
                $eventType = "resource_obtain";
                $eventData=[
                    "resource_obtain_name"=>(string)$type,
                    "resource_obtain_num"=>$count,
                    "resource_obtain_newnum"=>$num,
                    "resource_obtain_type"=>$rid,
                    "resource_obtain_ext"=>[$reason],
                ];
            }else{
                $eventType = "resource_cost";
                $eventData=[
                    "resource_cost_name"=>(string)$type,
                    "resource_cost_num"=>$count,
                    "resource_cost_newnum"=>$num,
                    "resource_cost_type"=>$rid,
                    "resource_cost_ext"=>[$reason],
                ];
            }
            oo::commonOprModel('ta')->setEventData($uid,$eventType,$eventData);
        }


    }

    /**
     * Notes:活动流水
     * User: wsc
     * Time: 2021/3/17 18:20
     * @param $aid
     * @param $uid
     * @param $type
     * @param $t
     * @param $count
     * @param $num
     * @param $rid
     * @param $reason
     */
    public function actlog($aid,$uid,$type,$t,$count,$num,$rid,$reason=''){
        $data = [
            'aid'=>(int)$aid,
            'uid'=>$uid,
            'type'=>$type,
            'num'=>(int)$count,
            'crease'=>$t,
            'reason'=>$reason,
            'last_num'=>(int)$num,
            'rid'=>$rid,
            'time'=>time()
        ];
        $key = okeys::actAssetsLog(date("YmdH"));
        oo::commonOprRedis('Statistics')->lPush($key,json_encode($data));//流水入队
    }
    /**
     * 每日宠物免费/付费 偷/打参与数据
     * @param int $uid
     * @param string $type (coindozer:推金币)
     * @param string $flag 标记(免费参与:0,付费参与:1)
     * @param string $day 日期
     */
    public function participation($uid, $type, $flag = 0, $day = '') {
        if(empty($day)){
            $day = date('Ymd');
        }
        $uKey = okeys::participationUidKey($uid, $type, $flag);
        //今天已经统计过
        if(!oo::commonOprRedis('statistics')->setNx($uKey, 1)){
            return;
        }
        oo::commonOprRedis('statistics')->expireAt($uKey, strtotime('23:59:59'));
        $key = okeys::participationLog($day);
        oo::commonOprRedis('Statistics')->hIncrBy($key, okeys::participationSubKey($type, $flag), 1);

        //参与数据保留3天缓存
        if(oo::commonOprRedis('Statistics')->hLen($key) < 2){
            oo::commonOprRedis('Statistics')->expire($key,oo::redisRandomExpire(3*24*3600)); //保留3天
        }
    }

    /**
     * Notes:定时创建流水表
     * User: wsc
     * Time: 2020/6/12 19:44
     * @param string $do
     */
    public function cronCreatAssessTable($do="false"){
        if(date('w',time())==5||$do){
            $sql = oo::cfg('sql')['assetslog'];
            for($i=1;$i<8;$i++){
                $d = date("Ymd",time()+$i*86400);
                $tb = 'assetslog_'.$d;
                $query = str_replace('#table#', $tb, $sql);
                $res  = funs::createTable("crazygod_log.".$tb,$query);
                oo::logs()->commlog("Create Table {$tb} Res:{$res}",'createAssessTable');
            }
        }
    }

    /**
     * Notes:统计个人每天金币，体力变化
     * User: wsc
     * Time: 2020/6/5 14:44
     * @param $data
     * @return bool
     */
    public function statisticsMS($data){
        $t = $data['crease'];
        if($t=="+"){
            //可能异常来源统计
//            $this->statisticsAbnormal($data);
        }
        //每日个人money.spans增减量统计
        $this->statisticsUserTodayData($data);
        $userlevelInfo = oo::commonOprModel("member")->getUserLevel($data['uid']);//获取用户信息
        //体力金币发放消耗关卡统计
        $LevelStatisticsT = $t=="-"?'Sub':'Add';
        oo::commonOprRedis('statistics')->hIncrBy(okeys::spinsMoneyLevelStatistics($data['type'],$LevelStatisticsT),$userlevelInfo['levelId'],$data['num']);
        //各变化来源分类合计统计
        oo::commonOprModel('member')->PropertyStatistics($t,$data['type'],$data['num'],$data['reason']);//用流水表做统计
        return true;
    }

    /**
     * Notes:每日个人money.spans增减量统计
     * User: wsc
     * Time: 2020/6/6 16:05
     * @param $data
     */
    public function statisticsUserTodayData($data){
        $type = $data['crease']=="-"?$data['type']:($data['type']=='money'?'addMoney':'addSpins');
        if($data['crease']=="+"){
//            //每日获得金币排行前100
//            $key = okeys::todayDataRank($type);
//            oo::commonOprRedis('statistics')->zAdd($key,$data['num'],$data['uid']);
//            $size = oo::commonOprRedis('statistics')->zSize($key);
//            if($size>100){
//                oo::commonOprRedis('statistics')->zDeleteRangeByScore($key,0,0);
//            }
        }
        //每日个人money.spins增减量统计
        oo::commonOprRedis('statistics')->hIncrBy(okeys::todayDataRank($type),$data['uid'],$data['num']);
    }


    //异常来源统计及警告
    public function statisticsAbnormal($data){
        $cfg = oo::commonOprModel('member')->moneyAddType();
        $reasonArr =explode(":",$data['reason']);
        $reason=!empty($reasonArr)?array_search($reasonArr[0],$cfg):'other';
        $akey = okeys::abnormalSta($data['uid']."_".$data['type']);
        $afterInfo = oo::commonOprRedis('statistics')->hGetAll($akey);
        if(isset($afterInfo['after_reason'])&&$afterInfo['after_reason']==$reason){//本次与上次是同一来源
            $sumlimit = oo::commonOprRedis('statistics')->hIncrBy($akey,$reason,1);
            if($sumlimit>=20){
                oo::commonOprModel('asynclog')->push("ABNORMAL",[
                    'uid'     => $data['uid'],
                    'num'     => $data['num'],
                    'reason'  => $reasonArr[0],
                    'type'    => $data['type'],
                    'abnormal'=> '连续20次增加来源一致',
                    'time'    => time(),
                ]);
                oo::commonOprRedis('statistics')->delete($akey);
            }
        }else{
            oo::commonOprRedis('statistics')->delete($akey);
            $cache = ["after_reason"=>$reason,$reason=>1];
            oo::commonOprRedis('statistics')->hMset($akey,$cache);
            oo::commonOprRedis('statistics')->expire($akey,86400);
        }
        return true;
    }

    private function coinsValueSta($data){
        if($data['type'] == "money" || $data['type'] == 'spins'){
            if(in_array($data['uid'],oo::commonOprModel("config")->payWhiteList())){
                return true;
            }
            if($data['type'] == "spins" && $data['crease'] == "-"){
                oo::commonOprRedis('statistics')->hIncrBy(okeys::CoinsValueSta("spins"),$data['uid']."-".$data['levelId'],$data['num']);
                oo::commonOprRedis('statistics')->hIncrBy(okeys::CoinsValueSta("slot"),$data['uid'],1);
                oo::commonOprRedis('statistics')->hSet(okeys::CoinsValueSta("dau"),$data['uid'],$data['levelId']);
            }else if($data['type'] == "money" && $data['crease'] == "+" && in_array($data['rid'],[1,2,3,4,9,10])){
                oo::commonOprRedis('statistics')->hIncrBy(okeys::CoinsValueSta("coins"),$data['uid']."-".$data['levelId'],$data['num']);
            }
            $hashKey = $data['type'] == "money" ? $data['uid']."-".$data['levelId'] : $data['uid'];
            oo::commonOprRedis('statistics')->hIncrBy(okeys::CoinsValueSta($data['type'].$data['crease']),$hashKey,$data['num']);

            if($data['type'] == "spins"){
                if($data['crease'] == "-"){
                    oo::commonOprModel('Statistics')->addUserStatistics($data['uid'],['costSpin'=>$data['num'],'spinTimes'=>1]);
                }else if($data['crease'] == "+"){
                    oo::commonOprModel('Statistics')->addUserStatistics($data['uid'],['obtainSpin'=>$data['num']]);
                }
            }
        }
        return true;
    }

    /**
     * Notes:设置累计用户每日数据
     * User: wsc
     * Time: 2021/5/18 15:15
     * @param $uid
     * @param $type
     * @param $num
     * @return bool
     */
    public function setUserDayData($uid,$type,$num){
        $num = intval($num);
        $date = date( 'Ymd',time());
        $key = okeys::UserDayData($uid,$date);
//        $keyArr = array_keys(oo::commonOprModel('ta')->events['resource_list']);
        $keyArr = ["obtain_spin","cost_spin","obtain_coin","cost_coin","obtain_card","cost_card","spin_times"];
        if(!in_array($type,$keyArr)||$num<1){
            return false;
        }
        $needSet=false;
        if(!oo::commonOprRedis('statistics')->exists($key)){
            $needSet = true;
        }
        oo::commonOprRedis('statistics')->hIncrBy($key,$type,$num);
        if($needSet){
            oo::commonOprRedis('statistics')->expire($key,oo::redisRandomExpire(oo::todayDeadline()+7200));
        }
    }
}
