<?php
/**
 * MemberLogic.php UTF-8
 *
 *
 * @date    : 2018/1/23 15:25
 *
 * @license 这不是一个自由软件,未经授权不许任何使用和传播。
 * @author  : linjiebin <ljb@huosdk.com>
 * @version : HUOSDK 8.0
 */
namespace web\pc\logic;

use huo\model\common\CommonModel;
use huo\model\member\MemberModel;
use huolib\constant\MemConst;
use huolib\status\MemberStatus;
use think\Session;
use think\Validate;
use think\Db;
use huolib\sms\Sms;

class MemberLogic extends CommonModel {
    private $mem_id;

    public function initialize($mem_id = 0) {
        parent::initialize();
        $this->mem_id = $mem_id;
        if (empty($this->mem_id)) {
            $this->mem_id = Session::get('user.id');
        }
    }

    /**
     * 获取玩家信息
     */
    public function getMemberInfo() {
        $id = $this->mem_id;
        if (empty($id)) {
            return [];
        } else {
            $field = 'id, username, nickname, reg_mobile ,avatar';
            $member = Db::name('member')
                        ->alias('m')
                        ->field($field)
                        ->where('id', $id)
                        ->find();
            if (empty($member['avatar'])) {
                $member['avatar'] = '';
            }

            return $member;
        }
    }

    /**
     * 玩家登陆
     *
     * @param $data
     *
     * @return array
     */
    public function login($data) {
        $validate = new Validate(
            [
                'username' => 'require',
                'password' => 'require|min:6|max:32',
            ]
        );
        $validate->message(
            [
                'username.require' => '用户名不能为空',
                'password.require' => '密码不能为空',
                'password.max'     => '密码不能超过32个字符',
                'password.min'     => '密码不能小于6个字符',
            ]
        );
        if (!$validate->check($data)) {
            return [
                'error' => 1,
                'msg'   => $validate->getError()
            ];
        }
        if (preg_match('/(^(13\d|15[^4\D]|17[013678]|18\d)\d{8})$/', $data['username'])) {
            $_user['username'] = $data['username'];
            $_user['password'] = $data['password'];
            $_log = $this->loginMobile($_user);
        } else {
            $_user['username'] = $data['username'];
            $_user['password'] = $data['password'];
            $_log = $this->loginUsername($_user);
        }
        $_loginRes = $this->checkUsernameStatus($_log);
        if (0 == $_loginRes['error']) {
            Session::set('user', $_log);
            // 记录登陆记录
            $this->loginLog($_log);
            $_loginRes['data'] = $_log;

            return $_loginRes;
        } else {
            return $_loginRes;
        }
    }

    /**
     * 手机号登陆
     *
     * @param array $data
     *
     * @return array|false|\PDOStatement|string|\think\Model
     */
    public function loginMobile($data = []) {
        $_map['reg_mobile'] = $data['username'];
        $_mem_info = $this->where($_map)->find();;
        if (!empty($_mem_info)) {
            $comparePasswordResult = cmf_compare_password($data['password'], $_mem_info['password']);
            if ($comparePasswordResult) {
                session('user', $_mem_info);
            } else {
                $_mem_info = [];
            }
        }

        return $_mem_info;
    }

    /**
     * 用户名登陆
     *
     * @param $data
     *
     * @return array|false|\PDOStatement|string|\think\Model
     */
    public function loginUsername($data) {
        $_map['username'] = $data['username'];
        $_mem_info = $this->where($_map)->find();
        if (!empty($_mem_info)) {
            $comparePasswordResult = cmf_compare_password($data['password'], $_mem_info['password']);
            if ($comparePasswordResult) {
                session('user', $_mem_info);
            } else {
                $_mem_info = [];
            }
        }

        return $_mem_info;
    }

    /**
     * 判断玩家的账户状态
     *
     * @param $userinfo
     *
     * @return array
     */
    public function checkUsernameStatus($userinfo) {
        if (empty($userinfo)) {
            return array(
                'error' => "1",
                'msg'   => '玩家的账户或密码不正确'
            );
        } else if ("3" == $userinfo['status']) {
            return array('error' => "1", 'msg' => '玩家的账户被冻结');
        } else if ("2" == $userinfo['status']) {
            return array('error' => "0", 'msg' => '登陆成功');
        }
    }

    /**
     * 记录登陆记录
     *
     * @param $userinfo
     *
     * @return int|string
     */
    public function loginLog($userinfo) {
//        $data['mem_id'] = $userinfo['id'];
//        $data['app_id'] = 0;
//        $data['create_time'] = time();
//        $data['from'] = 1; //1-WEB、2-WAP、3-Android、4-IOS、5-WP
//        $data['reg_time'] = $userinfo['create_time'];
//        $data['flag'] = 0;
//        $data['login_ip'] = request()->ip();
//        $res = Db::name('mem_login_log')->insertGetId($data);
//
//        return $res;
    }

    /**
     * 注册
     *
     * @param array $data
     *
     * @return array
     */
    public function reg($data = []) {
        //获取注册设置
        $_option_class = new OptionLogic();
        $_reg_setting = $_option_class->getValue('web_member');
        if (isset($_reg_setting['reg_is_allowed']) && $_reg_setting['reg_is_allowed'] == 1) {//不允许注册
            return [
                'error' => 1,
                'msg'   => '当前不允许注册'
            ];
        }
        $rules = [
            'code'     => 'require',
            'password' => 'require|min:6|max:32',
        ];
        $validate = new Validate($rules);
        $validate->message(
            [
                'code.require'     => '验证码不能为空',
                'password.require' => '密码不能为空',
                'password.max'     => '密码不能超过32个字符',
                'password.min'     => '密码不能小于6个字符',
            ]
        );
        if (!$validate->check($data)) {
            return [
                'error' => 1,
                'msg'   => $validate->getError()
            ];
        }
        if (preg_match('/^[1][23456789][0-9]{9}$/', $data['username'])) {
//            $_check_res = $this->checkMobileCode($data['username'], $data['code']);
            $_sms_rs = (new Sms())->check($data['username'], $data['code'], 1);
            if ($_sms_rs['code'] != 200) {
                return [
                    'error' => '1',
                    'msg' => $_sms_rs['msg']
                ];
            }
            $_user['username'] = $data['username'];
            $_user['password'] = $data['password'];
            $_log = $this->regMobile($_user);
            if ($_log['error'] == 0) {
                session('user', $_log['data']);
                Session::set('mobile', null, 'sms');
                Session::set('smstype', null, 'sms');
                Session::set('smscode', null, 'sms');
                Session::set('expire_time', null, 'sms');
                $_log['data']['reg_setting'] = $_reg_setting;

                return $_log;
            } else {
                return $_log;
            }
        }

        return [
            'error' => 1,
            'msg'   => '注册必须是手机号注册'
        ];
    }

    /**
     * 手机号注册
     *
     * @param $user
     *
     * @return array
     */
    public function regMobile($user) {
        $_map['username|mobile|reg_mobile'] = $user['username'];
        $result = (new MemberModel())->where($_map)->find();
        if (!empty($result)) {
            return [
                'error' => 1,
                'msg'   => '该账号已经被注册过了'
            ];
        }
        $data = [
            'username'    => $user['username'],
            'mobile'      => $user['username'],
            'nickname'    => $user['username'],
            'reg_mobile'  => $user['username'],
            'password'    => cmf_password($user['password']),
            'pay_pwd'     => cmf_password($user['password']),
            'from_device' => 'web',
            'reg_ip'      => get_client_ip(0, true),
            'create_time' => time(),
            'update_time' => time(),
            'status'      => MemConst::STATUS_NORMAL,
        ];
        $data['id'] = (new MemberModel())->addMem($data);
//        $userId = Db::name("member")->insertGetId($data);
//        $data = Db::name("member")->where('id', $userId)->find();
//        $this->loginLog($data);

        return [
            'error' => 0,
            'msg'   => '注册成功',
            'data'  => $data
        ];
    }

    /**
     * 退出登录
     *
     * @return array
     */
    public function logout() {
        Session::clear(null);

        return array('error' => 0, 'msg' => '退出成功');
    }

    /**
     * 修改密码
     *
     * @param array $data
     *
     * @return array
     */
    public function editPassword($data = []) {
        $_mem_info = $this->where(['id' => $data['id']])->find();
        if (!empty($_mem_info)) {
            $comparePasswordResult = cmf_compare_password($data['old_password'], $_mem_info['password']);
            if ($comparePasswordResult) {
                $_data = [
                    'password' => cmf_password($data['new_password']),
                ];
                $_res = Db::name("member")->where(['id' => $data['id']])->update($_data);
                if ($_res) {
                    return [
                        'error' => 0,
                        'msg'   => '修改成功'
                    ];
                }

                return [
                    'error' => 1,
                    'msg'   => '服务器内部错误'
                ];
            } else {
                return [
                    'error' => 1,
                    'msg'   => '原密码错误'
                ];
            }
        }

        return [
            'error' => 1,
            'msg'   => '用户不存在'
        ];
    }

    /**
     * 实名认证
     *
     * @param array $data
     *
     * @return array
     */
    public function authRealname($data = []) {
        if (empty($data['truename']) || empty($data['idcard'])) {
            return ['error' => 1, 'msg' => '姓名/身份证为必填信息'];
        }
        $_data = [
            'id'       => $data['id'],
            'real_name' => $data['truename'],
            'id_card'   => $data['idcard'],
        ];
        $_res = (new MemberModel())->update($_data);
        if (false === $_res) {
            return ['error' => 1, 'msg' => '服务器内部出错'];
        }

        return ['error' => 0, 'msg' => '实名认证成功'];
    }

    /**
     * 修改资料
     *
     * @param array $data
     *
     * @return array
     */
    public function editInfo($data = []) {
        if (empty($data['nickname'])) {
            return ['error' => 1, 'msg' => '昵称不能为空'];
        }
        $_data = [
            'id'       => $data['id'],
            'nickname' => $data['nickname'],
        ];
        $_res = Db::name("member")->update($_data);
        if (false === $_res) {
            return ['error' => 1, 'msg' => '服务器内部出错'];
        }

        return ['error' => 0, 'msg' => '修改成功'];
    }

    /**
     * 验证手机验证码是否正确
     *
     * @param $mobile
     * @param $mobileCode
     *
     * @return array
     */
    public function checkMobileCode($mobile, $mobileCode) {
        if ($mobile != Session::get('mobile', 'sms')) {
            return array('error' => '1', 'msg' => '请先发送短信');
        }
        // 判断验证码是否在有效期内
        if (Session::get('expire_time', 'sms') < time()) {
            return array('error' => '1', 'msg' => '验证码已经过期');
        }
        if (Session::get('smscode', 'sms') != $mobileCode) {
            return array('error' => '1', 'msg' => '验证码不正确');
        }

        return array('error' => '0', 'msg' => '验证通过');
    }

    /**
     * 验证邮箱验证码是否正确
     *
     * @param $email
     * @param $mobileCode
     *
     * @return array
     */
    public function checkEmailCode($email, $mobileCode) {
        if ($email != Session::get('email', 'user_email')) {
            return array('error' => '1', 'msg' => '请输入接收验证码的邮箱');
        }
        // 判断验证码是否在有效期内
        if (Session::get('expire_time', 'user_email') < time()) {
            return array('error' => '1', 'msg' => '验证码已经过期');
        }
        if (Session::get('email_code', 'user_email') != $mobileCode) {
            return array('error' => '1', 'msg' => '验证码不正确');
        }

        return array('error' => '0', 'msg' => '验证通过');
    }

    /**
     * 用户名是否存在
     *
     * @param $username
     *
     * @return array
     */
    public function usernameIsExists($username) {
        $_map['username'] = $username;
        $_memebr_info = Db::name('member')
                          ->where($_map)
                          ->find();
        if (empty($_memebr_info)) {
            return ['error' => 1, 'msg' => '用户不存在'];
        }
        $_is_mobile = 0;
        $_is_email = 0;
        if (!empty($_memebr_info['reg_mobile'])) {
            $_is_mobile = 1;
        }
        if (!empty($_memebr_info['reg_email'])) {
            $_is_email = 1;
        }

        return [
            'error' => 0,
            'msg'   => '用户名存在',
            'data'  => [
                'is_mobile' => $_is_mobile,
                'is_email'  => $_is_email
            ]
        ];
    }

    /**
     * 发送验证码
     *
     * @param string $username
     * @param string $mobile
     * @param string $email
     *
     */
    public function sendCode($username = '', $mobile = '', $email = '') {
        if (empty($username) || (empty($mobile) && empty($email))) {
            return ['code' => 400, 'msg' => '请输入找回方式'];
        }
        $_map['username'] = $username;
        $_memebr_info = Db::name('member')
                          ->where($_map)
                          ->find();
        if (!empty($mobile) && $_memebr_info['reg_mobile'] == $mobile) {
            $_sms_controller = new \huolib\sms\Sms();
            $_rdata = $_sms_controller->send($mobile, 3);
        } elseif (!empty($email) && $_memebr_info['reg_email'] == $email) {
            $_sms_controller = new \huo\controller\email\Email();
            $_rdata = $_sms_controller->send($email, $email);
        } else {
            $_rdata['code'] = 404;
            $_rdata['msg'] = '输入正确的绑定密保方式';
        }

        return $_rdata;
    }

    /**
     * 校验验证码
     *
     * @param string $mobile
     * @param string $email
     * @param string $code
     *
     * @return array
     */
    public function checkCode($mobile = '', $email = '', $code = '') {
        if ((empty($mobile) && empty($email)) || empty($code)) {
            return ['error' => 1, 'msg' => '请提交完整的参数'];
        }
        if (!empty($mobile)) {
            $_sms_rs = (new Sms())->check($mobile, $code, 4);
            if ($_sms_rs['code'] != MemberStatus::NO_ERROR) {
                $_rdata = [
                    'error' => '1',
                    'msg' => $_sms_rs['msg']
                ];
            }else{
                $_rdata = array('error' => '0', 'msg' => '验证通过');
            }
//           $_rdata = $this->checkMobileCode($mobile, $code);
        } else {
            $_rdata = $this->checkEmailCode($email, $code);
        }

        return $_rdata;
    }

    /**
     * 修改密码
     *
     * @param string $mobile
     * @param string $email
     * @param string $password
     * @param string $code
     *
     * @return array
     */
    public function setPassword($mobile = '', $email = '', $password = '', $code = '') {
        if ((empty($mobile) && empty($email)) || empty($password)) {
            return ['error' => 1, 'msg' => '请提交完整的参数'];
        }
        if (!empty($mobile)) {
            $_sms_rs = (new Sms())->check($mobile, $code, 1);
            if ($_sms_rs['code'] != MemberStatus::NO_ERROR) {
                $_r = [
                    'error' => '1',
                    'msg' => $_sms_rs['msg']
                ];
            }else{
                $_r = [
                    'error' => 0,
                    'msg' => $_sms_rs['msg']
                ];
            }
//            $_r = $this->checkMobileCode($mobile, $code);
            $_map['reg_mobile'] = $mobile;
        } else {
            $_r = $this->checkEmailCode($email, $code);
            $_map['reg_email'] = $email;
        }
        if ($_r['error'] > 0) {
            return $_r;
        }
        $_member_info = Db::name('member')->where($_map)->find();
        if (empty($_member_info)) {
            return ['error' => 1, 'msg' => '用户不存在'];
        }
        $_data['password'] = cmf_password($password);
        $_data['update_time'] = time();
        if ($_data['password'] == $_member_info['password']) {
            return ['error' => 1, 'msg' => '新密码不能与旧密码相同'];
        }
        $_res = Db::name('member')->where($_map)->update($_data);
        if (!$_res) {
            return ['error' => 1, 'msg' => '内部错误'];
        }
        //清空session
        if (!empty($mobile)) {
            Session::set('mobile', null, 'sms');
            Session::set('smstype', null, 'sms');
            Session::set('smscode', null, 'sms');
            Session::set('expire_time', null, 'sms');
        } else {
            Session::set('email', null, 'user_email');
            Session::set('email_code', null, 'user_email');
            Session::set('type', null, 'user_email');
            Session::set('email_time', null, 'user_email');
        }

        return ['error' => 0, 'msg' => '修改成功'];
    }

    /**
     * 修改手机号
     *
     * @param $mobile
     * @param $code
     *
     * @return array
     */
    public function editMobile($mobile, $code) {
        if (empty($mobile) || empty($code)) {
            return ['error' => 1, 'msg' => '手机/验证码为必填项'];
        }
//        $_r = $this->checkMobileCode($mobile, $code);
        $_sms_rs = (new Sms())->check($mobile, $code, 1);
        if ($_sms_rs['code'] != MemberStatus::NO_ERROR) {
            return [
                'error' => '1',
                'msg' => $_sms_rs['msg']
            ];
        }
        $_is_reg = Db::name('member')->where(['reg_mobile' => $mobile])->count();
        if ($_is_reg > 0) {
            return ['error' => 1, 'msg' => '该手机已绑定其他账号'];
        }
        $_map['id'] = $this->mem_id;
        $_data['reg_mobile'] = $mobile;
        $_data['update_time'] = time();
//        $_res = Db::name('member')->where($_map)->update($_data);
        $_res = MemberModel::update($_data, $_map, true);
        if (!$_res) {
            return ['error' => 1, 'msg' => '不能与原手机一致'];
        }

        return ['error' => 0, 'msg' => '修改成功'];
    }
}