<?php
/**
 * 定时自动完成
 */
namespace Admin\Controller;
use Admin\Model\SpendModel;
use Think\Think;
use Base\Tool\Printer;
use Base\Tool\TaskClient;
use Base\Service\PromoteService;
use GuzzleHttp\Client;
use think\Db;
use Base\Task\Task;
use Base\Service\MarketService;
use Base\Tool\AggregateClient;
use Base\Repository\GameRepository;
use Base\Tool\Redis;
use Think\Model;

class ConsoleController extends Think {

    protected function _initialize()
    {
        C(api('Config/lists'));
    }

    public function modifyPromote()
    {
        $promotes = M('promote', 'tab_')->where(['parent_id' => 0])->select();
        foreach ($promotes as $promote) {
            $promote['chain'] = '/';
            $promote['level'] = 1;
            
            M('promote', 'tab_')->where(['id' => $promote['id']])->save(['chain' => '/', 'level' => 1]);

            $subPromote = $promote;
            unset($subPromote['id']);
            $subPromote['parent_id'] = $promote['id'];
            $subPromote['parent_name'] = $promote['account'];
            $subPromote['chain'] = $promote['chain'] . $promote['id'] . '/';
            $subPromote['level'] = $promote['level'] + 1;
            $subPromote['account'] = 'second_' . $promote['account'];
            $subPromote['nickname'] = '二级_' . $promote['nickname'];
            $subPromote['mobile_phone'] = '';
            $subPromote['email'] = '';
            $subPromote['real_name'] = '';
            $subPromote['money'] = 0;
            $subPromote['total_money'] = 0;
            $subPromote['balance_coin'] = 0;
            $subPromote['create_time'] = time();
            $subPromote['last_login_time'] = 0;
            $subPromote['idcard'] = '';
            M('promote', 'tab_')->add($subPromote);
            $subId = M()->getLastInsID();
            $subChain = $subPromote['chain'] . $subId . '/';
            M('promote', 'tab_')->where(['parent_id' => $promote['id'], 'id' => ['neq', $subId]])->save([
                'parent_id' => $subId,
                'parent_name' => $subPromote['account'],
                'chain' => $subChain,
                'level' => 3,
            ]);
            // echo M()->getLastSql() . "\n";
            M('promote', 'tab_')->where(['grand_id' => $promote['id']])->save([
                'chain' => ['exp', 'concat("' . $subChain. '",parent_id,"/")'],
                'level' => 4,
            ]);
            // echo M()->getLastSql() . "\n";
        }
    }

    public function runShiftTask()
    {
        $promoteService = new PromoteService();
        $tasks = M('shift_task', 'sys_')->where(['status' => 0, 'order_time' => ['elt', time()]])->select();
        if (count($tasks) == 0) {
            Printer::export('无可执行任务', true);
        }
        foreach ($tasks as $task) {
            if ($task['type'] == 1) {
                $message = '推广员迁移[' . $task['id'] . ']';
            } elseif ($task['type'] == 2) {
                $message = '玩家迁移[' . $task['id'] . ']';
            } else {
                $message = '未知类型迁移[' . $task['id'] . ']';
            }
            $result = $promoteService->shift($task);
            if ($result['status']) {
                $message = 'SUCCESS ----- ' . $message . $result['msg'];
            } else {
                $message = 'ERROR ----- ' . $message . $result['msg'];
            }
            Printer::export($message);
        }
    }

    public function runTask($queue = 'common', $count = 10)
    {
        Printer::export($queue);
        Printer::export($count);
        try {
            $task = new Task($queue);
            $task->run($count);
            Printer::export('运行完成');
        } catch (\Exception $e) {
            Printer::export($e->getMessage());
        }
    }

    public function addTask()
    {
        /* $id = M('market_shift', 'tab_')->add([
            'from_id' => 1,
            'to_id' => 2,
            'split_time' => 0,
            'created_time' => time()
        ]);
        $params = [
            'market_shift_id' => $id
        ]; */
        for ($i=0; $i<50; $i++) {
            Task::add('test', ['value' => $i]);
        }
    }

    public function testAggregate()
    {
        /* $client = new AggregateClient();
        $result = $client->api('game-data', ['unique_codes' => ['w123'], 'started_at' => '2019-06-27', 'ended_at' => '2020-07-27']);
        var_dump($result); */

        echo M('game', 'tab_')->where('id>2')->field(['id', 'game_name'])->where('sdk_version=1')->select(false);
    }

    public function initMarketAdmin()
    {
        $marketService = new MarketService();
        $promoteService = new PromoteService();
        $promotes = M('promote', 'tab_')->field(['id', 'admin_id', 'account', 'chain', 'level'])
            ->where(['level' => 1, 'admin_id' => ['gt', 0], 'company_belong' => ['in', [1, 2]]])
            ->select();
        foreach ($promotes as $promote) {
            Printer::export('处理会长: ' . $promote['account']);
            $subPromotes = $promoteService->getAllChildren($promote, 0, ['id']);
            $promoteIds = [$promote['id']];
            $promoteIds = array_merge(array_column($subPromotes, 'id'), $promoteIds);
            $marketService->shiftSpend($promoteIds, 0, $promote['admin_id']);
            $marketService->shiftDeposit($promoteIds, 0, $promote['admin_id']);
        }
    }

    public function initPromoteAdmin()
    {
        $promotes = M('promote', 'tab_')->field(['id', 'chain', 'level', 'admin_id'])->where(['level' => 1, 'admin_id' => ['gt', 0]])->select();
        foreach ($promotes as $promote) {
            M('promote', 'tab_')->where(['chain' => ['like', $promote['chain'] . $promote['id'] . '/%']])->save(['admin_id' => $promote['admin_id']]);
        }
    }

    public function modifyLoginRepair()
    {
        $this->modifyLogin(1569686400);
    }

    public function modifyLoginGenerate($start_time=0)
    {
        $start_time = $start_time ? $start_time : date('Y-m-d', strtotime('-1 day'));
        $this->modifyLogin(strtotime($start_time));
    }

    public function modifyLoginCheck($start_time=0, $end_time=0)
    {
        $start_time = $start_time ? strtotime($start_time) : strtotime(date("Y-m-d"));
        $end_time = $end_time ? strtotime($end_time) : $start_time;
        $this->modifyLogin($start_time, $end_time);
    }

    /**
     * 登录校验
     */
    private function modifyLogin($start_time=0, $end_time=0)
    {
        $current_time = $end_time?: strtotime(date("Y-m-d"))-86400;
        for ($i=$start_time; $i<=$current_time; $i+=86400) {
            $end_time = $i+86400;
            $result = M()->query("SELECT
                game_id,
                UNIX_TIMESTAMP(FROM_UNIXTIME(login_time, '%Y-%m-%d')) create_time,
                user_id,
                promote_id
                FROM
                    tab_user_login_record ulr
                WHERE
                    login_time >= {$i} and login_time < {$end_time}
                    AND NOT EXISTS (
                        SELECT
                            id
                        FROM
                            tab_login_daily_record ldr
                        where ldr.create_time >= {$i} and ldr.create_time < {$end_time} and ldr.game_id = ulr.game_id and ldr.user_id = ulr.user_id and ldr.promote_id = ulr.promote_id
                    )
                GROUP BY
                    create_time,
                    game_id,
                    user_id,
                    promote_id");
                if ($result) {
                    foreach ($result as $index => $item) {
                        if (is_null($result[$index]['promote_id']))
                        {
                            unset($result[$index]);
                        }
                    }
                    $step = 500;
                    for ($j=0;;$j+=$step) {
                        $insData = array_slice($result, $j, $step);
                        if ($insData) {
                            $res = M("login_daily_record", 'tab_')->addAll($insData);
                            echo "写入 $res \n";
                        } else {
                            break;
                        }
                    } 
                } else {
                    echo "写入{$item['create_time']} 无 \n";
                }
            }
    }

    public function deleteRepeatUserPlayInfo()
    {
        $gameIds = [157, 155, 153, 150, 151, 148, 175, 142, 143, 172, 173, 155, 154, 180];
        foreach($gameIds as $gameId) {
            $this->doDeleteRepeatUserPlayInfo($gameId);
        }
    }

    public function doDeleteRepeatUserPlayInfo($gameId)
    {
        $sql = 'select id from tab_user_play_info a left join (
            select role_id, server_id, game_id, count(1) from tab_user_play_info where server_id="' . $serverId . '" and game_id = ' . $gameId . ' GROUP BY role_id, server_id, game_id, server_name having count(1) > 1
            ) b on a.role_id=b.role_id where a.server_id=b.server_id and a.game_id=b.game_id and a.server_id="' . $serverId . '" and a.game_id = ' . $gameId . ' order by a.role_id, a.server_id, a.game_id';
        $model = new \Think\Model();

        $servers = M('server', 'tab_')->field('server_id')->where(['game_id' => $gameId])->group('server_id')->select();
        foreach ($servers as $server) {
            $serverId = $server['server_id'];
            $sql = 'select a.id, a.role_id, a.server_id, a.game_id, a.role_level from tab_user_play_info a left join (
                select role_id, server_id, game_id, count(1) from tab_user_play_info where server_id="' . $serverId . '" and game_id = ' . $gameId . ' GROUP BY role_id, server_id, game_id, server_name having count(1) > 1
                ) b on a.role_id=b.role_id where a.server_id=b.server_id and a.game_id=b.game_id and a.server_id="' . $serverId . '" and a.game_id = ' . $gameId . ' order by a.role_id, a.server_id, a.game_id';
            // var_dump($sql);

            $result = $model->query($sql);
            $uniqueRole = null;
            $items = [];
            foreach ($result as $item) {
                $items[$item['role_id']][] = $item;
            }

            $maxRoleIds = [];
            $repeatIds = [];
            foreach ($items as $roles) {
                $maxRole = null;
                foreach ($roles as $role) {
                    if ($maxRole == null) {
                        $maxRole = $role;
                    } elseif ($role['role_level'] > $maxRole['role_level']) {
                        $repeatIds[] = $maxRole['id'];
                        $maxRole = $role;
                    } else {
                        $repeatIds[] = $role['id'];
                    }
                }
                $maxRoleIds[] = $maxRole['id'];
            }
            if (count($repeatIds) > 0) {
                M('user_play_info', 'tab_')->where(['id' => ['in', $repeatIds], 'game_id' => $gameId, 'server_id' => $serverId])->delete();
                echo M()->getLastSql();
                echo PHP_EOL;
            }
        }
    }

    public function deleteRepeatUserPlayInfo2()
    {
        $gameIds = [157, 148, 150, 151, 158, 175, 142, 143, 172, 173, 154, 155, 176, 165, 164, 179, 156, 153, 180];
        foreach ($gameIds as $gameId) {
            $this->doDeleteRepeatUserPlayInfo2($gameId);
        }
    }

    public function doDeleteRepeatUserPlayInfo2($gameId)
    {
        $sql = 'select id from tab_user_play_info a left join (
            select role_id, server_id, game_id, count(1) from tab_user_play_info where server_id="' . $serverId . '" and game_id = ' . $gameId . ' GROUP BY role_id, server_id, game_id, server_name having count(1) > 1
            ) b on a.role_id=b.role_id where a.server_id=b.server_id and a.game_id=b.game_id and a.server_id="' . $serverId . '" and a.game_id = ' . $gameId . ' order by a.role_id, a.server_id, a.game_id';
        $model = new \Think\Model();

        $servers = M('server', 'tab_')->field('server_id')->where(['game_id' => $gameId])->group('server_id')->select();
        foreach ($servers as $server) {
            $serverId = $server['server_id'];
            $sql = 'select a.id, a.role_id, a.server_id, a.game_id, a.role_level from tab_user_play_info a left join (
                select role_id, server_id, game_id, count(1) from tab_user_play_info where server_id="' . $serverId . '" and game_id = ' . $gameId . ' GROUP BY role_id, server_id, game_id having count(1) > 1
                ) b on a.role_id=b.role_id where a.server_id=b.server_id and a.game_id=b.game_id and a.server_id="' . $serverId . '" and a.game_id = ' . $gameId . ' order by a.role_id, a.server_id, a.game_id';
            // var_dump($sql);

            $result = $model->query($sql);
            $uniqueRole = null;
            $items = [];
            foreach ($result as $item) {
                $items[$item['role_id']][] = $item;
            }

            $maxRoleIds = [];
            $repeatIds = [];
            foreach ($items as $roles) {
                $maxRole = null;
                foreach ($roles as $role) {
                    if ($maxRole == null) {
                        $maxRole = $role;
                    } elseif ($role['role_level'] >= $maxRole['role_level']) {
                        $repeatIds[] = $maxRole['id'];
                        $maxRole = $role;
                    } else {
                        $repeatIds[] = $role['id'];
                    }
                }
                $maxRoleIds[] = $maxRole['id'];
            }
            if (count($repeatIds) > 0) {
                M('user_play_info', 'tab_')->where(['id' => ['in', $repeatIds], 'game_id' => $gameId, 'server_id' => $serverId])->delete();
                echo M()->getLastSql();
                echo PHP_EOL;
            }
        }
    }

    public function resetIndexChart()
    {
        for ($i=1; $i<100; $i++) {
            $item = M('index_chart', 'tab_')->where(['id' => $i])->find();
            if ($item) {
                $item['new_user_hours'] = json_encode(unserialize($item['new_user_hours']));
                $item['active_user_hours'] = json_encode(unserialize($item['active_user_hours']));
                $item['active_user_list'] = json_encode(unserialize($item['active_user_list']));
                $item['pay_user_hours'] = json_encode(unserialize($item['pay_user_hours']));
                $item['pay_user_list'] = json_encode(unserialize($item['pay_user_list']));
                $item['pay_money_hours'] = json_encode(unserialize($item['pay_money_hours']));
                $item['promote_new_hours'] = json_encode(unserialize($item['promote_new_hours']));
                $item['all_count'] = json_encode(unserialize($item['all_count']));
                M("index_chart_1", "tab_")->add($item);
            }
        }
    }

    public function testLogin()
    {
        /* $client = new Client([
            'base_uri' => 'http://47.111.118.107:9501',
            'timeout'  => 10.0,
        ]);
        $response = $client->post('/game-event/login', [
            'form_params' => [
                'user_id' => 28747,
                'game_id' => 153,
                'login_time' => 1577361998
            ]
        ]);
        $result = (string)$response->getBody();
        echo $result; */

        $data = [
            'user_id' => 28747,
            'game_id' => 153,
            'login_time' => 1577361998
        ];
        $client = new Client([
            'base_uri' => 'http://47.111.118.107:9501',
            'timeout'  => 5.0,
        ]);
        $promise = $client->requestAsync('POST', '/game-event/login', [
            'form_params' => $data
        ]);
        $promise->then(
            function (ResponseInterface $res) {
                echo $res->getStatusCode() . PHP_EOL;
            },
            function (RequestException $e) {
                echo $e->getMessage() . PHP_EOL;
                echo $e->getRequest()->getMethod();
            }
        );
    }

    public function divideWarnCheck()
    {
        $redis = new \Org\RedisSDK\Redis(['host'=>'127.0.0.1','port'=>6379],[]);
        $warns = M('partner_divide_warn', 'tab_')->alias('pdw')
        ->field('pdw.*, cgr.ratio, sum(s.pay_amount) as total_amount, p.partner')
        ->join('tab_partner p on pdw.partner_id = p.id')
        ->join('tab_game g on pdw.partner_id = g.partner_id')
        ->join('tab_cp_game_ratio cgr on cgr.game_id = g.id and begin_total_amount = 0 and is_del = 0')
        ->join('tab_game_data s on s.game_id = g.id')
        ->where(['pdw.status'=>1])
        ->group('pdw.id')
        ->select();
        if (!$warns) return;
        $taskClient = new TaskClient();
        $current_time = date('Y-m-d H:i:s');
        foreach ($warns as $info) {
            if (!$info['ratio']) return;
            $total_amount = ceil(($info['ratio'] / 100) * $info['total_amount']);
            $cacheKey = "divide:warn:check:{$info['partner_id']}";
            if (!($lastStep = $redis->get($cacheKey))) {
                $lastStep = 0;
            }
            if ((intval($info['advance_amount']) - intval($total_amount)) <= $info['warming_amount']) {
                if ($total_amount - $lastStep >= $info['warn_frequency']) { // 达到预警
                    // 发送预警短信
                    $content = "{$info['partner']}的预付分成款已于{$current_time}余额不足{$info['warming_amount']}元,请尽快进行充值。";
                    $sendRes = $taskClient->sendSmsBatch(json_decode($info['phones'], true), $content);
                    if ($sendRes['code'] != TaskClient::SUCCESS) {
                        continue;
                    }
                    // 变换缓存值,如果为0,需要设置过期时间
                    if ($lastStep) {
                        $redis->set($cacheKey, $total_amount);
                    } else {
                        $redis->setex($cacheKey, 86400 * 30, $total_amount);
                    }
                }
            }
        }
    }


    public function coinRecords() {
        $deposit = M('deposit', 'tab_')->field('pay_order_number,user_id,user_account,pay_status,pay_way,pay_amount,create_time as pay_time,2 as record_type')->where(['pay_status'=>1])->select(false);
      //  $agent = M('agent', 'tab_')->field('pay_order_number,user_id,user_account,pay_status,pay_way,real_amount as pay_amount,create_time as pay_time,3 as record_type')->where(['pay_status'=>1])->select(false);
      //  $spend = M('spend', 'tab_')->field('pay_order_number,user_id,user_account,pay_status,pay_way,pay_amount,pay_time,1 as record_type')->where(['pay_status' => 1,'pay_way'=>0])->select(false);
        $query = M('spend', 'tab_')->field('pay_order_number,user_id,user_account,pay_status,pay_way,pay_amount,pay_time,1 as record_type')->where(['pay_status' => 1,'pay_way'=>0])->union($deposit,'pay_time')->select(false);
        $model = new \Think\Model();
        $datas = $model->table('(' . $query . ') a ')->order('pay_time asc')->select();
        foreach ($datas as $key => $data) {
            if(empty($data['pay_order_number'])) {
                $order = 0;
            }else {
                $order = $data['pay_order_number'];
            }
            $data['order_number'] = $order;
            $data['user_id'] = $data['user_id'];
            $data['value'] = $data['pay_amount'];
            $data['before_value'] = 0;
            $data['after_value'] = 0;
            $data['create_time'] = $data['pay_time'];
            if ($data['record_type'] == 1) {
                $data['type'] = 'spend';
                $data['remark'] ='历史消费spend';
                $data['pay_type'] = 1;
                $data['value'] = -$data['pay_amount'];
            }
            if ($data['record_type'] == 2) {
                $data['type'] = 'deposit';
                $data['remark'] ='历史充值deposit';
                $data['pay_type'] = 2;
                $data['value'] = $data['pay_amount'];
            }

            
            M('value_detail_log', 'tab_')->add($data);
        }
        echo "success";
    }


    public function updateValue() {
        //$map['type'] = ['neq', '2'];
        $valueDetails = M('value_detail_log', 'tab_')->field('user_id')->where($map)->group('user_id')->select();
        foreach ($valueDetails as $key => $valueDetail) {
            $user_id = $valueDetail['user_id'];
            $map['user_id'] = $user_id;
            $userValues = M('value_detail_log', 'tab_')->where($map)->select();
            $currentValue = 0;
            foreach ($userValues as $userValue) {
                $id = $userValue['id'];
                $userValue['before_value'] = $currentValue;

                $userValue['after_value'] = $currentValue + $userValue['value'];
                M('value_detail_log', 'tab_')->where(['id' => $id])->save($userValue);
                $after_update = M('value_detail_log', 'tab_')->where(['id'=>$id])->find();
                $currentValue = $after_update['after_value'];
            }
        }
        
    }

    public function arpu()
    {
        $start = I('start', date('Y-m-d'));
        $end = I('end', date('Y-m-d'));
        $gameIds = I('game_ids', '');
        $startTime = strtotime($start . ' 00:00:00');
        $endTime = strtotime($end . ' 23:59:59');
        $gameIdRows = explode(',', $gameIds);

        // 新增用户

        /* M('user', 'tab_')
            ->field('count(*) count, FROM_UNIXTIME(register_time, "%Y-%m-%d") date')
            ->where([
                'game_id' => ['in', $gameIdRows], 
                'register_time' => ['between', [$startTime, $endTime]]
            ])
            ->group('date')
            ->select(); */

        $newUsers = M('user_play', 'tab_')
            ->field('count(DISTINCT user_id) count, FROM_UNIXTIME(create_time, "%Y-%m-%d") date')
            ->where([
                'game_id' => ['in', $gameIdRows], 
                'create_time' => ['between', [$startTime, $endTime]]
            ])
            ->group('date')
            ->select();
        $newUsers = index_by_column('date', $newUsers);

        // 活跃用户
        $loginUsers = M('login_daily_record', 'tab_')
            ->field('count(DISTINCT user_id) count, FROM_UNIXTIME(create_time, "%Y-%m-%d") date')
            ->where([
                'game_id' => ['in', $gameIdRows], 
                'create_time' => ['between', [$startTime, $endTime]]
            ])
            ->group('date')
            ->select();
        $loginUsers = index_by_column('date', $loginUsers);

        // 付费玩家,付费金额
        $payLogs = M('spend', 'tab_')
            ->field('count(DISTINCT user_id) count, sum(pay_amount) amount, FROM_UNIXTIME(pay_time, "%Y-%m-%d") date')
            ->where([
                'game_id' => ['in', $gameIdRows], 
                'pay_time' => ['between', [$startTime, $endTime]],
                'pay_status' => 1,
            ])
            ->group('date')
            ->select();
        $payLogs = index_by_column('date', $payLogs);

        // 起始时间前的总充值金额
        /* $beforePayAmount =M('spend', 'tab_')
            ->where([
                'game_id' => ['in', $gameIdRows], 
                'pay_time' => ['lt', $startTime],
                'pay_status' => 1,
            ])
            ->sum('pay_amount'); */
        
        $rows = [];
        for ($time = $startTime; $time < $endTime; $time = $time + 24*3600) {
            $date = date('Y-m-d', $time);
            $newUser = isset($newUsers[$date]) ? $newUsers[$date]['count'] : 0;
            $loginUser = isset($loginUsers[$date]) ? $loginUsers[$date]['count'] : 0;
            $payAmount = isset($payLogs[$date]) ? $payLogs[$date]['amount'] : 0;
            $payUser = isset($payLogs[$date]) ? $payLogs[$date]['count'] : 0;
            $rows[] = [
                'date' => $date,
                'new_user' =>  $newUser,
                'login_user' => $loginUser,
                'pay_amount' => $payAmount,
                'pay_user' => $payUser,
                'pay_rate' => $loginUser > 0 ? (round($payUser / $loginUser * 100, 2) . '%') : '--',
                'arpu' => $loginUser > 0 ? (round($payAmount / $loginUser, 2)) : '0.00',
                'arppu' => $payUser > 0 ? (round($payAmount / $payUser, 2)) : '0.00',
            ];
        }

        $thml = '';
        $html .= '<table>' . PHP_EOL;
        $html .= '<tr>' . PHP_EOL;
        $html .= '<th>日期</th><th>新增用户</th><th>活跃玩家</th><th>充值金额</th><th>付费玩家</th><th>付费率</th><th>ARPU</th><th>ARPPU</th>' . PHP_EOL;
        $html .= '</tr>' . PHP_EOL;
        foreach ($rows as $row) {
            $html .= '<tr>' . PHP_EOL;
            $html .= '<td>' . $row['date'] . '</td>' . PHP_EOL;
            $html .= '<td>' . $row['new_user'] . '</td>' . PHP_EOL;
            $html .= '<td>' . $row['login_user'] . '</td>' . PHP_EOL;
            $html .= '<td>' . $row['pay_amount'] . '</td>' . PHP_EOL;
            $html .= '<td>' . $row['pay_user'] . '</td>' . PHP_EOL;
            $html .= '<td>' . $row['pay_rate'] . '</td>' . PHP_EOL;
            $html .= '<td>' . $row['arpu'] . '</td>' . PHP_EOL;
            $html .= '<td>' . $row['arppu'] . '</td>' . PHP_EOL;
            $html .= '</tr>' . PHP_EOL;
        }
        $html .= '<table>' . PHP_EOL;
        echo $html;

        // 付费率 (当日充值用户数/当日活跃用户数)
        // ARPU (当日充值金额/当日活跃用户数)
        // ARRPU (当日充值金额/当日充值用户数)
    }
    
    public function checkAndfreezeTestingUser()
    {
        $pageCount = 100;
        $hasNext = true;
        $lastId = 0;
        do {
            $testingUsers = M('testing_user', 'tab_')
                ->where(['status' => ['in', [1, 2]], 'id' => ['gt', $lastId]])
                ->order('id asc')
                ->limit($pageCount)
                ->select();
            if (count($testingUser) < $pageCount) {
                $hasNext = false;
            }
            $userIds = array_column($testingUsers, 'user_id');
            $users = M('user', 'tab_')->field(['id', 'account', 'login_time'])->where(['id' => ['in', $userIds]])->select();
            $users = index_by_column('id', $users);
            $unloginLimitTime = 7 * 24 * 3600;
            $unloginUserIds = [];
            foreach ($testingUsers as $testingUser) {
                $user = $users[$testingUser['user_id']] ?? null;
                if ($user && (time() - $user['login_time']) > $unloginLimitTime) {
                    $unloginUserIds[] = $user['id'];
                }
                $lastId = $testingUser['id'];
            }
            if (count($unloginUserIds) > 0) {
                M('testing_user', 'tab_')->where(['user_id' => ['in', $unloginUserIds]])->save([
                    'status' => 3
                ]);
            }
        } while($hasNext);
    }

    public function statUserRetention()
    {
        $begin = I('begin', date('Y-m-d'));
        $end = I('end', date('Y-m-d'));
        $baseGameId = I('base_game_id', 0);

        $repository = new GameRepository();
        $baseGame = M('base_game', 'tab_')->where(['id' => $baseGameId])->find();

        $beginDate = strtotime($begin);
        $endDate = strtotime($end);
        $dayTime = 24 * 3600;

        $trs = '';
        for ($date = $beginDate; $date <= $endDate; $date = $date + $dayTime) {
            $dateStr = date('Y-m-d', $date);
            $userRegisterCount = $repository->getUserRegisterCount($baseGame, $dateStr);
            $userRetentionCount60 = $repository->getUserRetentionCount($baseGame, $dateStr, 60);
            $userRetentionCount90 = $repository->getUserRetentionCount($baseGame, $dateStr, 90);
            $trs .= '<tr>' . PHP_EOL;
            $trs .= '<td>' . $dateStr . '</td>' . PHP_EOL;
            $trs .= '<td>' . $userRegisterCount . '</td>' . PHP_EOL;
            $trs .= '<td>' . $userRetentionCount60 . '</td>' . PHP_EOL;
            $trs .= '<td>' . $userRetentionCount90 . '</td>' . PHP_EOL;
            $trs .= '<td>' . round($userRetentionCount60 / $userRegisterCount * 100, 2) . '%' . '</td>' . PHP_EOL;
            $trs .= '<td>' . round($userRetentionCount90 / $userRegisterCount * 100, 2) . '%' . '</td>' . PHP_EOL;
            $trs .= '</tr>'. PHP_EOL;
        }
        echo '<table>'  . PHP_EOL . $trs . '</table>';
    }

    public function generateHistoryGame()
    {
        $items = M('spend', 'tab_')
            ->field(['tab_promote.level1_id', 'group_concat(distinct tab_spend.game_id) game_ids'])
            ->join('left join tab_promote on tab_spend.promote_id=tab_promote.id')
            ->where('tab_spend.is_check=1 and tab_spend.pay_status=1')
            ->group('tab_promote.level1_id')
            ->select();
        foreach ($items as $item) {
            if ($item['level1_id']) {
                $key = Redis::getKey('promote_history_games', ['promote_id' => $item['level1_id']]);
                Redis::set($key, $item['game_ids']);
            }
        }
    }

    public function updateHistoryGame()
    {
        $items = M('spend', 'tab_')
            ->field(['tab_promote.level1_id', 'group_concat(distinct tab_spend.game_id) game_ids'])
            ->join('left join tab_promote on tab_spend.promote_id=tab_promote.id')
            ->where('tab_spend.is_check=1 and tab_spend.pay_status=1 and tab_spend.pay_time>' . strtotime(date('Y-m-d 00:00:00')))
            ->group('tab_promote.level1_id')
            ->select();
        foreach ($items as $item) {
            if ($item['level1_id']) {
                $key = Redis::getKey('promote_history_games', ['promote_id' => $item['level1_id']]);
                $value = Redis::get($key);
                $gameIds = $value ? explode(',', $value) : [];
                $nowGameIds = explode(',', $item['game_ids']);
                $gameIds = array_unique(array_merge($gameIds, $nowGameIds));
                Redis::set($key, implode(',', $gameIds));
            }
        }
    }

    public function generatePromotesLevelId()
    {
        $promotes = M('promote', 'tab_')->field(['chain', 'id'])->select();
        foreach ($promotes as $promote) {
            $fullChain = explode('/', $promote['chain'] . $promote['id']);
            M('promote', 'tab_')->where(['id' => $promote['id']])->save([
                'level1_id' => $fullChain[1] ?? 0,
                'level2_id' => $fullChain[2] ?? 0,
                'level3_id' => $fullChain[3] ?? 0,
                'level4_id' => $fullChain[4] ?? 0,
            ]);
        }
    }

    public function setUserFirstPayTime()
    {
        $hasNext = true;
        $limit = 500;
        $lastId = 0;
        do {
            $items = M('spend', 'tab_')
                ->field(['user_id', 'min(pay_time) first_pay_time'])
                ->where(['pay_status' => 1, 'user_id' => ['gt', $lastId]])
                ->group('user_id')
                ->order('user_id asc')
                ->limit($limit)
                ->select();
            
            $model = new Model();
            $model->startTrans();
            foreach ($items as $item) {
                M('user', 'tab_')->where(['id' => $item['user_id']])->save([
                    'first_pay_time' => $item['first_pay_time']
                ]);
                $lastId = $item['user_id'];
            }
            $model->commit();

            if (count($items) < $limit) {
                $hasNext = false;
            }
        } while($hasNext);
    }

    /* public function shiftPromote()
    {
        $service = new PromoteService();
        $fromPromoteId = 0;
        $fromCompanyId = 0;
        $toPromoteId = 0;
        $toCompanyId = 0;
        $adminId = 0;
        $service->shiftPromote([
            'from_promote_id' => $fromPromoteId,
            'to_promote_id' => $toPromoteId,
            'shift_ids' => '',
        ]);
        M('promote', 'tab_')->where(['level1_id' => $fromPromoteId, 'company_id' => $fromCompanyId])->save([
            'company_id' => $toCompanyId,
            'admin_id' => $adminId
        ]);
    } */
}