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

import com.ace.cache.annotation.Cache;
import com.ace.cache.annotation.CacheClear;
import com.github.wxiaoqi.security.admin.entity.AppUserDetail;
import com.github.wxiaoqi.security.admin.entity.AppUserLogin;
import com.github.wxiaoqi.security.admin.entity.AppUserRelationTemp;
import com.github.wxiaoqi.security.admin.vo.AppUserVo;
import com.github.wxiaoqi.security.admin.bo.InviteMemberBO;
import com.github.wxiaoqi.security.admin.vo.InviteMemberVo;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.github.wxiaoqi.security.admin.entity.AppUserRelation;
import com.github.wxiaoqi.security.admin.mapper.AppUserRelationMapper;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户关系表
 *
 * @author libin
 * @email 18178966185@163.com
 * @date 2019-07-03 16:36:44
 */
@Service
public class AppUserRelationBiz extends BaseBiz<AppUserRelationMapper,AppUserRelation> {

    @Autowired
    AppUserRelationTempBiz relationTempBiz;

    @Autowired
    AppUserDetailBiz userDetailBiz;

    @Autowired
    private AppUserLoginBiz appUserLoginBiz;

    @Value("${temamember.failureTime:60}")
    private Long failureTime;

    /**
     * 关系绑定
     * @param userId
     * @param parentId
     */
    public   void bindRelation(Integer userId,Integer parentId,Integer type){
        AppUserRelation relation=getMyBiz().getRelationByUserId(parentId);
         if(relation==null){
             relation=new AppUserRelation();
             relation.setUserId(parentId);
             insertSelective(relation);
         }
        relation=getMyBiz().getRelationByUserId(userId);
        Long time=System.currentTimeMillis();
         if(relation==null){
             relation=new AppUserRelation();
             relation.setUserId(userId);
             relation.setParentId(parentId);
             relation.setBindType(type);
             relation.setBindTime(time);
             insertSelective(relation);
         }else {
             if(relation.getParentId()==null||relation.getParentId()==0||(relation.getIsForever()!=1&&(time-relation.getBindTime())>3600)){
                 relation.setParentId(parentId);
                 relation.setBindType(type);
                 relation.setBindTime(time);
                getMyBiz().updRelation(relation);
             }
         }
    }
    //永久稳定关系
    public void foreverBind(Integer user_id ){
        AppUserRelation relation=getMyBiz().getRelationByUserId(user_id);
        if(relation!=null&&relation.getIsForever()==0&&relation.getParentId()!=null&&relation.getParentId()>0){
            relation.setIsForever(1);
            getMyBiz().updRelation(relation);
        }

    }

    /**
     * 小程序分享上下线绑定
     * @param userid  当前人小程序id
     * @param pid  分享人id
     * @param platform_userid  当前人统一平台id
     */
    public ObjectRestResponse shareParentByUserId(Integer userid, Integer pid, Integer platform_userid){
        if(pid==null||pid==0||((platform_userid==null||platform_userid==0)&&(userid==0||userid==null))){
            return ObjectRestResponse.createFailedResult(ResultCode.NULL_CODE, "参数为空");
        }
        if(platform_userid==null||platform_userid==0){
            upRelationTemp(pid,userid);
        }else {
            AppUserVo userVo=userDetailBiz.getUserInfoById(platform_userid);
            if(userVo==null){
                upRelationTemp(pid,userid);
            }else {
                bindRelation(platform_userid,pid,2);
            }
        }
        return ObjectRestResponse.succ();

    }

    /**
     * 新增临时关系
     * @param pid
     * @param userid
     */
    public  void upRelationTemp(Integer pid,Integer userid){

        AppUserRelationTemp relationTemp=new AppUserRelationTemp();
        relationTemp.setUserId(pid);
        relationTemp.setIsDel(0);
        relationTemp.setType(1);
        AppUserRelationTemp relationTemp1= relationTempBiz.selectOne(relationTemp);
        if(relationTemp1==null){
            relationTemp.setTempId(userid);
            relationTempBiz.insertSelective(relationTemp);
        }

    }

    /**
     * 小程序上下线绑定
     * @param platform_userid 当前人统一平台id
     * @param userid 当前人小程序id
     */
    public void bindByUserId(Integer platform_userid,Integer userid){
        if(platform_userid==null||platform_userid==0||userid==null||userid==0){
            return;
        }
        AppUserRelationTemp relationTemp =new AppUserRelationTemp();
        relationTemp.setTempId(userid);
        relationTemp.setIsValid(0);
        relationTemp.setType(1);
        relationTemp.setIsDel(0);
        relationTemp=relationTempBiz.selectOne(relationTemp);
        if(relationTemp==null){
           return;
        }
        Integer parentId=relationTemp.getUserId();
        bindRelation(platform_userid,parentId,2);

    }

    /**
     * 获取用户的上线关系
     * @param userId
     * @return
     */
    @Cache(key="user:relation{1}")
    public  AppUserRelation getRelationByUserId(Integer userId){
        AppUserRelation relation=new AppUserRelation();
        relation.setUserId(userId);
        return  selectOne(relation);
    }

     @CacheClear(key="user:relation{1.userId}")
    public  int  updRelation(AppUserRelation appUserRelation){
       return super.updateSelectiveByIdRe(appUserRelation);
    }

    private AppUserRelationBiz getMyBiz() {
        return AopContext.currentProxy() != null ? (AppUserRelationBiz) AopContext.currentProxy() : this;
    }

    public PageDataVO<AppUserRelation> findMemberPageByLeaderId(Integer leaderId, Integer pageNo, Integer pageSize) {
       return PageDataVO.pageInfo(pageNo, pageSize, () -> mapper.selectByLeaderId(leaderId));
    }

    public InviteMemberVo findInviteMemberByActivitState(Integer leaderId, Integer state, Integer page, Integer limit) {

        InviteMemberVo inviteMemberVo = new InviteMemberVo();
        inviteMemberVo.setPage(page);
        inviteMemberVo.setLimit(limit);
        inviteMemberVo.setFailureTime(failureTime*24*60*60);
        Example example = new Example(AppUserRelation.class);
        Example.Criteria criteria = example.createCriteria();
        if (state!=null) {
            criteria.andEqualTo("isForever", state);
        }
        criteria.andEqualTo("parentId",leaderId);
        PageDataVO<AppUserRelation> pageDataVO = PageDataVO.pageInfo(page, limit, () -> mapper.selectByExample(example));
        List<AppUserRelation> appUserRelations = pageDataVO.getData();
        if (CollectionUtils.isEmpty(appUserRelations)){
            inviteMemberVo.setInviteMembers(Collections.EMPTY_LIST);
            return inviteMemberVo;
        }

        List<Integer> memberIds = appUserRelations.stream().map(AppUserRelation::getUserId).collect(Collectors.toList());
        Map<Integer, AppUserLogin> userIdAndUserLoginMap = appUserLoginBiz.findUserIdAndUserLoginMapByMemberIds(memberIds);
        Map<Integer, AppUserDetail> userIdAndUserDetailMap = userDetailBiz.findUserIdAndUserDetailMapByMemberIds(memberIds);

        List<InviteMemberBO> inviteMemberBOS = new ArrayList<>();
        InviteMemberBO inviteMemberBO;
        for (AppUserRelation appUserRelation : appUserRelations) {
           inviteMemberBO = new InviteMemberBO();
           inviteMemberBO.setBindTime(appUserRelation.getBindTime());
           inviteMemberBO.setJoinTime(appUserRelation.getBindTime());
           inviteMemberBO.setUsername(userIdAndUserLoginMap.get(appUserRelation.getUserId()).getUsername());
           inviteMemberBO.setHeadUrl(userIdAndUserDetailMap.get(appUserRelation.getUserId()).getHeadimgurl());
           inviteMemberBOS.add(inviteMemberBO);
        }
        inviteMemberVo.setTotalCount(pageDataVO.getTotalCount().intValue());
        inviteMemberVo.setTotalPage(pageDataVO.getTotalPage());
        inviteMemberVo.setInviteMembers(inviteMemberBOS);
        return inviteMemberVo;
    }

    public Integer findLeaderIdByMemberId(Integer userId) {
         Example example = new Example(AppUserRelation.class);
         Example.Criteria criteria = example.createCriteria();
         criteria.andEqualTo("userId",userId);
         List<AppUserRelation> appUserRelations = mapper.selectByExample(example);
        if (CollectionUtils.isEmpty(appUserRelations)){
            return 0;
        }
        return appUserRelations.get(0).getParentId();
    }

    public Map<Integer, Integer> findMemberSateAndCountMapByLeaderId(Integer userId) {
         Map<Integer,Integer> memberSateAndCountMap = new HashMap<>();
        AppUserRelation appUserRelation = new AppUserRelation();
        appUserRelation.setParentId(userId);
        int totalCount = mapper.selectCount(appUserRelation);
        appUserRelation.setIsForever(1);
        int activityCount = mapper.selectCount(appUserRelation);
        memberSateAndCountMap.put(0,totalCount);
        memberSateAndCountMap.put(1,activityCount);
        return memberSateAndCountMap;
    }
}