<?php

/**
 * 用户基础信息
 * @author benzhan
 */
class User extends Singleton {

    const REDIS_USER_ID_HASH = 'globals:user_id_hash';

    private static $userInfo = null;

    public static function checkLogin() {
        $userInfo = self::getInfo();
        return $userInfo;
    }

    public static function getUserId() {
        $userInfo = self::getInfo();
        return $userInfo['user_id'] ?: 0;
    }

    public static function getUserName() {
        $user_id = self::getUserId();
        $user_name = self::getUserNameById($user_id);
        return $user_name;
    }

    public static function getInfo() {
        if (self::$userInfo) {
            return self::$userInfo;
        }

        $flag = Account::checkToken();
        if ($flag) {
//            if ($_REQUEST['token'] && $_REQUEST['user_id']) {
//                $token = $_REQUEST['token'];
//                $user_id = $_REQUEST['user_id'];
//            } else {
//                $token = $_COOKIE['token'];
//                $user_id = $_COOKIE['user_id'];
//            }

            $token = $_REQUEST['token'];
            $user_id = $_REQUEST['user_id'];

            self::$userInfo = compact('user_id', 'token');
            //            self::$userInfo['user_id'] = self::getUserIdByName(self::$userInfo['user_id']);
            return self::$userInfo;
        } else {
            return [];
        }
    }

    /**
     * 获取用户名
     * @author solu
     * @param $user_id
     * @return string
     */
    public static function getUserNameById($user_id) {
        $objRedis = dwRedis::init();
        $userName = $objRedis->hGet(self::REDIS_USER_ID_HASH, $user_id);
        if (!$userName) {
            $objUser = new TableHelper('user_info', 'dw_chat');
            $userName = $objUser->getOne(['user_id' => $user_id], ['_field' => 'nick_name']);
            if ($userName) {
                self::setUserNameById($user_id, $userName, $objRedis);
            }
        }

        return $userName;
    }

    public static function setUserNameById($user_id, $user_name, $objRedis = null) {
        !$objRedis && $objRedis = dwRedis::init();
        $objRedis->hSet(self::REDIS_USER_ID_HASH, $user_id, $user_name);
    }

    /**
     * 获取用户信息
     * @param $user_id
     *
     * @return array
     */
    public static function getUserInfoById($user_id) {
        $_field = 'user_id, user_name, nick_name, cover_photo';

        $objUser = new TableHelper('user_info', 'dw_chat');
        $userInfo = $objUser->getRow(compact('user_id'), compact('_field'));

        return $userInfo;
    }

    /**
     * 用户登录（首次登录创建用户）
     * @author benzhan
     * @param $account
     * @param string $type
     * @param $name
     */
    public static function login($account, $type = 'eos', $name = '') {
        $where = compact('account');

        $objUserBindInfo = new TableHelper('user_bind_info', 'dw_chat');
        $row = $objUserBindInfo->getRow($where);

        $data = [
            'last_login_time' => NOW,
            'update_time' => NOW,
        ];

        $objUserInfo = new TableHelper('user_info', 'dw_chat');
        $user_id = $row['user_id'];
        if ($user_id) {
            $objUserInfo->updateObject($data, compact('user_id'));
        } else {
            $objUserInfo->autoCommit(false);

            $oldUser = $objUserInfo->getRow(['first_account' => $account, 'first_type' => $type]);
            if ($oldUser) { // 有老账号
                $user_id = $oldUser['user_id'];
            } else {
                // 添加用户信息
                $data['first_type'] = $type;
                $data['nick_name'] = $name ?: self::getNewName($account);
                $data['user_name'] = $data['nick_name'] . '-' . strtoupper($type);
                $objUserInfo->addObject($data);
                $user_id = $objUserInfo->getInsertId();
            }

            // 添加绑定关系
            $data2 = [
                'user_id' => $user_id,
                'type' => $type,
                'account' => $account,
                'create_time' => NOW,
            ];
            $objUserBindInfo->addObject($data2);

            $objUserInfo->tryCommit();

            try {
                (new GroupInfo())->joinGroup($user_id, GroupInfo::OFFICIAL_ID);
            } catch (Exception $e) {
                var_log("new user:{$user_id} add official group error:" . $e->getMessage());
            }
        }

        return $user_id;
    }

    /**
     * 绑定第三方账号
     * @param $user_id
     * @param $account
     * @param string $type
     *
     * @return mixed
     */
    public static function bind($user_id, $account, $type = 'eos') {
        $objUser = new TableHelper('user_info', 'dw_chat');
        $objUserBindInfo = new TableHelper('user_bind_info', 'dw_chat');

        $user = $objUser->getRow(['user_id' => $user_id]);
        if ($user['first_type'] == $type && $user['first_account'] != $account) {
            Response::error(CODE_NORMAL_ERROR, "this account {$type} must be bind {$user['first_account']}");
        }

        $where = compact('account');
        $row = $objUserBindInfo->getRow($where);
        if ($row) {
            Response::error(CODE_NO_PERMITION, "{$type} account have been bind.");
        }

        $where = compact('user_id', 'type');
        $row = $objUserBindInfo->getRow($where);
        if ($row) {
            Response::error(CODE_NORMAL_ERROR, "you have bind {$type} account.");
        }

        $data = compact('user_id', 'type', 'account');
        $data['create_time'] = NOW;

        // 添加绑定关系
        $objUserBindInfo->addObject($data);

        return $user_id;
    }

    /**
     * 解绑操作
     * @author solu
     * @param $userId
     * @param string $type
     * @return bool
     * @throws Exception
     */
    public static function unbind($userId, $type = Account::TYPE_EOS) {
        $objBind = new TableHelper('user_bind_info', 'dw_chat');
        $rows = $objBind->getAll(['user_id' => $userId]);

        if (!$objBind->delObject(['user_id' => $userId, 'type' => $type])) {
            throw new Exception('unbind error', CODE_NORMAL_ERROR);
        }

        $bind = [];
        foreach ($rows as $row) {
            if ($row['type'] == $type) {
                $bind = $row;
                break;
            }
        }

        if ($bind['type'] == Account::TYPE_TG) {
            Telegram::delUserByTG($bind['account']);
        }

        return true;
    }

    public static function getNewName($account) {
        if (strlen($account) <= 12) {
            return $account;
        } else {
            $account = ltrim($account, '0x');
            $objUserInfo = new TableHelper('user_info', 'dw_chat');
            for ($i = 0; $i < 4; $i++) {
                $user_name = substr($account, 0, 12 + $i);
                $count = $objUserInfo->getCount(['user_name' => $user_name]);
                if ($count == 0) {
                    return $user_name;
                }
            }

            for ($i = 0; $i < 10; $i++) {
                $user_name = substr($account, 0, 12) . rand(1, 999);
                $count = $objUserInfo->getCount(['user_name' => $user_name]);
                if ($count == 0) {
                    return $user_name;
                }
            }

            throw new Exception('can not gen new user_name', CODE_UNKNOW_ERROT);
        }
    }

    /**
     * 保存用户信息
     * @param $user_id
     * @param $data
     */
    public static function saveInfo($user_id, $data) {
        $objUserInfo = new TableHelper('user_info', 'dw_chat');
        $objUserInfo->updateObject($data, compact('user_id'));
    }

    /**
     * 用户信息
     * @author solu
     * @param $userId
     * @param $self
     * @param $groupId
     * @return array
     */
    public static function getUserInfo($userId, $self, $groupId) {
        $myself = $userId == $self;

        $objUserInfo = new TableHelper('user_info', 'dw_chat');
        $keyword = [];
        if (!$myself) {
            $keyword['_field'] = 'user_id, user_name, nick_name, cover_photo, is_block';
        }
        $userInfo = $objUserInfo->getRow(['user_id' => $userId], $keyword);
        $objBind = new TableHelper('user_bind_info', 'dw_chat');
        $keyword = [
            '_field' => 'type, account, is_visible, create_time',
        ];
        if (!$myself) {
            $keyword['_field'] = 'type, account, is_visible';
        }

        $items = $objBind->getAll(['user_id' => $userId], $keyword);
        $items = arrayFormatKey($items, 'type');
        $allType = array_keys(Account::getAllType());

//        $isAdmin = false;
//        if ($groupId) {
//            $isAdmin = (new UserGroup())->isAdmin($groupId, $self);
//        }

        $binds = [];
        foreach ($allType as $type) {
            $item = $items[$type];
            if ($item) {
                $item['is_visible'] = intval($item['is_visible']);
//                if (!$myself && !$item['is_visible'] && !$isAdmin) {
                if (!$myself && !$item['is_visible']) {
                    $item['account'] = '******'; // 不可见
                }
            } else {
                $item = [
                    'type' => $type,
                    'account' => '',
                    'is_visible' => 1,
                ];
            }
            $binds[] = $item;
        }
        $userInfo['binds'] = $binds;

        return $userInfo ?: [];
    }
}
