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 lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
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
@Slf4j
public class AppUserRelationBiz extends BaseBiz<AppUserRelationMapper,AppUserRelation> {

    @Autowired
    AppUserRelationTempBiz relationTempBiz;

    @Autowired
    AppUserDetailBiz userDetailBiz;

    @Autowired
    private AppUserLoginBiz appUserLoginBiz;

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

    @Autowired
    private  AppUserDetailBiz appUserDetailBiz;

    @Value("${admin.validTime}")
    private  Long  validTime;

    /**
     * 关系绑定
     * 规则A->B (B无有效上线+无有效下线)
     * @param userId
     * @param parentId
     */
    public   void bindRelation(Integer userId,Integer parentId,Integer type){
        if (userId.equals(parentId)){
            log.info("----userId==="+userId+"----parentId===="+parentId+"----自己不能成为自己的上线");
            return;
        }
        AppUserVo appUserVo=userDetailBiz.getUserInfoById(userId);
        if (appUserVo==null){
            log.info("----userId==="+userId+"----parentId===="+parentId+"----该用户不存在");
            return;
        }
         appUserVo=userDetailBiz.getUserInfoById(parentId);
        if (appUserVo==null){
            log.info("----userId==="+userId+"----parentId===="+parentId+"----该上线用户不存在");
            return;
        }
        AppUserRelation relation=getMyBiz().getRelationByUserId(parentId);
        Long time=System.currentTimeMillis();
         if(relation==null){
             relation=new AppUserRelation();
             relation.setUserId(parentId);
             relation.setBindType(type);
             insertSelective(relation);
         }
        Long bindTime=time-validTime;
         //判断用户是否有有效的下线
        if (getCountByParentId(userId,bindTime)==0L){
            relation=getMyBiz().getRelationByUserId(userId);
            if(relation==null){
                relation=new AppUserRelation();
                relation.setUserId(userId);
                relation.setParentId(parentId);
                relation.setBindType(type);
                relation.setBindTime(time);
                insertSelective(relation);
            }else {
                //判断用户是否有有效的上线
                log.info("----userId==="+userId+"----bindTime===="+bindTime+"----relation.getBindTime()==="+relation.getBindTime());
                if(relation.getParentId()==null||relation.getParentId()==0||(relation.getIsForever()!=1&&validTime>0&&relation.getBindTime()<bindTime)){
                    relation.setParentId(parentId);
                    relation.setBindType(type);
                    relation.setBindTime(time);
                    getMyBiz().updRelation(relation);
                }
            }
        }
    }
    //首页关系绑定
    public  ObjectRestResponse  appBindRelation(Integer userId,String code){
        Integer parentId=0;
        if (StringUtils.isNotBlank(code)){
            //判断处理活动关键字
            String[] codes = code.split("_");
            if(codes.length > 1) {
                code = codes[0];
            }
            parentId=appUserDetailBiz.getUserByCode(code);
        }
        if (parentId!=null&&parentId>0&&userId!=null&&userId>0){
            getMyBiz().bindRelation(userId,parentId,1);
        }
        return  ObjectRestResponse.succ();
    }
    //永久稳定关系
    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.setTempId(userid);
        relationTemp.setIsDel(0);
        relationTemp.setType(1);
        AppUserRelationTemp relationTemp1= relationTempBiz.selectOne(relationTemp);
        if(relationTemp1==null){
            relationTemp.setUserId(pid);
            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);
    }

    //获取有效的上线
    public  AppUserRelation getRelationByIdUserIdAndTime(Integer userId){
        AppUserRelation userRelation= getMyBiz().getRelationByUserId(userId);
        if (userRelation==null){
            return    null;
        }
        log.info("---userId==="+userId+"-----isForever==="+userRelation.getIsForever());
        Long time=System.currentTimeMillis()-validTime;
        if (userRelation.getIsForever()==1||userRelation.getBindTime()>time){
            return  userRelation;
        }
        log.info("---userId==="+userId+"-----time==="+time+"----userRelation.getBindTime()==="+userRelation.getBindTime());
        return  null;
    }

    //获取用户的下线总数
    public  int getCountByParentId(Integer parentId,Long time){
         if (validTime<=0){
             time= validTime;
         }
        return  mapper.countByParentId(parentId,time);
    }

     @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) {
            if (userIdAndUserLoginMap==null || userIdAndUserDetailMap==null){
                continue;
            }
           inviteMemberBO = new InviteMemberBO();
           inviteMemberBO.setBindTime(appUserRelation.getBindTime());
           inviteMemberBO.setJoinTime(appUserRelation.getBindTime());
           inviteMemberBO.setUsername(userIdAndUserLoginMap==null?"":userIdAndUserLoginMap.get(appUserRelation.getUserId())==null?"":userIdAndUserLoginMap.get(appUserRelation.getUserId()).getUsername());
           inviteMemberBO.setHeadUrl(userIdAndUserDetailMap==null?"":userIdAndUserDetailMap.get(appUserRelation.getUserId())==null?"":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);
        appUserRelation.setIsForever(0);
        int totalCount = mapper.selectCount(appUserRelation);
        appUserRelation.setIsForever(1);
        int activityCount = mapper.selectCount(appUserRelation);
        memberSateAndCountMap.put(0,totalCount);
        memberSateAndCountMap.put(1,activityCount);
        return memberSateAndCountMap;
    }

    public void deleteByMemberIds(Collection<Integer> userIds) {
        Example example = new Example(AppUserRelation.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("parentId",userIds);
        List<AppUserRelation> list=mapper.selectByExample(example);
        for (AppUserRelation appUserRelation:list){
            getMyBiz().delRelation(appUserRelation.getUserId());
        }
        mapper.deleteByExample(example);
        Example example2 = new Example(AppUserRelation.class);
        Example.Criteria criteria1 = example2.createCriteria();
        criteria1.andIn("userId",userIds);
        mapper.deleteByExample(example2);
        for (Integer userId:userIds){
            getMyBiz().delRelation(userId);
        }
    }
    @CacheClear(key="user:relation{1}")
    public  void delRelation(Integer userId){

    }




    }

