<?php

/**
 * 同步vip数据
 * User: ben
 * Date: 2018/10/28
 * Time: 下午2:08
 */
require_once realpath(dirname(__FILE__)) . '/../common.php';

if (!singleProcess(getCurrentCommand(), ROOT_PATH . "/bin/run/syncVip.pid")) {
    exit("Sorry, this script file has already been running ...\n");
}

//$GLOBALS['eosProtocol'] = 'https';
//$GLOBALS['eosHost'] = 'proxy.eosnode.tools';
//$GLOBALS['eosPort'] = 443;
//
//if ($GLOBALS['eosProtocol'] == 'https' && $GLOBALS['eosPort'] == 443) {
//    $GLOBALS['eosUrl'] = "{$GLOBALS['eosProtocol']}://{$GLOBALS['eosHost']}/";
//} else {
//    $GLOBALS['eosUrl'] = "{$GLOBALS['eosProtocol']}://{$GLOBALS['eosHost']}:{$GLOBALS['eosPort']}/";
//}

$objUserGroup = new TableHelper('user_group', 'dw_chat');
$objGroupEos = new TableHelper('group_eos', 'dw_chat');

$_where = "vip_info IS NOT NULL AND vip_info != ''";
$_field = "group_id, vip_info";
$rows = $objGroupEos->getAll(compact('_where', '_field'));

foreach ($rows as $row) {
    // {"code": "eosgetadmin1", "table": "vip", "account_field": "player", "vip_field": "vip_level", "amount_field": "total_bet_amount", "amount_rate": 10000, "index_position": 0}
    $vipInfo = json_decode($row['vip_info'], true);
    if (!$vipInfo) {
        Eos::log("skip error vip info. group_id: {$row['group_id']}, vip_info: {$row['vip_info']}");
        continue;
    }

    Eos::log("sync group_id: {$row['group_id']}.");
    syncVip($row['group_id'], $vipInfo);
}

function syncVip($group_id, $vipInfo) {
    $code = $vipInfo['code'];
    $table = $vipInfo['table'];
    $index_pos = $vipInfo['index_position'];
    $accountField = $vipInfo['account_field'];
    $vipField = $vipInfo['vip_field'];
    $amountField = $vipInfo['amount_field'];
    $amountRate = $vipInfo['amount_rate'];

    $lower = null;
    do {
        $ret = _getDatas($code, $table, $index_pos, $lower);
        $last = end($ret['rows']);

        $accounts = array_column($ret['rows'], $accountField);
        $map = _getUserMap($accounts);
        $user_ids = array_values($map);

        $vipMap = _getVipMap($group_id, $user_ids);

        $newAccountList = [];
        $newJoinList = [];
        $skipNum = 0;
        foreach ($ret['rows'] as $row) {
            $account = $row[$accountField];
            $user_id = $map[$account];
            $total_bet_amount = $row[$amountField] * $amountRate;
            if ($total_bet_amount < 10000) {
                $skipNum++;
                continue;
            }

            if (empty($user_id)) {
                $newAccountList[] = $account;
            } else {
                $info = $vipMap[$user_id];
                $vip_level = 0;
                if (!$vipField && $vipInfo['vip_config']) {
                    foreach ($vipInfo['vip_config'] as $i => $target) {
                        if ($total_bet_amount < $target) {
                            $vip_level = $i + 1;
                            break;
                        }
                    }
                } else {
                    $vip_level = $row[$vipField];
                }

                if ($info) {
                    // 已经加入群的老用户
                    if ($info['vip_level'] != $vip_level) {
                        _updateVip($user_id, $group_id, $vip_level);
                    } else if ($amountField && $amountRate) {
                        $total_bet_amount = $row[$amountField] * $amountRate;
                        if ($info['total_bet_amount'] != $total_bet_amount) {
                            _updateVip($user_id, $group_id, $vip_level, $total_bet_amount);
                        }
                    }
                } else {
                    // 还没加入群的老用户
                    $newJoinList[] = $user_id;
                }
            }
        }

        if ($newAccountList) {
            $newUserIds = _createAccount($newAccountList);
            // 加入官方群
            _joinGroup(10000, $newUserIds);

            $newJoinList = array_merge($newJoinList, $newUserIds);
        }

        // 这批没加入群的用户要拉入群
        if ($newJoinList) {
            _joinGroup($group_id, $newJoinList);
        }

        $rowNum = count($ret['rows']);
        $newAccountNum = count($newAccountList);
        $newAJoinNum = count($newJoinList);
        Eos::log("getData lower:{$lower}, rowNum:{$rowNum}, skipNum:{$skipNum}, newAccountNum:{$newAccountNum}, newAJoinNum:{$newAJoinNum}. ");

        $lower = $last[$accountField];
    } while($ret['more']);
}

/**
 * 批量创建账号，并返回user_id
 * @param $accounts
 *
 * @return array
 */
function _createAccount($accounts) {
    $datas = [];
    $type = 'eos';
    $user_names = [];
    // 创建用户，并加入到$newJoinList
    foreach ($accounts as $account) {
        $nick_name = User::getNewName($account);
        $user_name = $nick_name . '-' . strtoupper($type);
        $datas[] = [
            'first_type' => $type,
            'nick_name' => $nick_name,
            'user_name' => $user_name,
            'last_login_time' => NOW,
            'update_time' => NOW,
        ];
        $user_names[] = $user_name;
    }

    $objUserInfo = new TableHelper('user_info', 'dw_chat');
    $objUserInfo->addObjectsIfNoExist($datas);

    $rows = $objUserInfo->getAll(['user_name' => $user_names], ['_field' => 'user_id, user_name']);
    $datas2 = [];
    foreach ($rows as $row) {
        $parts = explode('-', $row['user_name']);
        $datas2[] = [
            'user_id' => $row['user_id'],
            'type' => $type,
            'account' => $parts[0],
            'create_time' => NOW,
        ];
    }

    $objUserBindInfo = new TableHelper('user_bind_info', 'dw_chat');
    $objUserBindInfo->addObjectsIfNoExist($datas2);

    return array_column($rows, 'user_id');
}

function _joinGroup($group_id, $user_ids) {
    global $objUserGroup;

    $datas = [];
    $sessDatas = [];
    foreach ($user_ids as $user_id) {
        $datas[] = [
            'user_id' => $user_id,
            'group_id' => $group_id,
            'join_time' => NOW,
            'update_time' => NOW,
            'state' => UserGroup::STATE_IN_GROUP,
        ];

        $sessDatas[] = [
            'user_id' => $user_id,
            'session_id' => $group_id,
            'is_group' => 1,
            'update_time' => NOW,
            'update_time_int' => TIME,
        ];
    }

    // 加入群
    $objUserGroup->addObjectsIfNoExist($datas);

    // 加入会话
    $objSession = new Session();
    $objSession->objTable->addObjectsIfNoExist($sessDatas);

    // 更新群的人数
    $member_num = $objUserGroup->getCount(['group_id' => $group_id, 'state' => 1]);
    $objGroupInfo = new GroupInfo();
    $objGroupInfo->objTable->updateObject(compact('member_num'), compact('group_id'));
}

function _updateVip($user_id, $group_id, $vip_level, $total_bet_amount = 0) {
    global $objUserGroup;

    $newData = compact('vip_level', 'total_bet_amount');
    $where = compact('user_id', 'group_id');
    $objUserGroup->updateObject($newData, $where);
}

function _getVipMap($group_id, $user_ids) {
    global $objUserGroup;

    $where = [
        'group_id' => $group_id,
        'user_id' => $user_ids,
        '_field' => 'user_id, vip_level, total_bet_amount'
    ];


    $map = $objUserGroup->getAll($where);
    $map = arrayFormatKey($map, 'user_id');

    return $map;
}

function _getUserMap($accounts) {
    $where = [
        'type' => 'eos',
        'account' => $accounts,
        '_field' => 'user_id, account'
    ];

    $objUserBindInfo = new TableHelper('user_bind_info', 'dw_chat');
    $map = $objUserBindInfo->getAll($where);
    $map = arrayFormatKey($map, 'account', 'user_id');

    return $map;
}

function _getDatas($code, $table, $index_pos = 0, $lower = null, $limit = 1000) {
    $cmd = "cleos -u {$GLOBALS['eosUrl']} get table {$code} {$code} {$table} --index {$index_pos} -l {$limit} ";
    if ($lower) {
        $cmd .= " -L '{$lower}' ";
    }

    $json = Eos::execCmd($cmd);
    $datas = json_decode($json, true);

    //        Eos::log("get {$code} {$table} lower:{$lower}, count:" . count($datas['rows']));

    return $datas;
}
