package com.github.wxiaoqi.security.admin.biz;

import com.ace.cache.annotation.Cache;
import com.ace.cache.annotation.CacheClear;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.admin.entity.AppUserLogin;
import com.github.wxiaoqi.security.admin.mapper.AppUserLoginMapper;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.config.rabbit.RabbitConstant;
import com.github.wxiaoqi.security.common.constant.UserConstant;
import com.xxfc.platform.universal.entity.IdInformation;
import com.xxfc.platform.universal.feign.MQSenderFeign;
import com.xxfc.platform.universal.feign.ThirdFeign;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * ${DESCRIPTION}
 *
 * @author wanghaobin
 * @create 2017-06-08 16:23
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AppUserLoginBiz extends BaseBiz<AppUserLoginMapper, AppUserLogin> {

    private static final  String WX_TYPE="wx";
    private static final  String QQ_TYPE="q";

    @Autowired
    ThirdFeign thirdFeign;
    @Autowired
    MQSenderFeign mqSenderFeign;

    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    @Override
    public void insertSelective(AppUserLogin entity) {
        String password = new BCryptPasswordEncoder(UserConstant.PW_ENCORDER_SALT).encode(entity.getPassword());
        entity.setPassword(password);
        super.insertSelective(entity);
    }

    @Override
    @CacheClear(pre = "user{1.username}")
    public void updateSelectiveById(AppUserLogin entity) {
        super.updateSelectiveById(entity);
    }

    @CacheClear(pre = "user{1.username}")
    public int bindOpenid(AppUserLogin entity) {
        return  mapper.bindOpenId(entity);
    }

    @CacheClear(pre = "user{1.username}")
    public void updatePasswordById(AppUserLogin entity) {
        String password = new BCryptPasswordEncoder(UserConstant.PW_ENCORDER_SALT).encode(entity.getPassword());
        entity.setPassword(password);
        super.updateSelectiveById(entity);
    }

    public Object test() {
        threadRunner();
        return "success";
    }

    public void threadRunner() {
        List<AppUserLogin> list = mapper.selectAll();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new Runnable() {
             @Override
              public void run() {
                 if(list != null && list.size() > 0) {
                     for(AppUserLogin appUserLogin : list) {
                         try {
                             Thread.sleep(3000);
                         } catch (Exception e){}
                         IdInformation idInformation = thirdFeign.getOneByUserId(appUserLogin.getId());
                         if(idInformation != null) { //实名认证
                             JSONObject jsonObject = new JSONObject();
                             jsonObject.put("userId", appUserLogin.getId());
                             jsonObject.put("integralRuleCode", "CRETIFICATION");
                             jsonObject.put("channelId", idInformation.getId());
                             mqSenderFeign.sendMessage(RabbitConstant.INTEGRAL_TOPIC, RabbitConstant.INTEGRAL_ROUTING_KEY, jsonObject.toJSONString());
                         }
                         try {
                             Thread.sleep(3000);
                         } catch (Exception e){}
                         JSONObject jsonObject = new JSONObject();
                         jsonObject.put("userId", appUserLogin.getId());
                         jsonObject.put("integralRuleCode", "REGISTER");
                         jsonObject.put("channelId", appUserLogin.getId());
                         mqSenderFeign.sendMessage(RabbitConstant.INTEGRAL_TOPIC, RabbitConstant.INTEGRAL_ROUTING_KEY, jsonObject.toJSONString());

                     }
                 }
               }
        });
    }

    /**
     * 根据用户名获取用户信息
     *
     * @param username
     * @return
     */
    @Cache(key = "user{1}")
    public AppUserLogin getUserByUsername(String username) {
        AppUserLogin user = new AppUserLogin();
        user.setUsername(username);
        return mapper.selectOne(user);
    }

   /* public TableResultResponse<AppUserLogin> selectPage(Query query, AppUserLogin currentUser) {
        if(DATA_ALL_TRUE.equals(currentUser.getDataAll())) {
            return super.selectByQuery(query);
        }else {
            Example example = new Example(User.class);
            if(query.entrySet().size()>0) {
                Example.Criteria criteria = example.createCriteria();
                for (Map.Entry<String, Object> entry : query.entrySet()) {
                    criteria.andLike(entry.getKey(), "%" + entry.getValue().toString() + "%");
                }
            }
            if(StringUtils.isNotBlank(currentUser.getDataCompany())){
                example.createCriteria().andIn("companyId", Arrays.asList(currentUser.getDataCompany().split(",")));
            }
            if(StringUtils.isNotBlank(currentUser.getDataZone())){
                example.createCriteria().andIn("zoneId", Arrays.asList(currentUser.getDataZone().split(",")));
            }
            Page<Object> result = PageHelper.startPage(query.getPage(), query.getLimit());
            List<User> list = mapper.selectByExample(example);
            return new TableResultResponse<User>(result.getTotal(), list);
        }
    }*/

    /**
     * 根据手机号码判断是否存在用户
     *
     * @param username
     * @return
     * @throws Exception
     */

    public AppUserLogin checkeUserLogin(String username) {
        Example example = new Example(AppUserLogin.class);
        example.createCriteria().andEqualTo("username", username).andEqualTo("isdel", 0).andEqualTo("status", 0);
        List<AppUserLogin> userLoginList = mapper.selectByExample(example);
        if (userLoginList != null && userLoginList.size() != 0) {
            return userLoginList.get(0);
        }
        return null;
    }

    /**
     * 根据微信号判断是否存在用户
     *
     * @param openid
     * @return
     */
    public AppUserLogin getUserByOpenid(String openid, Integer isQQ) {
        Example example = new Example(AppUserLogin.class);
        if (isQQ == 1) {
            example.createCriteria().andEqualTo("openid", openid).andEqualTo("isdel", 0);
        } else {
            example.createCriteria().andEqualTo("wxOpenid", openid).andEqualTo("isdel", 0);
        }
        List<AppUserLogin> userLoginList = mapper.selectByExample(example);
        if (userLoginList != null && userLoginList.size() != 0) {
            return userLoginList.get(0);
        }
        return null;
    }

    /**
     * 根据手机号码判断是否已绑定微信
     *
     * @param userLogin
     * @return
     */
    public boolean checkeWechatUser(AppUserLogin userLogin) {
        boolean flag = true;
        if (null != userLogin) {
            Integer userid = userLogin.getId();
            userLogin = mapper.selectByPrimaryKey(userid);
            if (userLogin == null) {
                flag = false;
            }
        }
        return flag;
    }

    //获取用户信息
    public AppUserLogin getUserById(Integer userId) {
        return mapper.selectByPrimaryKey(userId);
    }

    /**
     * 登录信息更改
     *
     * @param userId
     * @param ip
     */
    public void updateLoginInfo(Integer userId, String ip) {
        mapper.updateLoginUserInfoById(userId, ip, Instant.now().toEpochMilli());
    }

    public Map<String, Integer> findPhoneAndUserIdMapByPhones(List<String> phones) {
        List<AppUserLogin> appUserLogins = mapper.selectbyPhones(phones);
        Map<String, Integer> phoneAndUserIdMap = null;
        if (CollectionUtils.isNotEmpty(appUserLogins)) {
            phoneAndUserIdMap = appUserLogins.stream().collect(Collectors.toMap(AppUserLogin::getUsername, AppUserLogin::getId));
        }
        return phoneAndUserIdMap;
    }

    public Map<Integer, AppUserLogin> findUserIdAndUserLoginMapByMemberIds(List<Integer> memberIds) {
         Map<Integer,AppUserLogin>  userIdAndAppUserLoginMap = new HashMap<>();
        List<AppUserLogin> appUserLogins = mapper.selectByIdList(memberIds);
        if (CollectionUtils.isNotEmpty(appUserLogins)){
           userIdAndAppUserLoginMap = appUserLogins.stream().collect(Collectors.toMap(AppUserLogin::getId, Function.identity()));
        }
        return userIdAndAppUserLoginMap;
    }

    public AppUserLogin findUserByImiId(Integer imiId) {
        Example example = new Example(AppUserLogin.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("imUserid",imiId);
        List<AppUserLogin> appUserLogins = mapper.selectByExample(example);
        if (CollectionUtils.isNotEmpty(appUserLogins)){
            return appUserLogins.get(0);
        }
        return null;
    }

    @CacheClear(pre = "user{1.id}")
    public void disable(AppUserLogin appUserLogin) {
      mapper.updateByPrimaryKeySelective(appUserLogin);
    }

    @CacheClear(pre = "user{1.id}")
    public void available(AppUserLogin appUserLogin) {
        mapper.updateByPrimaryKeySelective(appUserLogin);
    }

    public void deleteByPhones(List<String> phons) {
        Example example = new Example(AppUserLogin.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("username",phons);
        mapper.deleteByExample(example);
    }

    @CacheClear(pre = "user{1}")
    @Transactional(rollbackFor = Exception.class)
    public void deleteAppUserById(Integer id) {
        AppUserLogin appUserLogin = new AppUserLogin();
        appUserLogin.setId(id);
        appUserLogin.setIsdel(1);
        mapper.updateByPrimaryKeySelective(appUserLogin);
    }

    public List<Integer> findAllExistUserIds(){
       return mapper.selectAllExistUserIds();
    }

    /**
     * 检查第三方是否绑定
     * @param wxOpenId
     * @param wxUnionId
     * @param openId
     * @return
     */
    public boolean checkThirdPartyBindingState(String wxOpenId, String wxUnionId, String openId) {
         AppUserLogin appUserLogin = new AppUserLogin();
         appUserLogin.setWxOpenid(wxOpenId);
         appUserLogin.setUnionid(wxUnionId);
         appUserLogin.setOpenid(openId);
       return mapper.selectOne(appUserLogin) != null;
    }

    @CacheClear(pre = "user{2}")
    public void unBindThirdPartyByType(String type,String username,Integer userId) {
        AppUserLogin appUserLogin = new AppUserLogin();
        appUserLogin.setId(userId);
        //微信解绑
        if (WX_TYPE.equals(type)){
            appUserLogin.setWxOpenid("");
            appUserLogin.setUnionid("");
            mapper.updateByPrimaryKeySelective(appUserLogin);
        }
         //qq解绑
        if (QQ_TYPE.equals(type)){
             appUserLogin.setOpenid("");
             mapper.updateByPrimaryKeySelective(appUserLogin);
        }
    }
}
