<?php
defined('BASEPATH') OR exit('No direct script access allowed');

/*
* 定时器
*/
class Crontab2 extends CI_Controller
{
	public function __construct()
	{
		parent::__construct();
		
		//防止http访问
		if(!$this->is_cli()){
			die("ip error");
		}
		
		$this->load->model('oo');
	}

    public function getRfm(){
	ini_set("display_errors", "On");//打开错误提示
	ini_set("error_reporting",E_ALL);//显示所有错误
        $days = [
            '20210301',
            //'20210302',
            //'20210303',
            //'20210304',
            //'20210305',
        ];
        $groups = [];
        //分组
        $configs = oo::commonOprModel('config')->getUserGroupConfigByCid(2);
        $configs = array_column($configs, 'name', 'id');
        $tb = otable::UserDynamicsData();

        $file = '/tmp/res.txt';
        file_put_contents($file, '日期,RFM分组,dau,最大体力获取量,最小体力获取量,平均体力获取量,最大体力消耗量,最小体力消耗量,平均体力消耗量'."\n", FILE_APPEND);

        foreach($days as $day){
            $newGroups[$day] = $groups[$day] = [];
            $newUids = $uids = $uidGroups = [];
            $newArr = oo::commonOprModel('statistics')->getAllPlayer($day, 1, [1, 2]); //新玩家
            foreach($newArr as $k => $v){
                if(!in_array($v, $newUids)){
                    $newUids[] = $v;
                }
            }

            $allArr = oo::commonOprModel('statistics')->getAllPlayer($day, 2, [1, 2]); //所有玩家
            foreach($allArr as $k => $v){
                if(!isset($uidGroups[$v])){
                    $uids[] = $v;
                }
                //500个取一次数据
                if(count($uids) > 500){
                    $uidGroups = $this->getUidGroups($uids, $uidGroups, $configs);
                    $uids = [];
                }
            }
            //500个取一次数据
            if(count($uids) > 0){
                $uidGroups = $this->getUidGroups($uids, $uidGroups, $configs);
            }

            $groupUids = [];
            //用户分组列表
            foreach($uidGroups as $uid => $groupId){
                if(!isset($groupUids[$groupId])){
                    $groupUids[$groupId] = [];
                }
                $groupUids[$groupId][] = $uid;
            }


            //结果列表
            foreach($groupUids as $groupId => $uids){
                $uidStr = implode(',', $uids);
                $minAdd = $minDecr = $maxAdd = $maxDecr = $sumAdd = $sumDecr = 0;
                for($i = 0; $i < 10; $i++){
                    $atable = otable::Assetslog($day, $i);
                    $sql = "SELECT uid, SUM(num) as sum FROM {$atable} WHERE type = 'spins' AND uid IN({$uidStr}) AND crease='+' group by uid";
                    $tmpAdd = oo::commonOprDb('log')->getAll($sql, 1);

                    $sql = "SELECT uid, SUM(num) as sum FROM {$atable} WHERE type = 'spins' AND uid IN({$uidStr}) AND crease='-' group by uid";
                    $tmpDecr = oo::commonOprDb('log')->getAll($sql, 1);

                    list($minAdd, $maxAdd, $sumAdd) = $this->getResData($tmpAdd, $minAdd, $maxAdd, $sumAdd);
                    list($minDecr, $maxDecr, $sumDecr) = $this->getResData($tmpDecr, $minDecr, $maxDecr, $sumDecr);
                }
                $count = count($uids);
                $groups[$day][$groupId] = [
                    'group' => $groupId,
                    'dau' => $count,
                    'spinsMinAdd' => $minAdd,
                    'spinsAvgAdd' => sprintf('%.2f', $sumAdd / $count),
                    'spinsMaxAdd' => $maxAdd,
                    'spinsMinDecr' => $minDecr,
                    'spinsAvgDecr' => sprintf('%.2f', $sumDecr / $count),
                    'spinsMaxDecr' => $maxDecr,
                ];
            }
            $newStr = implode(',', $newUids);
            for($i = 0; $i < 10; $i++){
                $newMinAdd = $newMinDecr = $newMaxAdd = $newMaxDecr = $newSumAdd = $newSumDecr = 0;
                $atable = otable::Assetslog($day, $i);
                $sql = "SELECT uid, SUM(num) as sum FROM {$atable} WHERE type = 'spins' AND uid IN({$newStr}) AND crease='+' group by uid";
                $newTmpAdd = oo::commonOprDb('log')->getAll($sql, 1);

                $sql = "SELECT uid, SUM(num) as sum FROM {$atable} WHERE type = 'spins' AND uid IN({$newStr}) AND crease='-' group by uid";
                $newTmpDecr = oo::commonOprDb('log')->getAll($sql, 1);
                list($newMinAdd, $newMaxAdd, $newSumAdd) = $this->getResData($newTmpAdd, $newMinAdd, $newMaxAdd, $newSumAdd);
                list($newMinDecr, $newMaxDecr, $newSumDecr) = $this->getResData($newTmpDecr, $newMinDecr, $newMaxDecr, $newSumDecr);
            }
            $newGroups[$day] = [
                'dau'          => count($newUids),
                'spinsMinAdd'  => $newMinAdd,
                'spinsAvgAdd'  => sprintf('%.2f', $newSumAdd / count($newUids)),
                'spinsMaxAdd'  => $newMaxAdd,
                'spinsMinDecr' => $newMinDecr,
                'spinsAvgDecr' => sprintf('%.2f', $newSumDecr / count($newUids)),
                'spinsMaxDecr' => $newMaxDecr,
            ];
        }
var_dump($groups);
var_dump($newGroups);
        foreach($groups as $day => $val){
            foreach($val as $v){
                $gid = isset($configs[$v['group']]) ? $configs[$v['group']] : $v['group'];
                file_put_contents($file, "{$day},{$gid},{$v['dau']},{$v['spinsMaxAdd']},{$v['spinsMinAdd']},{$v['spinsAvgAdd']},{$v['spinsMaxDecr']},{$v['spinsMinDecr']},{$v['spinsAvgDecr']}"."\n", FILE_APPEND);
            }
        }
        foreach($newGroups as $day => $v){
            file_put_contents($file, "{$day},新用户,{$v['dau']},{$v['spinsMaxAdd']},{$v['spinsMinAdd']},{$v['spinsAvgAdd']},{$v['spinsMaxDecr']},{$v['spinsMinDecr']},{$v['spinsAvgDecr']}"."\n", FILE_APPEND);           
        }
    }

    function getResData($data, $min = 0, $max = 0, $sum = 0) {
        foreach($data as $v){
            $sum += $v['sum'];
            if(empty($min) || $min > $v['sum']){
                $min = $v['sum'];
            }
            if(empty($max) || $max < $v['sum']){
                $max = $v['sum'];
            }
        }
        return [$min, $max, $sum];
    }

    function getUidGroups($uids, $uidGroups, $configs) {
        $implodes = implode(',', $uids);
        $tb = otable::UserDynamicsData();
        $sql = "SELECT uid, groupId2 FROM {$tb} WHERE uid IN({$implodes})";
        $arr = oo::commonOprDb('slavedb')->getAll($sql, true);
        foreach($arr as $k => $v){
            $groupId2 = $v['groupId2'] ? explode(',', $v['groupId2']) : [];
            $uidGroups[$v['uid']] = $this->getUserGroup($groupId2, $configs);
        }
        return $uidGroups;
    }

    public function getUserGroup($groups, $configs) {
        foreach($groups as $groupId){
            if(isset($configs[$groupId])){
                return $groupId;
            }
        }
        return 0;
    }

        public function test() {
            $days = ['20210301', '20210302'];
            $doubleRewards = $uids = [];
            for($i = 0; $i < 10; $i++){
                foreach($days as $d){
                    $tb = otable::Assetslog($d, $i);
                    $sql = "SELECT DISTINCT(uid) as uid FROM {$tb} WHERE rid = 997";
                    $a = oo::commonOprDb('log')->getAll($sql, 1);
                    foreach($a as $v){
                        if(!in_array($v['uid'], $uids)){ //重复领过的
                            $uids[] = $v['uid'];
                        }else{
                            $doubleRewards[] = $v['uid'];
		            file_put_contents('/tmp/res.txt', $v['uid']."\n", FILE_APPEND);
                        }
                    }
                }
            }
            var_dump($doubleRewards);
            exit;
        }
	
	//触发php index.php Crontab crontab
	public function crontab(){
		set_time_limit(0);
		// G(小时，24 小时格式，没有前导零，0 到 23), i(有前导零的分钟数，00 到 59>)
		$now = time();
		$time = date('Gi', $now);
		$day = date("j"); // 月份中的第几天，没有前导零(1到31)
		$week = date('w');//星期中的星期几 周日是0 周一是1 依次排下去
		
		$minute = date('i');


        /**
         * 更新用戶分組 --- start
         */
        oo::commonOprModel('member')->updateUserGroup();
        oo::commonOprModel('member')->updateUserGroup2();
        oo::commonOprModel('member')->updateUserGroupByUid();
        if($time == '030'){
            //广告组删除移除用户数据
            oo::commonOprModel('member')->delUserGroupAction();
        }
        /**
         * 更新用戶分組 --- end
         */


        oo::commonOprModel('push')->crontabPush();// 定时推送

        if($time == "045"){ //上午9点自动刷新一次cdn md5，防止程序开发上传后忘记刷新
            oo::commonOprModel('Filemd5')->makeActivityMd5();
        }

        if($time == "2350"){
            //登陆事件上报 保存到数据库
            oo::commonOprModel('statistics')->saveLoginEventSta();
        }
        if($time == "2355"){
            //当天人均通关数（当天通关数 / 当天登陆用户数） 保存到数据库
            oo::commonOprModel('statistics')->saveTodayUpLvelSta();
        }
		if($time == "2358"){
			//事件统计
			oo::commonOprModel('statistics')->newGuideLost();
			//新手步骤统计 保存到数据库
		    oo::commonOprModel('statistics')->saveNoviceStepsSta();
		}
		
		if($time == "2357"){
			//关卡分布统计 保存到数据库
			oo::commonOprModel('statistics')->levelSta();
		}
		
		if($time == '001') {
			//广告事件上报
		  	oo::commonOprModel('statistics')->advertisement();
		  	//网络重连上报统计 保存到数据库
		  	oo::commonOprModel('statistics')->saveNetworkReportSta();
		  	//分享事件上报 保存到数据库
            oo::commonOprModel('statistics')->shareEventSta();
		}
		
		if($time == "002"){
			//adJust 統計
			oo::commonOprModel('statistics')->adJustSta();
		}
		
		if($time == '003'){
			//支付上报 保存到数据库
		    oo::commonOprModel('statistics')->savePayReportSta();
		    //每日金币、体力、盾牌存量统计 保存到数据库
		    oo::commonOprModel('statistics')->todayStockSta();
		    //商城促销统计 保存到数据库
		    oo::commonOprModel('statistics')->shopDiscountSta();
		}
		
		if($time == '004'){
			//金币体力发放消耗统计
		    oo::commonOprModel('statistics')->savePropertyStatistics();
		}
		
		if($time == '005'){
			//老虎机统计
		    oo::commonOprModel('statistics')->slotStatistics();
		}
		
		if($time == '006'){
			//打概率统计 击中率（损毁建筑） & 摧毁率（岛被打光）& 打到盾概率
		    oo::commonOprModel('statistics')->attackChanceSta();
		}
		
		if($time == '007'){
			//当天用户分组人数
		    oo::commonOprModel('statistics')->todayUserGroupSta();
		}
		
		if($time%5 == 0){
			//创建流水表
            oo::commonOprModel('currency')->cronCreatAssessTable();
            //创建体力记录表
            oo::commonOprModel('currency')->cronCreatSpinsAddLowTable();
		}
		
		if($time == '008'){
			//FB留存
		    oo::commonOprModel('statistics')->recordDataFB();
		}
		if($time == '009'){
			//体力分布统计 每天
			oo::commonOprModel('statistics')->todaySpinsSta();
		}
		if($time == '010'){
			//老虎机关卡概率统计
		    oo::commonOprModel('statistics')->slotLevelStatistics('',1);
		}
		
		if($time == '015'){
			//宝藏探索数据统计
		    oo::commonOprModel('statistics')->treasureSlotSta();
		}
		
		if($time == '016'){
			//规则礼包统计 保存到数据库
		    oo::commonOprModel('statistics')->GiftEventSta();
		}
		
		if($time == '017'){
			//邀请事件上报 保存到数据库
		    oo::commonOprModel('statistics')->inviteEventSta();
		}
		
		if($time == '018'){
			//宝藏探索关卡统计 保存到数据库
		    oo::commonOprModel('statistics')->treasureSlotLevelSta();
		}
		
		if($time == '019'){
			//小丑卡统计 保存到数据库
		    oo::commonOprModel('statistics')->jokerCardSta();
		}

        if($time == '020'){
            //邮件统计
            oo::commonOprModel('statistics')->sendMailSta();
        }
        if($time == '021'){
            //每日体力盈亏统计 保存到数据库
            oo::commonOprModel('statistics')->todaySpinsAddLowSta2();
        }
        if($time == '022'){
            //好友召回统计 保存到数据库
            oo::commonOprModel('statistics')->friendRecallSta();
        }
        if($time == '023'){
            //统计特殊收集活动的特殊道具概率 保存到数据库
            oo::commonOprModel('statistics')->superCollectSta();
        }
        if($time == '024'){
            //redis 这一分钟可多设置几个定时器
            //后台增加老虎机体力统计/老虎机体力关卡概率统计
            oo::commonOprModel('statistics')->slotSpinsSta();
        }
        if($time == "035"){ //小游戏参与率统计
            oo::commonOprModel('statistics')->saveParticipation();
        }

        if($time == "055"){ //tradeplus分组统计
            oo::commonOprModel('tradeplus')->loopApiData();
        }

        if($time == '101'){
            //每日卡片发放产出统计 保存到数据库
            oo::commonOprModel('statistics')->cardGrantSta();
        }
        if($time == '102'){
            //好友召回留存统计
            oo::commonOprModel('statistics')->friendRecallremainSta();
        }
		
		oo::commonOprModel('report')->clientlog();
		
		logMessage('crontab',"crontab ".date("Ymd H:i:s"));
	}

    //转储到oos
    public function dbToOos($sql = '') {
        ini_set('max_execution_time', 3600);
        if(empty($sql)){
            exit("sql file error");
        }
        $res = oo::commonOprModel('common')->upToOss("database/{$sql}","/mnt2/database/{$sql}");
        if(!$res){
            exit("upload {$sql} data error");
        }
        exit("ok");
    }

    /**
     * 从oss下载到本地
     */
    public function ossToLocal($sql = '') {
        ini_set('max_execution_time', 3600);
        if(empty($sql)){
            exit("sql file error");
        }
        if(strrpos($sql, '.sql') === false){
            $sql = $sql.'.sql';
        }
        $res = oo::commonOprModel('common')->downloadFromOss("database/{$sql}","/mnt2/database/{$sql}");
        if(!$res){
            exit("upload {$sql} data error");
        }
        exit("ok");
    }

    public function assetsToCircle() {
        $date = date("Ymd");
        //$date = date("Ymd", time() - 86400);
        for($i = 0; $i < 10; $i++){
            $sql = 'INSERT INTO '.otable::Assetslog($date, $i).' (uid,type,num,crease,reason,time,last_num,rid,levelId)';
            $sql .= ' SELECT uid,type,num,crease,reason,time,last_num,rid,levelId FROM '.otable::Assetslog($date, -1) . ' WHERE uid % 10 = '.$i;
            oo::commonOprDb('log')->query($sql);
        }
    }

	//2号定时器
	public function crontablog(){
		set_time_limit(0);
        $random = mt_rand(1,100000);
		if(oo::commonOprRedis('Statistics')->setnxex(okeys::CrontabLock('crontablog'),$random,300)){
            //转盘流水落地
            oo::commonOprModel('asynclog')->cacheIntoDb();
            //先判断随机数，是同一个则删除锁
            if (oo::commonOprRedis('Statistics')->get(okeys::CrontabLock('crontablog')) == $random) {
                oo::commonOprRedis('Statistics')->delete(okeys::CrontabLock('crontablog'));
            }
        }else{
		    echo 'lock';
        }
		logMessage('crontab',"crontablog ".date("Ymd H:i:s"));
	}
	
	//3号定时器
	public function crontabPoint(){
		set_time_limit(0);
        $random = mt_rand(1,100000);
        if(oo::commonOprRedis('Statistics')->setnxex(okeys::CrontabLock('crontabPoint'),$random,300)){
            //埋点数据落地
            oo::commonOprModel('asynclog')->cacheIntoPointDb();
            //先判断随机数，是同一个则删除锁
            if (oo::commonOprRedis('Statistics')->get(okeys::CrontabLock('crontabPoint')) == $random) {
                oo::commonOprRedis('Statistics')->delete(okeys::CrontabLock('crontabPoint'));
            }
        }else{
            echo 'lock';
        }
		logMessage('crontab',"crontabPoint ".date("Ymd H:i:s"));
	}

	//删除数据
    function delLog($date = ''){
        oo::commonOprModel('currency')->delLog($date);
    }
	
	function is_cli(){
	    return preg_match("/cli/i", php_sapi_name()) ? true : false;
	}
}
