<?php

namespace DAO;

use Error\CodeConfigModel;
use Error\ErrorModel;
use Our\ImageConst;
use Our\NameConst;
use Our\ApiConst;
use Our\Validate;


/**
 * 用户数据层
 */
class MemberModel extends \DAO\AbstractModel
{
    private $memberMysql;
    protected $_tableName = 'han_member';

    //有效用户返回数据
    private $availMemberColumn = array('member_id', 'member_name', 'member_truename', 'member_avatar', 'member_sex', 'member_birthday', 'member_mobile', 'member_mobile_bind', 'member_qq', 'member_qqopenid', 'member_qqinfo', 'member_wxinfo', 'member_wxopenid', 'member_sinaopenid', 'member_sinainfo', 'member_points', 'member_state', 'member_quicklink', 'member_exppoints', 'store_id', 'iswx', 'agree_flag', 'seller_id', 'diliveryman_id', 'member_tag_ids', 'member_group_ids', 'is_teacher', 'member_email', 'member_email_bind','is_wxsend');

    public function init()
    {
        $this->memberMysql = \Mysql\MemberModel::getInstance();
    }


    /**
     * 获取会员头像
     * @param $memberId 对应会员ID
     * @param $memberAvatar 会员对应member_avatar字段
     * @return string
     */
    public function getMemberAvatarUrl($memberId, $memberAvatar)
    {
        $filename = \Our\ImageConst::defaultMemberAvatarName;
        if ($memberAvatar) {
            if (strpos($memberAvatar, \Our\NameConst::http) === 0) {
                return $memberAvatar;
            }else{
                $filename = $memberAvatar;
            }
            //$filename = \Our\ImageConst::memberAvatarPrefix . $memberId;
        }
        return \Our\Common::getStaticFile($filename, \Our\ImageConst::memberAvatar);
    }

    //原生方法
    public function query()
    {
        $mysql = \Mysql\Slave\MemberModel::getInstance();
        $res = $mysql->query("select * from han_member");
        echo json_encode($res);
        exit;
    }

    //对主库进行操作
    public function update($sql)
    {
        $mysql = \Mysql\UserModel::getInstance();
        $res = $mysql->excute($sql);
        return $res;
    }

    public function getOneByMobileAndPassword($mobile, $password)
    {
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $where[NameConst::memberMobile] = $mobile;
        $where[NameConst::memberPasswd] = $password;
        $result = $this->db->select($this->availMemberColumn)->from($this->_tableName)->where($where)->fetchOne();
        if ($result) {
            $memberAvatarUrl = $this->getMemberAvatarUrl($result['member_id'], $result['member_avatar']);
            $result['memberAvatarUrl'] = $memberAvatarUrl;
        }
        return $result;
    }

    public function saveInfo($data, $memberId)
    {
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result = $this->db->update($this->_tableName)->rows($data)->where(array('member_id' => $memberId))->execute();
        if ($result!==false) {
            $memberDb0Redis = \Redis\Db0\MemberRedisModel::getInstance();
            $member = $data;
            if (isset($member['member_avatar']) && $member['member_avatar']) {
                $memberAvatarUrl = $this->getMemberAvatarUrl($memberId, $member['member_avatar']);
                $member['memberAvatarUrl'] = $memberAvatarUrl;
            }
            if(isset($member['member_passwd'])&&$member['member_passwd']){
                unset($member['member_passwd']);
            }
            $memberDb0Redis->tableHMSet($memberId, $member);
        }
        return $result;

    }

    public function getWxUserToken($memberId){
        $memberDb0Redis = \Redis\Db0\MemberRedisModel::getInstance();
        $member = $memberDb0Redis->tableHGAll($memberId);
        $memberDb0Redis->tableExpire($memberId, ApiConst::tenDaySecond);
        if(isset($member['wxUserToken'])&&$member['wxUserToken']){
            return $member['wxUserToken'];
        }
        return \Our\NameConst::emptyString;
    }

    public function saveWxUserToken($key,$memberId){
        $member = $this->getInfo($memberId);
        $memberDb0Redis = \Redis\Db0\MemberRedisModel::getInstance();
        $memberDb0Redis->tableHMSet($memberId, array('wxUserToken'=>$key));
    }

    /**
     * 保存用户信息
     */
    public function addInfo($data)
    {
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result = $this->db->insert($this->_tableName)->rows($data)->execute();
        if ($result) {
            $memberDb0Redis = \Redis\Db0\MemberRedisModel::getInstance();
            $memberAvatar = '';
            if (isset($data['member_avatar'])) {
                $memberAvatar = $data['member_avatar'];
            }
            $memberAvatarUrl = $this->getMemberAvatarUrl($result, $memberAvatar);
            $data['memberAvatarUrl'] = $memberAvatarUrl;
            $data['member_id'] = $result;
            $memberDb0Redis->tableHMSet($result, $data);
            return $this->db->getInsertId();
        }
        return false;
    }


    /**
     * 类实例
     *
     * @var \DAO\UserModel
     */
    private static $_instance = null;

    public function getInfo($memberId, $field = false)
    {
        $memberDb0Redis = \Redis\Db0\MemberRedisModel::getInstance();
        if ($field) {
            $memberField = $memberDb0Redis->tableHGet($memberId, $field);
            if (!empty($memberField)) {
                return $memberField;
            } else {
                $one = $this->getOneByMemberId($memberId, $field);
                return $one[$field];
            }
        } else {
            $member = $memberDb0Redis->tableHGAll($memberId);
            $memberDb0Redis->tableExpire($memberId, ApiConst::tenDaySecond);
            if (!empty($member)) {
                $return = array(
                    'memberId' => (int)$member['member_id'],
                    'memberName' => $member['member_name'],
                    'memberTrueName' => $member['member_truename'],
                    'memberAvatar' => $member['member_avatar'],
                    'memberSex' => (int)$member['member_sex'],
                    'memberBirthday' => $member['member_birthday'],
                    'memberEmail' => isset($member['member_email']) ? $member['member_email'] : '',
                    'memberEmailBind' => isset($member['member_email_bind']) ? (int)$member['member_email_bind'] : ApiConst::zero,
                    'memberMobile' => $member['member_mobile'],
                    'memberMobileBind' => (int)$member['member_mobile_bind'],
                    'memberWxinfo' => isset($member['member_wxinfo'])&&$member['member_wxinfo']? unserialize($member['member_wxinfo']) : new \stdClass(),
                    'memberWxopenid' => $member['member_wxopenid'],
                    'sellerId' => (int)$member['seller_id'],
                    'diliverymanId' => (int)$member['diliveryman_id'],
                    'storeId' => (int)$member['store_id'],
                    'memberAvatarUrl' => $member['memberAvatarUrl'],
                    'isWxsend'=>$member['is_wxsend'],
                    'pushSet'=>$member['push_set'],
                );
            } else {
                $member = $this->getOneByMemberId($memberId, '*');
                $return = array(
                    'memberId' => $member['member_id'],
                    'memberName' => $member['member_name'],
                    'memberTrueName' => $member['member_truename'],
                    'memberAvatar' => $member['member_avatar'],
                    'memberSex' => $member['member_sex'],
                    'memberBirthday' => $member['member_birthday'],
                    'memberEmail' => isset($member['member_email']) ? $member['member_email'] : '',
                    'memberEmailBind' => isset($member['member_email_bind']) ? $member['member_email_bind'] : ApiConst::zero,
                    'memberMobile' => $member['member_mobile'],
                    'memberMobileBind' => $member['member_mobile_bind'],
                    'memberWxinfo' => isset($member['member_wxinfo']) ? unserialize($member['member_wxinfo']) : new \stdClass(),
                    'memberWxopenid' => $member['member_wxopenid'],
                    'sellerId' => $member['seller_id'],
                    'diliverymanId' => $member['diliveryman_id'],
                    'storeId' => $member['store_id'],
                    'memberAvatarUrl' => $member['memberAvatarUrl'],
                    'isWxsend'=>$member['is_wxsend'],
                    'pushSet'=>$member['push_set'],
                );
                foreach ($member as $key => $value) {
                    if (empty($value) || is_null($value)) {
                        $member[$key] = ApiConst::zero;
                    }
                }
                foreach ($return as $key => $value) {
                    if (empty($value) || is_null($value)) {
                        $return[$key] = ApiConst::zero;
                    }
                }
                $memberDb0Redis->tableHMSet($memberId, $member);
            }
            return $return;
        }

    }

    public function updateInfo($data, $where)
    {
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result = $this->db->update($this->_tableName)->rows($data)->where($where)->execute();
        return $result;

    }

    public function getOneByWhereWithField($where, $field)
    {
        $this->setDb($this->dbName);
        $member = $this->db->from($this->_tableName)->select($field)->where($where)->fetchOne();
        return $member;
    }

    public function getOneByMemberId($memberId, $field = '*')
    {
        $this->setDb($this->dbName);
        $where['member_id'] = $memberId;
        $member = $this->getOneByWhereWithField($where, $field);;
        if(isset($member['member_avatar'])){
            $memberAvatarUrl = $this->getMemberAvatarUrl($memberId, $member['member_avatar']);
            $member['memberAvatarUrl'] = $memberAvatarUrl;
        }
        return $member;
    }

    /**
     * 获取类实例
     *
     * @return \DAO\UserModel
     */
    public static function getInstance($dbName=\Our\DbNameConst::salveDBConnectName)
    {
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self();
        }

        return self::$_instance;
    }


    /**
     * 验证会员信息
     * @param $where
     * @return array
     * @throws \Exception
     */
    public function getValidMember($where)
    {
        if ($where['memberName']) {
            if (!\Our\Validate::checkLengthRange($where['memberName'], 1, 25)) {
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::memberNameLengthLimit);
            }
        }
        /*if ($where['memberBirthday']) {
            if (!\Our\Validate::checkDateStr($where['memberBirthday'])) {
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::memberBirthdayError);
            }
            if (strtotime($where['memberBirthday']) > strtotime(date('Y-m-d'))) {
                \Error\ErrorModel::throwException(\Error\CodeConfigModel::illegalMemberBirthday);
            }
        }*/
        if (!($where['memberSex'] && in_array($where['memberSex'], array(\Our\ApiConst::woman, \Our\ApiConst::man)))) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongMemberSex);
        }
        $memberInfo['memberName'] = $where['memberName'];
        $memberInfo['memberSex'] = $where['memberSex'];
        $memberInfo = \Our\Common::convertHump($memberInfo);
        return $memberInfo;

    }


    public function validMemberNameAndAvatar($where){
        if(!$where['avatar']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyUserAvatar);
        }
        if(!$where['nickname']){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyUserNickname);
        }
        return true;
    }

    public function validRegisterInfo($where)
    {
        if (!\Our\Common::checkMobilePhone($where['mobile'])) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongMobileFormat);
        }
        if (!$where['password']) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyPassword);
        }
        if (!\Our\Validate::checkPassword($where['password'])) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::passwordLimit);
        }
        if (!$where['deviceType']) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyDeviceType);
        }
        if (!$where['deviceUniqueCode']) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyDeviceUniqueCode);
        }
        return true;
    }

    public function checkChangedInfo($where)
    {
        $this->checkRegisterMobile($where);
        if (!\Our\Validate::checkPassword($where['password'])) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::passwordLimit);
        }
    }

    /**
     * 验证注册手机号码
     */
    public function checkRegisterMobile($where)
    {
        $mobile = $where['mobile'];
        if (!\Our\Common::checkMobilePhone($mobile)) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongMobileFormat);
        }
        $member = $this->getOneByWhereWithField(array('member_mobile' => $mobile), 'member_id');
        if ($member) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::registerMobileExist);
        }
        return true;
    }

    /**
     * 验证手机是否存在有效用户
     * @param $where
     */
    public function checkLoginMobile($where)
    {
        $mobile = $where['mobile'];
        if (!\Our\Common::checkMobilePhone($mobile)) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongMobileFormat);
        }
        $member = $this->getOneByWhereWithField(array('member_mobile' => $mobile, 'member_state' => \Our\ApiConst::one), 'member_id');
        if (!$member) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::memberMobileExist);
        }
        return true;
    }

    /**
     * 微信用户绑定发送验证码时验证表单
     * @param $where
     * @param $memberId
     * @throws \Error\OurExceptionModel
     * @throws \Exception
     */
    public function checkWxBindMobileForSms($where,$memberId){
        if(!$memberId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wxMemberBindMobileSendCode);
        }
        $member = $this->getInfo($memberId);
        if(($member['memberMobile']&&$member['memberMobileBind'])){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wxMemberHasBindMobile);
        }
        return true;
    }


    public function checkWxBindMobileCommon($where){
        $mobile = $where['mobile'];
        if (!\Our\Common::checkMobilePhone($mobile)) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongMobileFormat);
        }
        $member = $this->getOneByWhereWithField(array('member_mobile' => $mobile, 'member_state' => \Our\ApiConst::one), 'member_id');
        if ($member) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::mobileExistMember);
        }
    }
    public function checkSaleMobile($where,$memberId) {
        if(!$memberId){
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::saleNotLogin);
        }
        $member_mobile = $this->getInfo($memberId,'member_mobile');
        if($member_mobile != $where['mobile']) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::salePhoneError);
        }
//        $mobile = $where['mobile'];
//        if (!\Our\Common::checkMobilePhone($mobile)) {
//            \Error\ErrorModel::throwException(\Error\CodeConfigModel::wrongMobileFormat);
//        }
//        $member = $this->getOneByWhereWithField(array('member_mobile' => $mobile, 'member_state' => \Our\ApiConst::one), 'member_id');
//        if ($member) {
//            \Error\ErrorModel::throwException(\Error\CodeConfigModel::mobileExistMember);
//        }
    }
    /**
     * 微信用户更改手机号码提交表单时验证
     * @param $where
     * @param $memberId
     * @throws \Error\OurExceptionModel
     * @throws \Exception
     */
    public function checkWxBindMobile($where){
        $this->checkWxBindMobileCommon($where);
        if (!\Our\Validate::checkPassword($where['password'])) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::passwordLimit);
        }
    }


    public function checkPassword($data)
    {
        if (!($data['password'] && $data['rePassword'])) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyPasswordAndRepassword);
        }
        if ($data['password'] != $data['rePassword']) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::differentPasswordAndRepassword);
        }
        if (!\Our\Validate::checkPassword($data['password'])) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::passwordLimit);
        }
    }

    /**
     * 更换密码时验证密码和旧密码
     * @param $data
     * @param $memberId
     * @throws \Exception
     */
    public function checkOldPassword($data, $memberId)
    {
        if (!$data['oldPassword']) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyOldPassword);
        }
        $memberCurrent = $this->getOneByWhereWithField(array('member_id' => $memberId), 'member_passwd');
        if (!($memberCurrent && $memberCurrent['member_passwd'] == md5($data['oldPassword']))) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::worngOldPassword);
        }
        $this->checkPassword($data);
    }

    public function checkDelMember($data)
    {
        if (!(APP_ENV == 'test' || APP_ENV == 'develop'|| APP_ENV == 'pre')) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::noAvailForDelMember);
        }
        if (!$data['mobile']) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::emptyMobileForDelMember);
        }
    }

    public function getMemberById($memberId)
    {
        $member = $this->getOneByWhereWithField(array('member_id' => $memberId), $this->availMemberColumn);
        foreach ($member as $key => $value) {
            if (empty($value) || is_null($value)) {
                $member[$key] = \Our\ApiConst::zero;
            }
        }
        $memberAvatarUrl = $this->getMemberAvatarUrl($member['member_id'], $member['member_avatar']);
        $member['memberAvatarUrl'] = $memberAvatarUrl;
        return $member;
    }

    public function getMemberForLogin($memberIds){
        $member = array();
        $memberCon['member_id'] = array('in',$memberIds);
        $memberCon['member_state'] = \Our\ApiConst::one;
        $orders = array('member_mobile'=>'desc','member_id'=>'desc');
        $memberList = $this->getList($memberCon,$this->availMemberColumn,$orders);
        if($memberList){
            $member = $memberList[0];
            $memberAvatarUrl = $this->getMemberAvatarUrl($member['member_id'], $member['member_avatar']);
            $member['memberAvatarUrl'] = $memberAvatarUrl;
        }
        return $member;
    }

    public function del($where)
    {
        $this->setDb(\Our\DbNameConst::masterDBConnectName);
        $result = $this->db->delete($this->_tableName)->where($where)->execute();
        return $result;
    }

    /**
     * 个人中心统计数量更新
     * @param $type
     *  /Our/NameConst
     *  const waitPay = 'waitPay';//待付款 order_state=10
     *  const waitShipments = 'waitShipments';//待发货 order_state=20,25
     *  const waitReceiving = 'waitReceiving';//待收货 order_state=30
     *  const waitEvaluate = 'waitEvaluate';//待评价 order_state=40 and evaluation_state=0,2
     *  const refund = 'refund';//退款中 seller_state=1 or (is_platform_in = 1 and platform_state = 0)
     *  const storeCollection = 'storeCollection';//店铺收藏数量
     *  const goodsCollection = 'goodsCollection';//商品收藏数量
     *  const footprint = 'footprint';//足迹数量
     * @param $num
     */
    public function _changeNum($type, $memberId, $num = 1)
    {
        $memebrCenterDb1Redis = \Redis\Db1\MemberCenterRedisModel::getInstance();
        if ($memebrCenterDb1Redis->tableKeyExists($memberId) !== false) {
            $memebrCenterDb1Redis->tableHIncrBy($memberId, $type, $num);
        }
    }

    public function getList($where,$field = \Our\NameConst::allField,$orders = array()){
        $this->setDb($this->dbName);
        if(is_array($where)){
            $where = $this->db->getSqlWhereByArray($where);
        }
        if($orders){
            foreach($orders as $key=>$order){
                $this->db->order($key,$order);
            }
        }
        return $this->db->from($this->_tableName)->select($field)->where($where)->fetchAll();
    }

    public function changeNum($memberId, $orderState, $evaluation_state = null, $num = 1)
    {
        switch ($orderState) {
            case ApiConst::orderStateWaitPay:
                $type = NameConst::waitPay;
                break;
            case ApiConst::orderStateWaitSend:
                $type = NameConst::waitShipments;
                break;
            case ApiConst::orderStateWaitRecieve:
                $type = NameConst::waitReceiving;
                break;
            case ApiConst::orderStateComplete:
                $type = NameConst::waitEvaluate;
                break;
            default:
                break;
        }
        if ($type) {
            $this->_changeNum($type, $memberId, $num);
        }
    }
    public function getListMemberUrl($list){
        foreach($list as &$li){
            $li['memberAvatar']=$this->getMemberAvatarUrl($li['memberId'],$li['memberAvatar']);
        }
        return $list;
    }

    //删除统计缓存
    public function deleteTotalCache($memberId,$type=FALSE){
        $memebrCenterDb1Redis = \Redis\Db1\MemberCenterRedisModel::getInstance();
        if(!empty($type)){
            $memebrCenterDb1Redis->tableHDel($memberId,$type);
        }else{

            //$memebrCenterDb1Redis->tableDel($memberId);
            $memebrCenterDb1Redis->tableHDel($memberId,NameConst::waitPay);
            $memebrCenterDb1Redis->tableHDel($memberId,NameConst::waitShipments);
            $memebrCenterDb1Redis->tableHDel($memberId,NameConst::waitReceiving);
            $memebrCenterDb1Redis->tableHDel($memberId,NameConst::waitEvaluate);
            $memebrCenterDb1Redis->tableHDel($memberId,NameConst::refund);
        }
    }
    public function fromOrderStateToOrderState($memberId, $fromState, $toState)
    {
        $this->changeNum($memberId, $fromState, null, -1);
        $this->changeNum($memberId, $toState, null, 1);
    }
    public function setIsWxsend($memberId,$pushData){
           foreach($pushData as $key=>$val){
               if($key!='timeDiff'){
                   if(!in_array($val,array(ApiConst::closeMessage,ApiConst::openMessae))){
                       ErrorModel::throwException(CodeConfigModel::paramsError);
                   }
               }
           }
           $data['push_set']=serialize($pushData);
        if(isset( $data['push_set'])){
            $res=$this->saveInfo($data,$memberId);
            return $res;
        }
    }
    public function validPassword($where){
        if (!\Our\Validate::checkPassword($where['password'])) {
            \Error\ErrorModel::throwException(\Error\CodeConfigModel::passwordLimit);
        }
    }
}
