package com.ssj.service.weixin.user.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ssj.bean.weixin.libmy.domain.TbLibManager;
import com.ssj.bean.weixin.user.domain.QrCode;
import com.ssj.bean.weixin.user.domain.User;
import com.ssj.bean.weixin.user.domain.UserAccount;
import com.ssj.dao.weixin.user.dao.UserDao;
import com.ssj.dao.weixin.user.dao.UserQueryDao;
import com.ssj.framework.core.common.service.BaseServiceImpl;
import com.ssj.framework.core.persistence.DynamicSpecifications;
import com.ssj.framework.core.persistence.SearchFilter;
import com.ssj.framework.core.security.exception.RequestsException;
import com.ssj.framework.core.security.manager.TokenManager;
import com.ssj.framework.core.util.*;
import com.ssj.framework.idworker.IdWorker;
import com.ssj.framework.weixin.util.MUDload;
import com.ssj.framework.weixin.util.UserInfo;
import com.ssj.framework.weixin.util.WxUtil;
import com.ssj.service.sys.easemob.service.EasemobService;
import com.ssj.service.weixin.library.service.IBookManagerService;
import com.ssj.service.weixin.user.dto.AppWxUserInfo;
import com.ssj.service.weixin.user.service.QrCodeService;
import com.ssj.service.weixin.user.service.UserAccountService;
import com.ssj.service.weixin.user.service.UserService;
import com.ssj.service.weixin.user.util.UserHandlerUtil;
import com.ssj.sys.util.j2se.RandomUtils;
import com.ssj.taskthread.Task;
import com.ssj.taskthread.ThreadPool;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service(version="1.0")
@Transactional
public class UserServiceImpl extends BaseServiceImpl<User, String> implements UserService {
	
	private static Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
	@Autowired
	private UserDao userDao;
	
	@Autowired
	private UserQueryDao userQueryDao;

	@Autowired
	private TokenManager tokenManager;
	@Autowired
	private UserAccountService userAccountService;
	@Autowired
	private QrCodeService qrCodeService;
	@Autowired
	private EasemobService easemobService;
	@Autowired
	private IBookManagerService managerService;
	@Autowired
	private RedisUtil redisUtil;
	

	@Override
	public PagingAndSortingRepository<User, String> getDao() {
		return userDao;
	}
	
	@Override
	public Page<User> findByPage(Map<String, Object> params, Pageable sp)
			throws Exception {
		 Map<String, SearchFilter> filters = SearchFilter.parse(params);
	     Specification<User> specification = DynamicSpecifications.bySearchFilter(filters.values(), User.class);
	     return userDao.findAll(specification, sp);
	}




	
	@Override
	public User findByAccount(String account) {
		return userDao.findByAccount(account);
	}

	@Override
	public User insertUser(User  user) {
		logger.info("insertUser--user)" +JSON.toJSONString(user));
		if(null!=user.getUnionid()){
			List<User> userList=userDao.getUserByUnionid(user.getUnionid());
			logger.info("userList--)" +JSON.toJSONString(userList));
			if(userList !=null && userList.size()>0 ){
				User weiXinUser = userList.get(0);
				userAccountService.updateUserIdByUnionId(user.getUnionid(), weiXinUser.getId());

				if(user.getSex()!=null)weiXinUser.setSex(user.getSex());
				if(user.getCity()!=null)weiXinUser.setCity(user.getCity());
				if(user.getCountry()!=null)weiXinUser.setCountry(user.getCountry());
				if(user.getProvince()!=null)weiXinUser.setProvince(user.getProvince());
				if(user.getLanguage()!=null)weiXinUser.setLanguage(user.getLanguage());
				if(user.getName()!=null)weiXinUser.setName(user.getName());
				if(user.getAccount()!=null){
					if(StringUtils.isBlank(weiXinUser.getAccount()) ){
						weiXinUser.setAccount(user.getAccount());
					}

				}
					weiXinUser.setName(user.getName());
				if(user.getWeixinPhoto() !=null&&user.getWeixinPhoto().trim().length()>0){
					weiXinUser.setWeixinPhoto(user.getWeixinPhoto());
					String photo  = MUDload.downloadImage(user.getWeixinPhoto());
					if(photo !=null){
						weiXinUser.setPhoto(photo);
					}
				}
				this.save(weiXinUser);

				return weiXinUser;
			}
		}
		if(user.getWeixinPhoto()!=null){
			String photo  = MUDload.downloadImage(user.getWeixinPhoto());
			if(photo !=null){
				user.setPhoto(photo);
			}
		}
		user.setId(IdWorker.generateId());
		this.save(user);
		return user;
	}

	@Override
	public User uploadUser(String id) {
		   User 	user=this.getById(id);
			if(user !=null && user.getAccount()!=null){
				String accessToken=tokenManager.getSSJAccessToken();
				User weiXinUser=UserHandlerUtil.getUserInfo(accessToken, user.getAccount());
				if(1==weiXinUser.getSubscribe()){
					user.setName(weiXinUser.getName());
					if(weiXinUser.getWeixinPhoto() !=null&&weiXinUser.getWeixinPhoto().trim().length()>0){
						user.setWeixinPhoto(weiXinUser.getWeixinPhoto());
						String photo  = MUDload.downloadImage(weiXinUser.getWeixinPhoto());
						if(photo !=null){
							user.setPhoto(photo);
						}
					}
					if(weiXinUser.getSex()!=null)user.setSex(weiXinUser.getSex());
					if(weiXinUser.getCity()!=null)user.setCity(weiXinUser.getCity());
					if(weiXinUser.getCountry()!=null)user.setCountry(weiXinUser.getCountry());
					if(weiXinUser.getProvince()!=null)user.setProvince(weiXinUser.getProvince());
					if(weiXinUser.getLanguage()!=null)user.setLanguage(weiXinUser.getLanguage());
				}
				user.setSubscribe(weiXinUser.getSubscribe());
				if(weiXinUser.getUnionid()!=null){
					user.setUnionid(weiXinUser.getUnionid());
				}
				this.save(user);
			}
			return user;
	}
	
	@Override
	public Page<Map<String, Object>> getWXUser(
			Map<String, Object> searchParams, Pageable pageable) {
		return userQueryDao.getWXUser(searchParams, pageable);
	}
	@Override
	public Page<Map<String, Object>> getTSGUser(
			Map<String, Object> searchParams, Pageable pageable) {
		return userQueryDao.getTSGUser(searchParams, pageable);
	}

	@Override
	public void updateSubscribe(String openId, Integer subscribe) {
		userDao.updateSubscribe(openId, subscribe);
	}


	@Override
	public String findUserById(String wx_account) {
		return userDao.findUserById(wx_account);
	}

	@Override
	public  void updateById(String id){
		userDao.updateById(id);
	}

	@Override
	public Map<String, String> findUserExist(String openId) {
		 Map<String, String> map  =new  HashMap<String, String>();
		 String key ="wx_open_id_ssj"+openId;
        if(tokenManager.exists(key)){
            return   tokenManager.hget(key);
        };
		User user=this.findByAccount(openId);
		if(user==null){
			user=UserHandlerUtil.getUserInfo(tokenManager.getSSJAccessToken(), openId);
			if(StringUtil.isNotBlank(user.getUnionid())){
				List<User> userList=userDao.getUserByUnionid(user.getUnionid());
				if(userList!=null && userList.size()>0){
					logger.info("公众号进来userList--)" +userList);
					//明天改逻辑。
					User weiXinUser =userList.get(0);
					if(userList.size()>1){
						// 这里重新关联 tb_user_account.userId
						userAccountService.updateUserIdByUnionId(user.getUnionid(), weiXinUser.getId());
					}
					

					weiXinUser.setAccount(openId);
					weiXinUser.setSubscribe(user.getSubscribe());
					weiXinUser.setName(user.getName());
					if(StringUtil.isNotBlank(user.getWeixinPhoto())){
						String photo  = MUDload.downloadImage(user.getWeixinPhoto());
						if(photo !=null&&photo.trim().length()>0){
							weiXinUser.setPhoto(photo);
						}
						weiXinUser.setWeixinPhoto(user.getWeixinPhoto());
					}

					weiXinUser.setLanguage(user.getLanguage());
					weiXinUser.setCountry(user.getCity());
					weiXinUser.setCity(user.getCity());
					weiXinUser.setSex(user.getSex());
					weiXinUser.setProvince(user.getProvince());
					weiXinUser.setLastUpdateTime(new Date());
					this.save(weiXinUser);
					map.put("id", weiXinUser.getId());
					map.put("name",user.getName());
					map.put("openId", user.getAccount());
					map.put("unionid", user.getUnionid());
					map.put("photo", StringUtil.isNotEmpty(user.getPhoto())?user.getPhoto():"");
                    tokenManager.hset(key,map);
					return  map;
				}
			}
			user.setCreateTime(new  Date());
            if(StringUtil.isNotBlank(user.getWeixinPhoto())){
				String photo  = MUDload.downloadImage(user.getWeixinPhoto());
				if(photo !=null){
					user.setPhoto(photo);
				}
			}
			user.setId( IdWorker.generateId());
			user  =this.save(user);
			map.put("id", user.getId());
			map.put("name", user.getName());
			map.put("openId", user.getAccount());
			map.put("unionid", user.getUnionid());
            map.put("photo", StringUtil.isNotEmpty(user.getPhoto())?user.getPhoto():"");
		}else{
			
			User weiXinUser=UserHandlerUtil.getUserInfo(tokenManager.getSSJAccessToken(), openId);

			if(StringUtil.isBlank(weiXinUser.getWeixinPhoto())){
				String photo  = MUDload.downloadImage(weiXinUser.getWeixinPhoto());
				if(photo !=null&&photo.trim().length()>0){
					user.setPhoto(photo);
				}
				user.setWeixinPhoto(weiXinUser.getWeixinPhoto());
			}
			if(StringUtil.isBlank(user.getUnionid())){
				user.setUnionid(weiXinUser.getUnionid());
			}

			user.setName(weiXinUser.getName());
			user.setLanguage(weiXinUser.getLanguage());
			user.setCountry(weiXinUser.getCity());
			user.setCity(weiXinUser.getCity());
			user.setSex(weiXinUser.getSex());
			user.setProvince(weiXinUser.getProvince());
			user.setLastUpdateTime(new Date());
			user.setSubscribe(weiXinUser.getSubscribe());
			user  =this.save(user);
			map.put("id", user.getId());
			map.put("name",user.getName());
			map.put("openId", user.getAccount());
			map.put("unionid", user.getUnionid());
            map.put("photo", StringUtil.isNotEmpty(user.getPhoto())?user.getPhoto():"");
		}
        tokenManager.hset(key,map);
		return  map;
	}


	@Override
	public String getSubscribe(String userId) {

		String  subscribe= tokenManager.getWxOpenId(userId);
		if(StringUtil.isBlank(subscribe)){
			subscribe=  userDao.getSubscribe(userId);
			subscribe =StringUtil.isNotBlank(subscribe)?subscribe:"0";
			tokenManager.createWxOpenId(userId, subscribe);
		}

		return subscribe;
	}


	@Override
	public String getAccount(String id) {
		return userDao.getAccount(id);
	}

    /**
     * 需要修改
     */
	@Override
	public String insertXCXuser(String openid,String unionid,String appid,Integer type)  throws Exception{
		if(StringUtil.isBlank(unionid) ||  StringUtil.isBlank(openid)){
			throw new  Exception("unionid或openid为空");
		}
		String userId=tokenManager.getString("user_id"+unionid+type);
		if(StringUtil.isNotBlank(userId)){
            return userId;
		}
		//执行加锁，当前接口没有返回则不行执行下一步

       if(tokenManager.setnx("setnx_user_id"+unionid+type,"1")==1){
           UserAccount userAccount=userAccountService.findUserAccountByOpenid(openid);
           if(userAccount!=null){
               logger.info("该用户存在unionid="+userAccount.getUnionid());
               logger.info("该用户存在userid="+userAccount.getUserId());
               if("qrcode".equals(userAccount.getUnionid())||StringUtil.isBlank(userAccount.getUnionid())){
                   userAccount.setUnionid(unionid);
                   userAccountService.save(userAccount);
                   if(StringUtil.isNotBlank(userAccount.getUserId())){
                       userDao.updateUnionid( userAccount.getUserId(),unionid);
                   }

               }
               tokenManager.setString("user_id"+unionid+type,userAccount.getUserId(),30*24*3600);
               tokenManager.delString("setnx_user_id"+unionid+type);
               return userAccount.getUserId();
           }
           userId = userDao.findUserByUnionid(unionid);
           logger.info("用户unionid获取userId="+userId);
           if(StringUtil.isNotBlank(userId)){
               userAccount = new UserAccount();
               userAccount.setAppid(appid);
               userAccount.setOpenid(openid);
               userAccount.setUnionid(unionid);
               userAccount.setUserId(userId);
               userAccount.setType(type);
               userAccountService.save(userAccount);
               tokenManager.setString("user_id"+unionid+type,userId,30*24*3600);
               tokenManager.delString("setnx_user_id"+unionid+type);
               return userId;
           }
           userId=tokenManager.getString("user_id"+unionid+type);

           if(StringUtil.isNotBlank(userId)){
               tokenManager.delString("setnx_user_id"+unionid+type);
               return userId;
           }
           userId = IdWorker.generateId();
           ThreadPool.getInstance().addTask(new SyncSaveUserDBTask( openid, unionid, appid, type, userId, userAccountService, userDao));
           tokenManager.setString("user_id"+unionid+type,userId,30*24*3600);
           tokenManager.delString("setnx_user_id"+unionid+type);
         //  return userId;
       }else{
         //  throw new  Exception("unionid或openid为空");
           String message = String.format("请求太频繁 [%s] 请稍后", unionid+type);
           throw new RequestsException(message);
       }

		return userId;
	}
	@Override
	public String newInsertXCXuser(String openid,String unionid,String appid,Integer type,UserInfo  userInfo){
		unionid =StringUtil.isNotBlank(unionid) ? unionid :userInfo.getUnionId();
		String userId=tokenManager.getString("user_id"+unionid+type);
		if(StringUtil.isNotBlank(userId)){
			return userId;
		}
        if(tokenManager.setnx("newsetnx_user_id"+unionid+type,"1")==1){
            UserAccount userAccount=userAccountService.findUserAccountByOpenid(openid);
            if(userAccount!=null){
                logger.info("该用户存在unionid="+userAccount.getUnionid());
                logger.info("该用户存在userid="+userAccount.getUserId());
                if("qrcode".equals(userAccount.getUnionid())||StringUtil.isBlank(userAccount.getUnionid())){
                    userAccount.setUnionid(userInfo.getUnionId());
                    List<User> userList=userDao.getUserByUnionid(userInfo.getUnionId());
                    if(userList!=null && userList.size()>0){
                        logger.info("code.userInfo小程序进来-userList--)" +JSON.toJSONString(userList));
                        User weiXinUser =userList.get(0);
                        if(userList.size()>1){
                            // 这里重新关联 tb_user_account.userId
                            userAccountService.updateUserIdByUnionId(userInfo.getUnionId(), weiXinUser.getId());

                        }
                        userAccount.setUserId(weiXinUser.getId());
                        userAccountService.save(userAccount);
                        tokenManager.setString("user_id"+unionid+type,weiXinUser.getId(),30*24*3600);
                        tokenManager.delString("newsetnx_user_id"+unionid+type);
                        return weiXinUser.getId();
                    }else{
                        if(StringUtil.isNotBlank(userAccount.getUserId())){
                            userDao.updateUnionid( userAccount.getUserId(),unionid);
                        }
                    }
                    userAccountService.save(userAccount);
                }
                tokenManager.setString("user_id"+unionid+type,userAccount.getUserId(),30*24*3600);
                tokenManager.delString("newsetnx_user_id"+unionid+type);
                return userAccount.getUserId();
            }

            logger.info("用户unionid="+unionid);
            userId = userDao.findUserByUnionid(unionid);
            logger.info("用户unionid获取userId="+userId);
            if(StringUtil.isNotBlank(userId)){
                userAccount = new UserAccount();
                userAccount.setAppid(appid);
                userAccount.setOpenid(openid);
                userAccount.setUnionid(unionid);
                userAccount.setUserId(userId);
                userAccount.setType(type);
                userAccountService.save(userAccount);
                tokenManager.setString("user_id"+unionid+type,userId,30*24*3600);
                tokenManager.delString("newsetnx_user_id"+unionid+type);
                return userId;
            }
            userId=tokenManager.getString("user_id"+unionid+type);
            if(StringUtil.isNotBlank(userId)){
                tokenManager.delString("newsetnx_user_id"+unionid+type);
                return userId;
            }
            userId = IdWorker.generateId();
            if(22==type){
                saveUserInfo( openid, unionid, appid, type, userId, userInfo);
            }else{
                ThreadPool.getInstance().addTask(new SyncSaveUserInfoDBTask( openid, unionid, appid, type, userId, userAccountService, userDao,userInfo));
            }

            tokenManager.setString("user_id"+unionid+type,userId,30*24*3600);
            tokenManager.delString("newsetnx_user_id"+unionid+type);
        }else{
            String message = String.format("newInsertXCXuser请求太频繁 [%s] 请稍后", unionid+type);
            throw new RequestsException(message);
        }


		return userId;
	}

	@Override
	public void saveXCXUser(User user, UserInfo userinfo) {
		/**
		 * 由于用户已经存在，新开的小程序，用户第一次进来是获取不到unionid,
		 * 在登录的时候所以就直接插入了一条user记录，
		 * 这里就需要把旧的复制给新的
		 */
		String unionid = StringUtil.isBlank(user.getUnionid()) ? userinfo.getUnionId() :user.getUnionid();


		if( StringUtil.isBlank(user.getUnionid())){
			user.setUnionid(userinfo.getUnionId());
		}
		if(StringUtil.isBlank(user.getAccount())){
			logger.info("公众号的openId为空");
			List<User> userList=userDao.getUserByUnionid(unionid);
			logger.info("数据库存在"+JSON.toJSONString(userList));
			if(userList!=null&&userList.size()>0){
				logger.info("老用户存在");
				user = userList.get(0);
				// 这里重新关联 tb_user_account.userId
				userAccountService.updateUserIdByUnionId(user.getUnionid(), user.getId());
			}
		}
		if(userinfo.getNickName()!=null){
			user.setName(userinfo.getNickName());
			user.setUserName(userinfo.getNickName());
		}
		if(userinfo.getGender()!=null){
			int sex =1;
			if(userinfo.getGender().equals("2")){
				sex=2;
			}
			user.setSex(sex);
		}
		
		if(userinfo.getCity()!=null){user.setCity(userinfo.getCity());}
		
		if(userinfo.getProvince()!=null){user.setProvince(userinfo.getProvince());}
		
		if(userinfo.getCountry()!=null){user.setCountry(userinfo.getCountry());}
		
		if(userinfo.getLanguage()!=null){user.setLanguage(userinfo.getLanguage());}
		
	
		
		if(userinfo.getAvatarUrl()!=null && !userinfo.getAvatarUrl().equals(user.getWeixinPhoto())){
			user.setWeixinPhoto(userinfo.getAvatarUrl());
			String photo  = MUDload.downloadImage(userinfo.getAvatarUrl());
			logger.info("小程序保存下载用户头像成功，filePath=="+photo);
			if(photo !=null&&photo.trim().length()>0){
				user.setPhoto(photo);
			}
		}
		user.setLastUpdateTime(new Date());
		this.save(user);
		
	}

	@Override
	public void uploadUserAll() {
		final int threadNum  =10;//启动10个线程发送
		final long count =userDao.getCount();
		final int tl = (int)count % threadNum == 0 ? (int)count / threadNum : ((int)count / threadNum + 1);
		for ( int i = 0; i < threadNum; i++) {
			final int  num = i;
			Thread t1 = new Thread(new Runnable() {
				public void run() {
					uploadThread(tl,(int)count,num);
				}
			});
			t1.start();
		}
		
	}
	
	private void uploadThread(int  tl,int  length, int i ){
		  int end = (i + 1) * tl;
		  int _end = end > length ? length : end;
          String threadName = "第" + (i + 1) + "批数据：" + i * tl + "~" + _end;
          try {
              logger.info(threadName + ",开始处理"+"LIMIT="+ i * tl +" , " + tl);
              userSendTemplate(i * tl, tl);
              logger.info(threadName + ",处理完成," );
          } catch (Exception e) {
              e.printStackTrace();
          }
	}
	private void userSendTemplate(int start,int end){
		List<User> list =userDao.getByUserLimit(start, end);
		for (User user : list) {
					if(user !=null && user.getAccount()!=null){
						String accessToken=tokenManager.getSSJAccessToken();
						User weiXinUser=UserHandlerUtil.getUserInfo(accessToken, user.getAccount());
						if(1==weiXinUser.getSubscribe()){
							user.setName(weiXinUser.getName());
							if(weiXinUser.getWeixinPhoto() !=null&&weiXinUser.getWeixinPhoto().trim().length()>0&&!weiXinUser.getWeixinPhoto().equals(user.getWeixinPhoto())){
								user.setWeixinPhoto(weiXinUser.getWeixinPhoto());
								String photo  = MUDload.downloadImage(weiXinUser.getWeixinPhoto());
								if(photo !=null){
									user.setPhoto(photo);
								}
							}
							if(weiXinUser.getSex()!=null)user.setSex(weiXinUser.getSex());
							if(weiXinUser.getCity()!=null)user.setCity(weiXinUser.getCity());
							if(weiXinUser.getCountry()!=null)user.setCountry(weiXinUser.getCountry());
							if(weiXinUser.getProvince()!=null)user.setProvince(weiXinUser.getProvince());
							if(weiXinUser.getLanguage()!=null)user.setLanguage(weiXinUser.getLanguage());
						}
						user.setSubscribe(weiXinUser.getSubscribe());
						user.setLastUpdateTime(new Date());
						if(StringUtil.isNotBlank(weiXinUser.getUnionid())){
							user.setUnionid(weiXinUser.getUnionid());
						}
						this.save(user);
					}

		}
	}


	@Override
	public User getUserByUnionid(String unionid){
		return userDao.getUserByUnionidLimit(unionid);
	}

	@Override
	public void saveAppUser(String accessToken, AppWxUserInfo appWxUserInfo) {
		String userId= tokenManager.getUserId(accessToken);
		User userinfo =this.getById(userId);
		if(StringUtils.isBlank(userinfo.getEasemobName())) {
			//如果用户没有环信id
			userinfo.setEasemobName(this.createUniqueEasemobName());
			easemobService.createUserSingle(userinfo.getEasemobName(),userinfo.getUserName());
		}
		if(appWxUserInfo.getNickname()!=null){
			userinfo.setUserName(appWxUserInfo.getNickname());
			userinfo.setName(appWxUserInfo.getNickname());
			if(!appWxUserInfo.getNickname().equals(userinfo.getName())) {
				easemobService.updateUserNickName(userinfo.getEasemobName(), appWxUserInfo.getNickname());
			}
		}
		if(appWxUserInfo.getSex()!=null){userinfo.setSex(Integer.parseInt(appWxUserInfo.getSex()));}
		if(appWxUserInfo.getCity()!=null){userinfo.setCity(appWxUserInfo.getCity());}
		if(appWxUserInfo.getProvince()!=null){userinfo.setProvince(appWxUserInfo.getProvince());}
		if(appWxUserInfo.getHeadimgurl()!=null && !appWxUserInfo.getHeadimgurl().equals(userinfo.getWeixinPhoto())){
			userinfo.setWeixinPhoto(appWxUserInfo.getHeadimgurl());
			String photo  = MUDload.downloadImage(appWxUserInfo.getHeadimgurl());
			logger.info("APP下载用户头像成功，filePath=="+photo);
			if(photo !=null&&photo.trim().length()>0){
				userinfo.setPhoto(photo);
			}
		}
		userinfo.setLastUpdateTime(new Date());
		if(StringUtil.isEmpty(userinfo.getUnionid())){
			userinfo.setUnionid(appWxUserInfo.getUnionid());
		}
		this.save(userinfo);
		
	}

	@Override
	public List<User> searchUserByIds(List<String> ids) {
	    return userDao.findAll(ids);
	}



	@Override
	public List<User> findByIdIn(List<String> ids) {
		return userDao.findByIdIn(ids);
	}



	@Override
	public User findByEasemobName(String easemobName) {
		return userDao.findByEasemobName(easemobName);
	}

	@Override
	public void generateQrcode(String userId) {
		User user=this.getById(userId);
		if(user!=null){
			if(StringUtils.isBlank(user.getQrCode())){
				QrCode  qrCode=	qrCodeService.generateQrcode(userId);
				user.setQrCode(qrCode.getQrcodeUrl());
				this.save(user);
			}
		}
		
	}

	@Override
	public String createUniqueEasemobName() {
		String easemobName = null;
		long time = System.currentTimeMillis();
		String random = RandomUtils.getRandomNumber(6);
		String sysEnv = (String) SystemResourceLocator.getValue("SYS_ENV");
		if ("1".equals(sysEnv)){
			easemobName = time+random+"1";
		} else {
			easemobName = time+random+"0";
		}
		return easemobName;
	}

	@Override
	public User findByMobile(String mobile) {
		return userDao.findByMobile(mobile);
	}

	@Override
	public List<User> findByEasemobNameIsNotNull() {
		return userDao.findByEasemobNameIsNotNull();
	}

	@Override
	public List<User> findNoUserEasemobName() {
		return userDao.findNoUserEasemobName();
	}
	
	
	//认证用户的密码是否正确
	@Override
	public boolean verificationPassword(String userId,String password){
		User user=userDao.getOne(userId);
		if(user!=null && StringUtils.isNotEmpty(user.getPassword())){
			String pwdSalt=user.getPwdSalt();
			String encryptionPassword=PasswordUtil.initPassword(password, pwdSalt);
			if(user.getPassword().equals(encryptionPassword)){
				return true;
			}
		}
		return false;
	}

	@Override
	public ResponseEntity bindWeixin(String accessToken, AppWxUserInfo appWxUserInfo) {
		ResponseEntity responseEntity = new ResponseEntity();
		String userId= tokenManager.getUserId(accessToken);
		User userinfo =this.getById(userId);
		if(StringUtil.isNoneBlank(userinfo.getUnionid())){
			responseEntity.failure("已绑定微信，不用重复绑定！");
			return responseEntity;
		}
		//tokenManager.removeToken(accessToken, "APP_TEACHER"); //移除旧token
		UserAccount userAccount=userAccountService.findUserAccountByOpenid(appWxUserInfo.getOpenid());

		if(userAccount==null){
            String appId = WxUtil.map.get("lsdMobileAppId");
			userAccount = new UserAccount();
			userAccount.setAppid(appId);
			userAccount.setOpenid(appWxUserInfo.getOpenid());
			userAccount.setUnionid(appWxUserInfo.getUnionid());
			userAccount.setUserId(userId);
			userAccount.setType(11);
		}else{
			userAccount.setUserId(userId);
		}
		userAccountService.save(userAccount);
		tokenManager.setString("user_id"+appWxUserInfo.getUnionid()+11,userId,30*24*3600);
		//tokenManager.createToken(accessToken, userId, userAccount.getOpenid(), 4, userAccount.getUnionid(),"APP_TEACHER");
		if(StringUtils.isBlank(userinfo.getEasemobName())) {
			//如果用户没有环信id
			userinfo.setEasemobName(this.createUniqueEasemobName());
			easemobService.createUserSingle(userinfo.getEasemobName(),userinfo.getUserName());
		}
		if(appWxUserInfo.getNickname()!=null){
			userinfo.setUserName(appWxUserInfo.getNickname());
			userinfo.setName(appWxUserInfo.getNickname());
			if(!appWxUserInfo.getNickname().equals(userinfo.getName())) {
				easemobService.updateUserNickName(userinfo.getEasemobName(), appWxUserInfo.getNickname());
			}
		}
		if(appWxUserInfo.getSex()!=null){userinfo.setSex(Integer.parseInt(appWxUserInfo.getSex()));}
		if(appWxUserInfo.getCity()!=null){userinfo.setCity(appWxUserInfo.getCity());}
		if(appWxUserInfo.getProvince()!=null){userinfo.setProvince(appWxUserInfo.getProvince());}
		if(appWxUserInfo.getHeadimgurl()!=null && !appWxUserInfo.getHeadimgurl().equals(userinfo.getWeixinPhoto())){
			userinfo.setWeixinPhoto(appWxUserInfo.getHeadimgurl());
			String photo  = MUDload.downloadImage(appWxUserInfo.getHeadimgurl());
			logger.info("APP下载用户头像成功，filePath=="+photo);
			if(photo !=null&&photo.trim().length()>0){
				userinfo.setPhoto(photo);
				managerService.updateManagerPhoto(userId, photo);
			}
		}
		userinfo.setLastUpdateTime(new Date());


		//根据unionid查找用户
		User user2 = this.getUserByUnionid(appWxUserInfo.getUnionid());
		if(user2!=null){ //之前存在用户更新openid
			userinfo.setAccount(user2.getAccount());
			user2.setUnionid(null);
			user2.setAccount(null);
			this.save(user2);
		}
		if(StringUtil.isEmpty(userinfo.getUnionid())){
			userinfo.setUnionid(appWxUserInfo.getUnionid());
		}
		this.save(userinfo);
		responseEntity.success("绑定成功！");
		return responseEntity;
	}

	@Override
	public void towInOneUser(String accessToken, User user,String phone) {
		String userId = tokenManager.getUserId(accessToken);
		if(userId!=null  && !"".equals(userId)){
			//存在手机用户并且与token用户不一致，将用户合并以手机用户为准
			if(user !=null && !user.getId().equals(userId)){
				User oldUser = this.getById(userId);
				tokenManager.removeToken(accessToken); //移除旧token
				if(oldUser!=null && oldUser.getMobile()!=null && oldUser.getUnionid()!=null){
					logger.info("老师端未合并用户微信用户id->"+userId+",微信用户unionid:"+oldUser.getUnionid()+",微信用户手机:"+oldUser.getMobile()+",手机用户id->"+user.getId()+",手机号码->"+user.getMobile());
				}else{
					logger.info("老师端合并用户微信用户id->"+userId+",手机用户id->"+user.getId()+",手机号码->"+user.getMobile());
					//创建新的token
					UserAccount userAccount = userAccountService.findByUserIdAndType(userId,11);
					if(userAccount == null) {
						tokenManager.createToken(accessToken, user.getId(), "APP_TEACHER");
					}else {
						tokenManager.createToken(accessToken, user.getId(), userAccount.getOpenid(), 4, userAccount.getUnionid(),"APP_TEACHER");
						if(StringUtil.isNotBlank(user.getId())){
							userAccountService.updateUserIdByUnionId(userAccount.getUnionid(),user.getId());
						}

					}

					//删除"user_id"+unionid+type 的值
					Set<String> strings =  redisUtil.keys("user_id"+oldUser.getUnionid()+"*");
					if(strings!=null){
						for(String str:strings){
							tokenManager.delString(str);
						}
					}
					logger.info("老师端合并用户unionid->"+oldUser.getUnionid()+"");
					tokenManager.setString("user_id"+oldUser.getUnionid()+11,user.getId(),30*24*3600);

					//更新manager表用户头像
					List<TbLibManager> managerList = managerService.getByUserId(user.getId());
					if(!managerList.isEmpty()){
						for (TbLibManager ma:managerList){
							ma.settPhoto(oldUser.getPhoto());
							managerService.save(ma);
						}
					}
					user.setName(oldUser.getName());
					user.setAccount(oldUser.getAccount());
					user.setUnionid(oldUser.getUnionid());
					user.setPhoto(oldUser.getPhoto());
					user.setSex(oldUser.getSex());
					user.setUserName(oldUser.getUserName());
					user.setWeixinPhoto(oldUser.getWeixinPhoto());
					user.setCity(oldUser.getCity());
					user.setSubscribe(oldUser.getSubscribe());
					user.setProvince(oldUser.getProvince());
					user.setLanguage(oldUser.getLanguage());
					user.setCountry(oldUser.getCountry());
					user.setQrCode(oldUser.getQrCode());
					if(StringUtils.isBlank(oldUser.getEasemobName())) {
						//如果用户没有环信id
						user.setEasemobName(this.createUniqueEasemobName());
						easemobService.createUserSingle(user.getEasemobName(),user.getUserName());
					}else {
						user.setEasemobName(oldUser.getEasemobName());
					}
					this.save(user);
					oldUser.setAccount(null);
					oldUser.setUnionid(null);
					oldUser.setUserName(oldUser.getName() + "合并手机用户，废弃!");
					this.save(oldUser);
				}
			}
		}
	}


	//通过手机号与密码登录
	@Override
	public User getUserByPassword(String mobile, String password) {
		User user=userDao.findByMobile(mobile);
		if(user!=null){
			if(verificationPassword(user.getId(),password)){
				return user;
			}
		}
		return null;
	}

	
	//通过用户id更新密码
	@Override
	public User updateByResetPassword(String userId, String newPassword) {
		User user=this.getById(userId);
		if(user!=null){
			String pwdSalt=PasswordUtil.generateSalt();
			String passwrod=PasswordUtil.initPassword(newPassword, pwdSalt);
			userDao.updateByPassword(userId, passwrod,pwdSalt);
			return user;
		}
		return null;
	}
	
	
	//通过用户id与旧密码更新密码
	@Override
	public User updateByPassword(String userId, String oldPassword,String newPassword) {
		User user=this.getById(userId);
		if(user!=null){
			if(verificationPassword(user.getId(),oldPassword)){
				return updateByResetPassword(userId, newPassword);
			}
		}
		return null;
	}
	
	
	//密码换绑定手机号
	@Override
	public User updateBindPhone(String userId,String password, String newphone) {
		User user=this.getById(userId);
		if(user!=null){
			if(verificationPassword(user.getId(),password)){
				user.setMobile(newphone);
				this.save(user);
				managerService.updateManagerPhone(user.getId(), newphone);
				return user;
			}
		}
		return null;
	}

	//开始设置用户绑定手机号和密码
	@Override
	public User updatePasswordBindPhone(String userId, String password,String phone) {
		User user=this.getById(userId);
		if(user!=null){
			User bindUser=this.findByMobile(phone);
			if(bindUser==null || userId.equals(bindUser.getId())){
				//user.setMobile(phone);
				userDao.updateUserPhone(user.getId(),phone);
				managerService.updateManagerPhone(user.getId(), phone);
				updateByResetPassword(userId,password);
				return user;
			}
		}
		return null;
	}


	@Override
	public User getUserIdByMobilePhone(String phone, String userName) {
		User user=this.findByMobile(phone);
		if(user==null){//无老师user，生成老师user
			user=new User();
			user.setId(IdWorker.generateId());
			user.setUserName(userName);
			user.setMobile(phone);
			user.setCreateTime(new Date());
		} else {
			user.setUserName(userName);
		}
		return this.save(user);
	}

	private void saveUserInfo(String openid,String unionid,String appid,Integer type,String userId,UserInfo  userInfo){

        unionid =StringUtil.isBlank(unionid) ? unionid :userInfo.getUnionId();
        User user= new User();
        user.setId(userId);
        user.setCreateTime(new Date());
        user.setUnionid(unionid);
        user.setSubscribe(0);
        if(userInfo.getNickName()!=null){
            user.setName(userInfo.getNickName());
            user.setUserName(userInfo.getNickName());
        }
        if(userInfo.getGender()!=null){
            int sex =1;
            if(userInfo.getGender().equals("2")){
                sex=2;
            }
            user.setSex(sex);
        }
        if(userInfo.getCity()!=null){user.setCity(userInfo.getCity());}
        if(userInfo.getProvince()!=null){user.setProvince(userInfo.getProvince());}
        if(userInfo.getCountry()!=null){user.setCountry(userInfo.getCountry());}
        if(userInfo.getLanguage()!=null){user.setLanguage(userInfo.getLanguage());}
        if(userInfo.getAvatarUrl()!=null && !userInfo.getAvatarUrl().equals(user.getWeixinPhoto())){
            user.setWeixinPhoto(userInfo.getAvatarUrl());
            String photo  = MUDload.downloadImage(userInfo.getAvatarUrl());
            logger.info("小程序保存下载用户头像成功，filePath=="+photo);
            if(photo !=null&&photo.trim().length()>0){
                user.setPhoto(photo);
            }
        }
        user.setLastUpdateTime(new Date());
        user=userDao.save(user);
        UserAccount 	userAccount = new UserAccount();
        userAccount.setAppid(appid);
        userAccount.setOpenid(openid);
        userAccount.setUnionid(unionid);
        userAccount.setUserId(user.getId());
        userAccount.setType(type);
        userAccountService.save(userAccount);

    }
}




class SyncSaveUserDBTask extends Task {

	private static Logger logger = LoggerFactory.getLogger(SyncSaveUserDBTask.class);

	private UserAccountService userAccountService;

	private UserDao userDao;
	private String openid ;
	private String unionid;
	private String appid;
	private Integer type;
	private String userId;

	public SyncSaveUserDBTask(String openid,String unionid,String appid,Integer type,String userId,UserAccountService userAccountService,UserDao userDao) {
		super();
		this.userAccountService=userAccountService;
		this.userDao=userDao;
		this.openid=openid;
		this.unionid=unionid;
		this.type=type;
		this.userId=userId;
		this.appid=appid;

	}

	@Override
	public void run() {
		try {
			logger.info("openid="+openid);
			logger.info("unionid="+unionid);
			logger.info("type="+type);
			logger.info("userId="+userId);
			logger.info("appid="+appid);


				User user= new User();
				user.setId(userId);
				user.setCreateTime(new Date());
				user.setUnionid(unionid);
				user.setSubscribe(0);
				user=userDao.save(user);
				UserAccount 	userAccount = new UserAccount();
				userAccount.setAppid(appid);
				userAccount.setOpenid(openid);
				userAccount.setUnionid(unionid);
				userAccount.setUserId(user.getId());
				userAccount.setType(type);
				userAccountService.save(userAccount);


		} catch (Exception e) {
			logger.error("推送信息保存异常...");
		}

	}

}


class SyncSaveUserInfoDBTask extends Task {

	private static Logger logger = LoggerFactory.getLogger(SyncSaveUserInfoDBTask.class);

	private UserAccountService userAccountService;

	private UserDao userDao;
	private  UserInfo  userInfo;
	private String openid ;
	private String unionid;
	private String appid;
	private Integer type;
	private String userId;

	public SyncSaveUserInfoDBTask(String openid,String unionid,String appid,Integer type,String userId,UserAccountService userAccountService,UserDao userDao,UserInfo  userInfo) {
		super();
		this.userAccountService=userAccountService;
		this.userDao=userDao;
		this.openid=openid;
		this.unionid=unionid;
		this.type=type;
		this.userId=userId;
		this.appid=appid;
		this.userInfo=userInfo;

	}

	@Override
	public void run() {
		try {
			logger.info("openid="+openid);
			logger.info("unionid="+unionid);
			logger.info("type="+type);
			logger.info("userId="+userId);
			logger.info("appid="+appid);

			logger.info("直接保存推送信息data:"+JSONObject.toJSONString(userInfo));
			unionid =StringUtil.isBlank(unionid) ? unionid :userInfo.getUnionId();
			User user= new User();
			user.setId(userId);
			user.setCreateTime(new Date());
			user.setUnionid(unionid);
			user.setSubscribe(0);



			if(userInfo.getNickName()!=null){
				user.setName(userInfo.getNickName());
				user.setUserName(userInfo.getNickName());
			}
			if(userInfo.getGender()!=null){
				int sex =1;
				if(userInfo.getGender().equals("2")){
					sex=2;
				}
				user.setSex(sex);
			}

			if(userInfo.getCity()!=null){user.setCity(userInfo.getCity());}

			if(userInfo.getProvince()!=null){user.setProvince(userInfo.getProvince());}

			if(userInfo.getCountry()!=null){user.setCountry(userInfo.getCountry());}

			if(userInfo.getLanguage()!=null){user.setLanguage(userInfo.getLanguage());}



			if(userInfo.getAvatarUrl()!=null && !userInfo.getAvatarUrl().equals(user.getWeixinPhoto())){
				user.setWeixinPhoto(userInfo.getAvatarUrl());
				String photo  = MUDload.downloadImage(userInfo.getAvatarUrl());
				logger.info("小程序保存下载用户头像成功，filePath=="+photo);
				if(photo !=null&&photo.trim().length()>0){
					user.setPhoto(photo);
				}
			}
			user.setLastUpdateTime(new Date());






			user=userDao.save(user);
			UserAccount 	userAccount = new UserAccount();
			userAccount.setAppid(appid);
			userAccount.setOpenid(openid);
			userAccount.setUnionid(unionid);
			userAccount.setUserId(user.getId());
			userAccount.setType(type);
			userAccountService.save(userAccount);


		} catch (Exception e) {
			logger.error("推送信息保存异常...");
		}

	}



}


