<?php

use AlibabaCloud\SDK\Cms\V20190101\Cms;
use AlibabaCloud\SDK\Cms\V20190101\Models\DescribeMetricLastRequest;
use Darabonba\OpenApi\Models\Config;

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

/**
* 统计在线在玩
*/
class ModelRecordonline
{
	
	protected $gameidList = array(1, 2, 3, 4);//0代表在线不在玩
    private   $_onlineLoopTime = 12;//查看在线用户循环的时间

    /**
     * Notes:每分钟记录在线数
     * User: wsc
     * Time: 2020/12/10 17:07
     */
    public function setOnlenCount($ts = 0,  $online = 0){
//        $onlines = oo::commonOprModel('workerman')->getAllUidList();
//        $online = $this->getAliMonitor(__METHOD__);//count($onlines);
        $key = okeys::onlineCountLog();
        $first =false;
        if(!oo::commonOprRedis('statistics')->exists($key)){
            $first =true;
        }
        $ts = empty($ts) ? timeFuns::todaySecond() : $ts;
        oo::commonOprRedis('statistics')->hSet($key,$ts,$online);
        if($first){
            oo::commonOprRedis('statistics')->expire($key,oo::redisRandomExpire(86400*7));
        }
//        $this->crazyAbRecord($ts, $onlines);
        return $online;
    }

    /**
     * ab分组在线统计(wsc-2021.10.23弃用)
     * @param int $ts
     * @return bool
     */
    public function crazyAbRecord($ts, $onlines = []){
        $onlines = empty($onlines) ? oo::commonOprModel('workerman')->getAllUidList() : $onlines;
		//玩家在线人数加入redis
        $arr = [];
        //ab分组数据
        $abGroupArr = oo::commonOprRedis('common')->hMget(okeys::UserAbTest(), array_values($onlines));
        foreach($abGroupArr as $uid => $key){
            if(empty($key) || $key < 1){
                $key = 'D';
            }elseif($key > 2){
                $key = 'C';
            }else{
                $key = $key == '1' ?  'A' : 'B';
            }
            $arr[$key] = empty($arr[$key]) ? 1 : $arr[$key] + 1;
        }
        $ts = empty($ts) ? timeFuns::todaySecond() : $ts;
        foreach($arr as $key => $v){
            $key = date('Ymd', time()).'-'.$key;
            $first = !oo::commonOprRedis('statistics')->exists($key) ? true : false;
            oo::commonOprRedis('statistics')->hSet(okeys::onlineplaying($key),$ts,$v);
            if($first){ //保留7天数据
                oo::commonOprRedis('statistics')->expire(okeys::onlineplaying($key), 86400*7);
            }
        }
        return true;
    }
	
  	public function crazyRecord($now, $onlineNum){
        //获取在线玩家
//        $online = oo::commonOprModel('workerman')->getAllUidList();
//        $onlineNum = $this->getAliMonitor(__METHOD__);//count($online);
        //玩家在线人数加入redis

        $lastNum = intval(oo::commonOprRedis('statistics')->get(okeys::onlineusernum()));
        if(empty($onlineNum))$onlineNum = $lastNum;
        oo::commonOprRedis('statistics')->hSet(okeys::onlineplaying(1),$now,$onlineNum);
        oo::commonOprRedis('statistics')->set(okeys::onlineusernum(), $onlineNum);

//        return;
        //获取当天的最大在线数
        $date = date('Ymd', $now);
        $maxnumKey = okeys::onlineusermaxnum($date);
        $maxnum = intval(oo::commonOprRedis('statistics')->get($maxnumKey));
        if($onlineNum > $maxnum) {//记录当天的最大在线数
            oo::commonOprRedis('statistics')->set($maxnumKey, $onlineNum);
            oo::commonOprRedis('statistics')->expireAt($maxnumKey, oo::redisRandomExpire(strtotime("+2 days 23:59:59")));
        }


        $date = date('Y-m-d H:i');
        if($onlineNum < ceil($lastNum*0.5)){
            oo::commonOprModel('Enwechat')->send("【警报】FOX {$date} :5分钟内在线人数下降超过50%，由{$lastNum}人下降到{$onlineNum}人",[],[],1);
//                oo::commonOprModel('Enwechat')->send("【警报】FOX {$date} :5分钟内在线人数下降超过50%，由{$lastNum}人下降到{$onlineNum}人",[],[],1);
        }else if($onlineNum < ceil($lastNum*0.7)){
            oo::commonOprModel('Enwechat')->send("【警报】FOX {$date} :5分钟内在线人数下降超过30%，由{$lastNum}人下降到{$onlineNum}人",[],[],1);
//                oo::commonOprModel('Enwechat')->send("【警报】FOX {$date} :5分钟内在线人数下降超过30%，由{$lastNum}人下降到{$onlineNum}人",[],[],1);
        }else if($onlineNum < ceil($lastNum*0.9)){
//            if(($lastNum - $onlineNum) > 200){ //下滑超过200人才报警
                oo::commonOprModel('Enwechat')->send("【警报】FOX {$date} :5分钟内在线人数下降超过10%，由{$lastNum}人下降到{$onlineNum}人",[],[],1);
//            }
        }
//        elseif($lastNum - $onlineNum > 400){
//            $date = date('Y-m-d H:i');
//            oo::commonOprModel('Enwechat')->send("【警报】{$date} :5分钟内在线人数下降超过300人，由{$lastNum}人下降到{$onlineNum}人",[],[],1);
//        }
        /*
        $table = otable::onlineplaying();
        $sql = " INSERT INTO {$table}(ol_total, recordtime, gameid) VALUES({$onlineNum},{$now}, 1) ";
        oo::commonOprDb('common')->query($sql);
		*/
		//玩家在线人数加入redis
        oo::commonOprRedis('statistics')->hSet(okeys::onlineplaying(1),$now,$onlineNum);
		
//        self::loginMonitor();
    }

    public function getAliMonitor($method = '', $tryTimes = 0, $isActivite = true){
        $tryTimes++;
        try{
            $time = time();
            $accessKeyId = 'LTAI5tANQSEUhQE9JAfwwHEY';
            $accessKeySecret = 'b0FXaWdgUbWTm2cED0nhKfQAZhgrVN';
            $config = new Config([
                "accessKeyId" => $accessKeyId,
                "accessKeySecret" => $accessKeySecret
            ]);
            // 访问的域名
            $config->endpoint = "metrics.cn-hangzhou.aliyuncs.com";

            $client = new Cms($config);
            $dimensions = [
                [
                    'instanceId' => 'lb-0xit9qxfipdrir7mp7za3',
                    'port' => '8282',
                ],
                [
                    'instanceId' => 'lb-0xii7gpzz1yhoqwt6n54v',
                    'port' => '8282',
                ],
                [
                    'instanceId' => 'lb-0xi150md3kw771ogor7wj',
                    'port' => '8282',
                ],
                [
                    'instanceId'=>'lb-0xi6u8dr6pa36pukbilm5',
                    'port' => '8282',
                ],
                [
                    'instanceId'=>'lb-0xi6cb3w46sthz2gywxzh',
                    'port' => '8282',
                ]
            ];
            $describeMetricLastRequest = new DescribeMetricLastRequest([
                "namespace" => "acs_slb_dashboard",
                "metricName" => $isActivite ? "ActiveConnection" : 'InactiveConnection',
                "dimensions" => json_encode($dimensions),
            ]);
            $result = $client->describeMetricLast($describeMetricLastRequest);
            $json = $result->body->datapoints;
        }catch(\throwable $e){
            oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes, 'time' => date('Ymd H:i', $time), 'msg' => $e->getMessage()], 'getAliMonitorError.log');
            if($tryTimes<10)return $this->getAliMonitor($method, $tryTimes);
            return 0;
        }
        // 复制代码运行请自行打印 API 的返回值
        $online = 0;
        $data = @json_decode($json, true);
        foreach ($data as $item){
            $online+=$item['Average'];
        }
        if(empty($online)){
            oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes,  'time' => date('Ymd H:i', $time), 'response' => $result->body], 'getAliMonitor.log');
        }
        oo::logs()->debug3(['called location' => $method, 'tryTimes' => $tryTimes,  'time' => date('Ymd H:i', $time), 'online' => $online], 'getAliMonitor.log');
        return $online;
    }

    /**
     * 登录监控
     * Created by: Owen
     * Created on: 2020/4/24 19:54
     */
    public function loginMonitor(){
        $second = timeFuns::todaySecond();
        $cacheKey = okeys::LoginMonitor(1);
        $curKey = intval($second/5) - 1;
        if($curKey == -1){
            $curKey = 287; //读取前一天最后一个点数据,如果没有则读取当天0点数据
            $loginNum = oo::commonOprRedis('common')->hGet($cacheKey,$curKey);
            $loginNum = empty($loginNum) ? oo::commonOprRedis('common')->hGet($cacheKey, 0) : $loginNum;
        }else{
            $loginNum = oo::commonOprRedis('common')->hGet($cacheKey,$curKey);
        }

        if(!$loginNum){
            $date = date('Y-m-d H:i:s');
            !IS_DEBUF && oo::commonOprModel('Enwechat')->send("【警报】{$date} -- 安卓端：5分钟内登录人数为0",[],[],1);
        }
    }

    /**
     * 登录监控AB分组
     */
    public function loginMonitorAb(){
        $mkey = "MONITORABTEST";
        $time = (int)oo::commonOprRedis('statistics')->get($mkey);
        /////////////////////////////////
        //$time = 0;
        /////////////////////////////////
        $min = $time ? $time % 60 : 0;
        $hour = $time ? floor(($time) / 60) : 0;
        $dayTime = date('Y-m-d ', time()).sprintf('%02d', $hour).':'.sprintf('%02d', $min).':00';
        $day = date('Ymd');
        $stamp = strtotime($dayTime);
        $endStamp = strtotime(date('Y-m-d H:i:00', time()));
        /////////////////////////////////
        //$stamp = $stamp - 86400;
        //$endStamp = $endStamp + 86400;
        //$day = $day - 1;
        ////////////////////////////////
        $tb = otable::LoginLog($day);
        $sql = "SELECT uid FROM {$tb} Where ts >= {$stamp} AND ts < {$endStamp}";
        $tmpArr = oo::commonOprDb('statistics')->getAll($sql, 1);
        $uids = [];
        foreach($tmpArr as $val){
            if(!in_array($val['uid'], $uids)){
                $uids[] = $val['uid'];
            }
        }
        //ab分组数据
        $abGroupArr = oo::commonOprRedis('common')->hMget(okeys::UserAbTest(), $uids);

        $arr = [];
        foreach($abGroupArr as $uid => $key){
            if(empty($key) || $key < 1){
                $key = 'D';
            }elseif($key > 2){
                $key = 'C';
            }else{
                $key = $key == '1' ?  'A' : 'B';
            }
            if(empty($arr[$key])){
                $arr[$key] = [$uid];
            }
            $arr[$key][] = $uid;
        }

        foreach($arr as $key => $uids){
            $uidStr = implode(',', $uids);
            $sql = "UPDATE {$tb} SET ab = '{$key}' WHERE uid in ({$uidStr})";
            oo::commonOprDb('statistics')->query($sql);
        }
        oo::commonOprRedis('statistics')->setex($mkey, $stamp, 86400);
        return true;
    }

    /**
     * 15分钟检查一次谷歌支付是否正常
     */
    public function checkGooglePayStatus() {
        $tb = otable::summarylist();
        $time = time() - 900;
        $subOrders = "801,802,803";
        $sql = "SELECT COUNT(*) as count FROM {$tb} WHERE sl_sid = 1 AND sl_status = 2 AND sl_pay_time >= {$time} AND sl_gid NOT IN({$subOrders})";
        $ret = oo::commonOprDb('payment')->getOne($sql, 1);
        if(empty($ret['count'])){
            $date = date('Ymd', time());
            !IS_DEBUF && oo::commonOprModel('Enwechat')->send("【警报】{$date} :谷歌支付15分钟内没有成功支付订单了！",[],[],1);
        }
    }

    // fox 实时在线统计
    public function saveFoxRealTimeOnline($timestamp = 0, $onlineCnt = 0){
        $timestamp = empty($timestamp) ? time() : $timestamp ;
        $date = date('Ymd', $timestamp);
//        $start = $timestamp - 61;
//        $onlineCnt = $this->getAliMonitor(__METHOD__);//oo::commonOprRedis('common')->zCount(okeys::foxRealTimeOnlineKey(),$start, $timestamp);
        oo::commonOprRedis('statistics')->hSet(okeys::foxOnlineSummaryKey($date),$timestamp, $onlineCnt);

        $hi = date('Hi', $timestamp);
        if($hi == '0030'){
            // 上一天fox在线信息入库
            $yesterday = date('Ymd', $timestamp - 86400);
            $ret = oo::commonOprRedis('statistics')->hGetAll(okeys::foxOnlineSummaryKey($yesterday));
            $data['1'] = $ret;
            $data = json_encode($data,JSON_NUMERIC_CHECK);
            $tb = otable::staData();
            $type = 'foxOnlinePlaying';
            $sql = "INSERT INTO {$tb} VALUES('{$yesterday}', '{$type}' ,'{$data}')";
            oo::commonOprDb('statistics')->query($sql);
            oo::commonOprRedis('statistics')->delete(okeys::foxOnlineSummaryKey($yesterday));
        }
    }

    public function cardAssertSummary($timestamp, $type = 1){
        ini_set('memory_limit', -1);
        $date = date('Ymd', $timestamp - 86400);
        $cardInfoTbl = otable::cardinfo_config();
        $cardInfo    = oo::commonOprDb('common')->getAll("select * from {$cardInfoTbl}",1);
        $cardInfo = array_column($cardInfo, null, 'ciid');
        $sql = "select * from (  ";
        for ($i = 0;$i<10;$i++){
            $table = otable::AssetslogNew($date, $i);
            $sql .= "select * from {$table} where type='card'  ";
            if($date >= '20211109'){
                $sql .= " and game_version ={$type} ";
            }
            $sql .="  union all ";
        }
        $sql = rtrim($sql, 'union all ');
        $sql .= " ) t1 ";
        $result = oo::commonOprDb('statistics')->getAll($sql,1);
        $cardSummary = [
            '木质宝箱' => [
                'count' => 0,
                'total' => 0,
                'rank1' => 0,
                'rank2' => 0,
                'rank3' => 0,
                'rank4' => 0,
                'rank5' => 0,
                'golden' => 0,
            ],
            '白银宝箱' => [
                'count' => 0,
                'total' => 0,
                'rank1' => 0,
                'rank2' => 0,
                'rank3' => 0,
                'rank4' => 0,
                'rank5' => 0,
                'golden' => 0,
            ],
            '黄金宝箱' => [
                'count' => 0,
                'total' => 0,
                'rank1' => 0,
                'rank2' => 0,
                'rank3' => 0,
                'rank4' => 0,
                'rank5' => 0,
                'golden' => 0,
            ],
            '小丑宝箱获得' => [
                'count' => 0,
                'total' => 0,
                'rank1' => 0,
                'rank2' => 0,
                'rank3' => 0,
                'rank4' => 0,
                'rank5' => 0,
                'golden' => 0,
            ],
            '皮肤宝箱' => [
                'count' => 0,
                'total' => 0,
                'rank1' => 0,
                'rank2' => 0,
                'rank3' => 0,
                'rank4' => 0,
                'rank5' => 0,
                'golden' => 0,
            ],
        ];
        foreach ($result as $k => $item){
            if(!strpos($item['reason'], ':'))continue;
            list($chest, $cardStrs) = explode(':', $item['reason']);
            if(empty($cardSummary[$chest]))continue;
            $cardsIds = explode(',', $cardStrs);
            $cardSummary[$chest]['count']++;
            foreach ($cardsIds as $ciid){
                if(empty($cardInfo[$ciid]))continue;
                $cardSummary[$chest]['total']++;
                $cardSummary[$chest]['rank'.$cardInfo[$ciid]['ci_star_rank']]++;
                if($cardInfo[$ciid]['grade'] == 2)$cardSummary[$chest]['golden']++;
            }
        }
        $data = json_encode($cardSummary, JSON_UNESCAPED_UNICODE);
        $tb = otable::cardAssertSummary();
        $sql = "INSERT INTO {$tb} (`date`, `game_version`, `data`)  VALUES('{$date}', '{$type}' ,'{$data}')";
        $res = oo::commonOprDb('statistics')->query($sql);
        return $res;


    }
}
