package com.red.circle.other.infra.common.family;

import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.external.inner.endpoint.message.ImGroupMemberClient;
import com.red.circle.external.inner.model.cmd.message.GroupMemberAddCmd;
import com.red.circle.external.inner.model.cmd.message.GroupMemberRemoveCmd;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.infra.convertor.material.BadgeInfraConvertor;
import com.red.circle.other.infra.database.cache.key.FamilyKeys;
import com.red.circle.other.infra.database.cache.service.other.FamilyLevelCacheService;
import com.red.circle.other.infra.database.rds.entity.badge.BadgeBackpack;
import com.red.circle.other.infra.database.rds.entity.badge.BadgePictureConfig;
import com.red.circle.other.infra.database.rds.entity.family.FamilyBaseInfo;
import com.red.circle.other.infra.database.rds.entity.family.FamilyLevelConfig;
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
import com.red.circle.other.infra.database.rds.entity.props.PropsBackpack;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.service.badge.BadgeBackpackService;
import com.red.circle.other.infra.database.rds.service.badge.BadgePictureConfigService;
import com.red.circle.other.infra.database.rds.service.family.FamilyBaseInfoService;
import com.red.circle.other.infra.database.rds.service.family.FamilyLevelConfigService;
import com.red.circle.other.infra.database.rds.service.family.FamilyLevelExpService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberWeekExpService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMonthExpService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberTotalExpService;
import com.red.circle.other.infra.database.rds.service.family.FamilyWeekExpService;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.props.PropsBackpackService;
import com.red.circle.other.infra.database.rds.service.props.PropsSourceRecordService;
import com.red.circle.other.infra.enums.family.FamilyRoleEnum;
import com.red.circle.other.infra.enums.family.FamilyStatusEnum;
import com.red.circle.other.inner.asserts.FamilyErrorCode;
import com.red.circle.other.inner.enums.material.BadgeBackpackExpireType;
import com.red.circle.other.inner.enums.material.PropsCommodityType;
import com.red.circle.other.inner.model.dto.famliy.FamilyDetailsDTO;
import com.red.circle.other.inner.model.dto.material.BadgeBackpackDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;

/**
 * 家族增加增加经验值或升级.
 *
 * @author pengshigang
 * @since 2021-07-21
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class FamilyCommon {

  private final UserRegionGateway userRegionGateway;
  private final GiftConfigService giftConfigService;
  private final UserProfileGateway userProfileGateway;
  private final ImGroupMemberClient imGroupMemberClient;
  private final BadgeInfraConvertor badgeInfraConvertor;
  private final BadgeBackpackService badgeBackpackService;
  private final PropsBackpackService propsBackpackService;
  private final FamilyWeekExpService familyWeekExpService;
  private final FamilyLevelExpService familyLevelExpService;
  private final FamilyMonthExpService familyMonthExpService;
  private final FamilyBaseInfoService familyBaseInfoService;
  private final FamilyMemberInfoService familyMemberInfoService;
  private final FamilyLevelCacheService familyLevelCacheService;
  private final PropsSourceRecordService propsSourceRecordService;
  private final FamilyLevelConfigService familyLevelConfigService;
  private final BadgePictureConfigService badgePictureConfigService;
  private final FamilyMemberWeekExpService familyMemberWeekExpService;
  private final FamilyMemberTotalExpService familyMemberTotalExpService;
  private final RedisService redisService;

  private static final long BASE_RETRY_INTERVAL = 200L;
  private static final int MAX_RETRY = 8;

  /**
   * 移除群聊.
   */
  public void removeGroup(Long familyId, Long userId) {

    if (Objects.isNull(familyId) || Objects.isNull(userId)) {
      return;
    }

    FamilyBaseInfo familyBaseInfo = familyBaseInfoService.getBaseInfoById(familyId);
    if (Objects.isNull(familyBaseInfo)) {
      return;
    }
    imGroupMemberClient.removeGroupMember(new GroupMemberRemoveCmd()
        .setGroupId("FAMILY_" + familyBaseInfo.getFamilyAccount())
        .setAccounts(List.of(userId))
        .setSilenceType(Boolean.FALSE)
    );
  }

  /**
   * 添加成员.
   */
  public void addGroup(Long familyId, Long userId) {
    if (Objects.isNull(familyId) || Objects.isNull(userId)) {
      return;
    }

    FamilyBaseInfo familyBaseInfo = familyBaseInfoService.getBaseInfoById(familyId);
    if (Objects.isNull(familyBaseInfo)) {
      return;
    }

    imGroupMemberClient.addGroupMember(new GroupMemberAddCmd()
        .setGroupId("FAMILY_" + familyBaseInfo.getFamilyAccount())
        .setAccounts(List.of(userId))
        .setSilenceType(Boolean.FALSE)
    );
  }

  public void addFamilyExpAndLevelUp(Long userId, String sysOrigin, Long exp) {
    FamilyMemberInfo member = getFamilyMember(userId);
    if (Objects.isNull(member)) {
      return;
    }

    String lockKey = "family:level:lock:" + member.getFamilyId();
    int retryCount = 0;
    boolean lockAcquired = false;

    while (retryCount < MAX_RETRY) {
      try {
        lockAcquired = redisService.setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS);

        if (lockAcquired) {
          try {
            processExpAndLevelUpWithLock(member, sysOrigin, exp);
            return;
          } catch (Exception ex) {
            log.error("处理家族经验升级异常,FamilyId:{},userId:{},exp:{},error:{}",
                    member.getFamilyId(), userId, exp, Throwables.getStackTraceAsString(ex));
            throw ex;
          } finally {
            try {
              redisService.delete(lockKey);
              lockAcquired = false;
            } catch (Exception e) {
              log.error("释放家族升级锁异常,FamilyId:{},error:{}",
                      member.getFamilyId(), e.getMessage());
            }
          }
        }

        // 未获取到锁，进行重试
        retryCount++;
        if (retryCount < MAX_RETRY) {
          Thread.sleep((long)(BASE_RETRY_INTERVAL * Math.pow(2, retryCount)));
        }

      } catch (InterruptedException e) {
        // 中断异常处理
        Thread.currentThread().interrupt();
        log.error("获取家族升级锁被中断,FamilyId:{}", member.getFamilyId());

        if (lockAcquired) {
          try {
            redisService.delete(lockKey);
          } catch (Exception ex) {
            log.error("中断时释放锁异常,FamilyId:{}", member.getFamilyId());
          }
        }
        return;
      } catch (Exception ex) {
        // 其他异常处理（包括业务异常）
        log.error("获取家族升级锁异常,FamilyId:{},userId:{},error:{}",
                member.getFamilyId(), userId, Throwables.getStackTraceAsString(ex));

        if (lockAcquired) {
          try {
            redisService.delete(lockKey);
          } catch (Exception e) {
            log.error("异常时释放锁失败,FamilyId:{}", member.getFamilyId());
          }
        }
        return;
      }
    }

    // 重试失败日志
    log.error("获取家族升级锁失败,重试{}次后放弃,FamilyId:{},userId:{},exp:{}",
            MAX_RETRY, member.getFamilyId(), userId, exp);
  }
  
  /**
   * 在分布式锁保护下处理经验值和升级
   */
  private void processExpAndLevelUpWithLock(FamilyMemberInfo member, String sysOrigin, Long exp) {
    FamilyBaseInfo familyBaseInfo = familyBaseInfoService.getById(member.getFamilyId());
    if (Objects.isNull(familyBaseInfo)) {
      return;
    }

    String regionId = userRegionGateway.getRegionId(familyBaseInfo.getCreateUser());
    if (StringUtils.isBlank(regionId)) {
      return;
    }

    FamilyDetailsDTO currentLevel = getFamilyDetails(sysOrigin, member.getFamilyId());
    if (StringUtils.isBlank(sysOrigin) || Objects.isNull(currentLevel) || Objects.isNull(currentLevel.getLevel())) {
      log.error("增加家族经验失败,FamilyId:{}", member.getFamilyId());
      return;
    }

    processExpAndLevelUp(member, currentLevel, exp, sysOrigin, regionId);
  }

  /**
   * 处理经验值增加和升级逻辑
   */
  private void processExpAndLevelUp(FamilyMemberInfo member, FamilyDetailsDTO currentLevel,
                                    Long exp, String sysOrigin, String regionId) {

    long remainingExp = exp;
    FamilyDetailsDTO levelInfo = currentLevel;
    
    // 先统计一次总经验（只统计一次）
    expAccumulate(member, exp, regionId);

    while (remainingExp > 0) {
      FamilyLevelConfig nextLevel = getNewLevel(sysOrigin, levelInfo);

      if (Objects.isNull(nextLevel)) {
        // 满级了，剩余经验全部加到当前等级
        familyLevelExpService.incrExp(member.getFamilyId(), 
            levelInfo.getFamilyLevelId(), BigDecimal.valueOf(remainingExp));
        break;
      }

      long currentLevelCompleteExp = levelInfo.getLevelExp();
      long currentFamilyExp = familyLevelExpService.mapTotalExpCountByFamilyIds(new HashSet<>(Collections.singletonList(levelInfo.getFamilyId())))
              .getOrDefault(levelInfo.getFamilyId(), BigDecimal.ZERO).longValue();
      long expNeeded = currentLevelCompleteExp - currentFamilyExp;

      if (remainingExp < expNeeded) {
        // 经验不足以升级，全部加到当前等级
        familyLevelExpService.incrExp(member.getFamilyId(), 
            levelInfo.getFamilyLevelId(), BigDecimal.valueOf(remainingExp));
        break;
      }

      // 经验足够升级
      // 1. 把当前等级加满
      if (expNeeded > 0) {
        familyLevelExpService.incrExp(member.getFamilyId(), 
            levelInfo.getFamilyLevelId(), BigDecimal.valueOf(expNeeded));
      }
      
      // 2. 升级
      familyLevelUp(member, nextLevel);
      
      // 3. 剩余经验进入下一轮循环
      remainingExp -= expNeeded;
      
      // 4. 初始化新等级经验记录（如果有剩余经验，在下一轮循环会加上）
      if (remainingExp > 0) {
        familyLevelExpService.incrExp(member.getFamilyId(), 
            nextLevel.getId(), BigDecimal.ZERO);
      }
      
      // 5. 刷新等级信息
      levelInfo = getFamilyDetails(sysOrigin, member.getFamilyId());
    }
  }



  /**
   * 移除家族所有人的头饰与徽章.
   *
   * @param familyId 家族ID
   * @param newLevel 新等级
   */
  public void removeFamilyAllProps(Long familyId, FamilyLevelConfig newLevel) {

    List<Long> userIdList = getUserIds(familyId);
    if (CollectionUtils.isEmpty(userIdList)) {
      return;
    }

    List<FamilyLevelConfig> levelConfigs = getFamilyLevelConfigs();
    if (CollectionUtils.isEmpty(levelConfigs)) {
      log.error("移除家族道具,FamilyId:{}, 没有家族规则数据", familyId);
      return;
    }
    Set<Long> badgeIds = getBadgeIds(levelConfigs);

    Set<Long> avatarFrameIds = getAvatarFrameIds(levelConfigs);

    if (Objects.nonNull(newLevel)) {
      badgeIds.add(newLevel.getBadgeId());
      avatarFrameIds.add(newLevel.getAvatarFrameId());
    }

    List<List<Long>> memberBatch = Lists.partition(userIdList, 200);
    memberBatch.forEach(membersUserIds -> {

      if (CollectionUtils.isNotEmpty(badgeIds)) {
        badgeBackpackService.deleteBadge(new HashSet<>(membersUserIds)
            , badgeIds);
      }
      if (CollectionUtils.isNotEmpty(avatarFrameIds)) {
        propsBackpackService.deleteProps(Sets.newHashSet(membersUserIds), avatarFrameIds,
            PropsCommodityType.AVATAR_FRAME);
      }

      userProfileGateway.removeCacheAll(new HashSet<>(membersUserIds));
    });
  }

  /**
   * 发送家族等级荣誉给成员
   *
   * @param familyId 家族ID.
   * @param newLevel 最新家族等级.
   */
  public void sendFamilyProps(Long familyId, FamilyLevelConfig newLevel) {

    if (Objects.isNull(newLevel)) {
      log.info("【家族发送荣誉】sendFamilyProps 没有等级数据familyId:{}", familyId);
      return;
    }

    List<Long> userIdList = getUserIds(familyId);
    if (CollectionUtils.isEmpty(userIdList)) {
      log.info("【家族发送荣誉】sendFamilyProps 家族没有成员familyId:{}", familyId);
      return;
    }

    List<List<Long>> memberUserIdBatch = Lists.partition(userIdList, 200);

    log.info("【家族发送荣誉】sendFamilyProps 家族familyId:{}, 头饰框ID:{}, 徽章ID:{}", familyId,
        newLevel.getAvatarFrameId(), newLevel.getBadgeId());
    int batch = 0;
    for (List<Long> membersUserIds : memberUserIdBatch) {
      batch += 1;

      if (Objects.nonNull(newLevel.getBadgeId()) && newLevel.getBadgeId() > 0) {

        log.info("【家族发送荣誉】插入徽章ID:{}", newLevel.getBadgeId());

        List<BadgeBackpackDTO> badgeBackpacks = membersUserIds.stream()
            .map(membersUserId -> new BadgeBackpackDTO()
                .setId(IdWorkerUtils.getId())
                .setUserId(membersUserId)
                .setBadgeId(newLevel.getBadgeId())
                // 都不佩戴
                .setUseProps(Boolean.FALSE)
                .setExpireTime(TimestampUtils.nowPlusYear(3))
                .setExpireType(BadgeBackpackExpireType.PERMANENT.name())
                .setCreateTime(TimestampUtils.now())
                .setUpdateTime(TimestampUtils.now())
            ).collect(Collectors.toList());

        badgeBackpackService.saveBatch(badgeInfraConvertor.toListBadgeBackpack(badgeBackpacks));
        log.info("【家族发送荣誉】 家族familyId:{}, 批次:{} , 人数:{}, 徽章背包data:{}",
            familyId, batch, badgeBackpacks.size(), JacksonUtils.toJson(badgeBackpacks));
      }
      if (Objects.nonNull(newLevel.getAvatarFrameId()) && newLevel.getAvatarFrameId() > 0) {

        log.info("【家族发送荣誉】插入头饰框ID:{}", newLevel.getAvatarFrameId());

        List<PropsBackpack> propsBackpacks = membersUserIds.stream().map(membersUserId -> {
              PropsBackpack props = new PropsBackpack()
                  .setId(IdWorkerUtils.getId())
                  .setUserId(membersUserId)
                  .setType(PropsCommodityType.AVATAR_FRAME.name())
                  .setPropsId(newLevel.getAvatarFrameId())
                  .setUseProps(Boolean.TRUE)
                  // true 为不允许赠送
                  .setAllowGive(Boolean.TRUE)
                  .setExpireTime(TimestampUtils.nowPlusYear(3));
              props.setCreateTime(TimestampUtils.now());
              props.setUpdateTime(TimestampUtils.now());
              userProfileGateway.removeUseProps(membersUserId, PropsCommodityType.AVATAR_FRAME.name());
              userProfileGateway.switchUseProps(membersUserId, newLevel.getAvatarFrameId());
              return props;
            }
        ).collect(Collectors.toList());

        try {
          propsBackpackService.saveBatch(propsBackpacks);
        } catch (DuplicateKeyException ex) {
          // ignore
        }
        log.info("【家族发送荣誉】 家族familyId:{}, 批次:{} , 人数:{}, 头饰框背包data:{}",
            familyId, batch, propsBackpacks.size(), JacksonUtils.toJson(propsBackpacks));
      }
      userProfileGateway.removeCacheAll(new HashSet<>(membersUserIds));
    }
  }

  private List<Long> getUserIds(Long familyId) {

    Set<Long> userIds = Optional.ofNullable(familyMemberInfoService.listByFamilyId(familyId))
        .map(users -> users.stream().map(FamilyMemberInfo::getMemberUserId)
            .collect(Collectors.toSet())).orElse(Set.of());

    if (CollectionUtils.isEmpty(userIds)) {
      return List.of();
    }

    return Lists.newArrayList(userIds);
  }



  /**
   * 累加经验值(家族成员总榜、家族周榜、家族成员周经验值)
   *
   * @param member 成员
   * @param exp    经验值
   */
  private void expAccumulate(FamilyMemberInfo member, Long exp, String regionId) {
    familyMemberTotalExpService.incrMemberTotalExp(member.getSysOrigin(), member.getFamilyId(), member.getMemberUserId(), exp);
    familyWeekExpService.incrThisWeekExp(member.getSysOrigin(), member.getFamilyId(), regionId, exp);
    familyMemberWeekExpService.incrExp(member.getSysOrigin(), member.getFamilyId(), member.getMemberUserId(), exp);
  }

  /**
   * 组装完整的等级信息
   *
   * @param levelConfig 等级信息
   * @param familyCO    容器
   */
  private void fillFamilyDetails(FamilyLevelConfig levelConfig, FamilyDetailsDTO familyCO) {

    /*PropsSourceRecord avatarFrame = getPropsSourceById(levelConfig.getAvatarFrameId());
    BadgePictureConfig badge = getByBadgeId(levelConfig.getSysOrigin(),
        levelConfig.getBadgeId());
    GiftConfig gift = getEffectiveById(levelConfig);

    if (Objects.nonNull(avatarFrame)) {
      familyCO.setAvatarFrameId(levelConfig.getAvatarFrameId());
      familyCO.setAvatarFrameCover(avatarFrame.getCover());
      familyCO.setAvatarFrameSvg(avatarFrame.getSourceUrl());
    }

    if (Objects.nonNull(badge)) {
      familyCO.setBadgeId(levelConfig.getBadgeId());
      familyCO.setBadgeCover(badge.getSelectUrl());
      familyCO.setBadgeSvg(badge.getAnimationUrl());
    }

    if (Objects.nonNull(gift)) {
      familyCO.setGiftId(gift.getId());
      familyCO.setGiftCover(gift.getGiftPhoto());
      familyCO.setGiftSvg(gift.getGiftSourceUrl());
    }*/

    familyCO.setLevelSort(levelConfig.getSort());
    familyCO.setFamilyLevelId(levelConfig.getId());
    familyCO.setLevel(Integer.parseInt(levelConfig.getLevelKey().substring(6)));
    familyCO.setLevelExp(Long.valueOf(levelConfig.getLevelExp()));
    familyCO.setMaxMember(levelConfig.getMaxMember());
    familyCO.setMaxManager(levelConfig.getMaxManager());
    familyCO.setLevelBackgroundPicture(levelConfig.getLevelBackgroundPicture());
  }

  /**
   * 发送家族等级荣誉给成员
   *
   * @param userId        用户ID
   * @param avatarFrameId 头像框
   * @param badgeId       徽章
   */
  public void sendFamilyHonorToMember(Long userId, Long avatarFrameId, Long badgeId) {

    deleteFamilyAwardByUserId(userId);

    if (Objects.nonNull(avatarFrameId) && avatarFrameId > 0) {
      userProfileGateway.removeUseProps(userId, PropsCommodityType.AVATAR_FRAME.name());
      PropsBackpack propsBackpack = new PropsBackpack()
          .setUserId(userId)
          .setType(PropsCommodityType.AVATAR_FRAME.name())
          .setPropsId(avatarFrameId)
          .setUseProps(Boolean.TRUE)
          // true 为不允许赠送
          .setAllowGive(Boolean.TRUE)
          .setExpireTime(TimestampUtils.nowPlusYear(3));
      propsBackpack.setCreateTime(TimestampUtils.now());
      propsBackpack.setUpdateTime(TimestampUtils.now());
      propsBackpackService.save(propsBackpack);
      userProfileGateway.switchUseProps(userId, avatarFrameId);
    }

    if (Objects.nonNull(badgeId) && badgeId > 0) {
      BadgeBackpack badgeBackpack = new BadgeBackpack()
          .setUserId(userId)
          .setUseProps(Boolean.TRUE)
          .setBadgeId(badgeId)
          .setExpireTime(TimestampUtils.nowPlusYear(3))
          .setExpireType(BadgeBackpackExpireType.PERMANENT.name());
      badgeBackpack.setCreateTime(TimestampUtils.now());
      badgeBackpack.setUpdateTime(TimestampUtils.now());
      badgeBackpackService.save(badgeBackpack);
    }

    userProfileGateway.removeCacheAll(userId);
  }


  /**
   * 更新redis当前家族最新的等级详细信息
   *
   * @param key         redis key
   * @param levelConfig 等级信息
   * @param familyId    家族ID
   */
  public void cacheFamilyLevel(String key, FamilyLevelConfig levelConfig, Long familyId) {

    FamilyDetailsDTO levelCacheCO = new FamilyDetailsDTO()
        .setFamilyId(familyId);

    fillFamilyDetails(levelConfig, levelCacheCO);
  }

  /**
   * 获得家族缓存信息（等级，基本资料，配置）.
   *
   * @param sysOrigin 系统平台
   * @param familyId  家族ID
   * @return 等级信息
   */
  public FamilyDetailsDTO getFamilyDetails(String sysOrigin, Long familyId) {
    FamilyDetailsDTO familyDetailsDTO = familyLevelCacheService
        .getFamilyLevelData(sysOrigin + familyId, FamilyDetailsDTO.class);

    if (Objects.isNull(familyDetailsDTO)) {

      FamilyBaseInfo familyBaseInfo = getFamilyBaseInfo(familyId);
      ResponseAssert.notNull(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA, familyBaseInfo);

      familyDetailsDTO = new FamilyDetailsDTO()
          .setFamilyId(familyId)
          .setFamilyName(familyBaseInfo.getFamilyName())
          .setFamilyAccount(familyBaseInfo.getFamilyAccount())
          .setFamilyAvatar(familyBaseInfo.getFamilyAvatar())
          .setFamilyNotice(familyBaseInfo.getFamilyNotice());
      fillFamilyDetails(getFamilyLevelConfig(familyBaseInfo.getFamilyLevelId()), familyDetailsDTO);
    }
    return familyDetailsDTO;
  }

  private FamilyLevelConfig getFamilyLevelConfig(Long familyLevelId) {
    return familyLevelConfigService.getFamilyLevelConfig(familyLevelId);
  }

  /**
   * 移除家族用户
   *
   * @param member 被移除的成员
   */
  public void removeFamilyUser(FamilyMemberInfo member) {

    familyMemberInfoService.deleteByUserId(member.getMemberUserId());

    familyMemberWeekExpService.deleteBySysOriginMemberId(member.getMemberUserId(), member.getSysOrigin());

    familyMemberTotalExpService.deleteByMemberId(member.getFamilyId(), member.getMemberUserId());

    redisService.setString(FamilyKeys.USER_LEAVE.getKey(member.getMemberUserId()), member.getMemberUserId(), 1, TimeUnit.DAYS);
//    deleteFamilyAwardByUserId(member.getMemberUserId());
//    userProfileGateway.removeUseProps(member.getMemberUserId(),PropsCommodityType.AVATAR_FRAME.name());

//    userProfileGateway.removeCacheAll(member.getMemberUserId());

//    removeGroup(member.getFamilyId(), member.getMemberUserId());
  }

  /**
   * 家族是否存在
   *
   * @param familyId 家族ID
   * @return 是否存在家族 true存在
   */
  public Boolean isExistFamilyById(Long familyId) {

    FamilyBaseInfo familyBaseInfo = getFamilyBaseInfo(familyId);

    if (Objects.isNull(familyBaseInfo)) {
      return Boolean.FALSE;
    }

    return Objects.equals(FamilyStatusEnum.NORMAL.name(), familyBaseInfo.getFamilyStatus());

  }

  /**
   * 家族是否存在
   *
   * @param userId 成员UserID
   * @return 是否存在家族 true存在
   */
  public boolean isExistFamilyByUserId(Long userId) {

    FamilyMemberInfo familyMemberInfo = familyMemberInfoService.getFamilyMemberByUserId(userId);

    if (Objects.isNull(familyMemberInfo)) {
      return Boolean.FALSE;
    }

    FamilyBaseInfo familyBaseInfo = getFamilyBaseInfo(familyMemberInfo.getFamilyId());

    if (Objects.isNull(familyBaseInfo)) {
      return Boolean.FALSE;
    }

    return Objects.equals(FamilyStatusEnum.NORMAL.name(), familyBaseInfo.getFamilyStatus());
  }

  private FamilyBaseInfo getFamilyBaseInfo(Long familyId) {
    return familyBaseInfoService.getBaseInfoById(familyId);
  }

  /**
   * 是否为族长
   *
   * @param memberRole 成员权限
   * @return true 拥有权限
   */
  public boolean isAdmin(String memberRole) {
    return Objects.equals(memberRole, FamilyRoleEnum.ADMIN.name());
  }

  /**
   * 是否为管理员
   *
   * @param memberRole 成员权限
   * @return true 拥有权限
   */
  public boolean isManage(String memberRole) {
    return Objects.equals(memberRole, FamilyRoleEnum.MANAGE.name());
  }

  /**
   * 是否为成员
   *
   * @param memberRole 成员权限
   * @return true 拥有权限
   */
  public boolean isMember(String memberRole) {
    return Objects.equals(memberRole, FamilyRoleEnum.MEMBER.name());
  }





  private PropsSourceRecord getPropsSourceById(Long id) {
    if (Objects.isNull(id)) {
      return null;
    }
    return propsSourceRecordService.getById(id);
  }



  private BadgePictureConfig getByBadgeId(String sysOrigin, Long badgeId) {
    if (Objects.isNull(badgeId) || StringUtils.isBlank(sysOrigin)) {
      return null;
    }
    return badgePictureConfigService.getByBadgeId(sysOrigin, badgeId);
  }


  private FamilyMemberInfo getFamilyMember(Long userId) {
    return familyMemberInfoService.getFamilyMemberByUserId(userId);
  }

  private FamilyLevelConfig getNewLevel(String sysOrigin, FamilyDetailsDTO levelCO) {

    return familyLevelConfigService
        .getNextLevel(sysOrigin, levelCO.getLevelSort());
  }

  private GiftConfig getEffectiveById(FamilyLevelConfig levelConfig) {
    return giftConfigService.getById(levelConfig.getGiftId());
  }

  private void familyLevelUp(FamilyMemberInfo member, FamilyLevelConfig newLevel) {

    familyBaseInfoService.updateSelectiveById(new FamilyBaseInfo()
        .setId(member.getFamilyId())
        .setFamilyLevelId(newLevel.getId())
    );
  }

  public void deleteFamilyAwardByUserId(Long userId) {

    List<FamilyLevelConfig> levelConfigs = getFamilyLevelConfigs();
    if (CollectionUtils.isEmpty(levelConfigs)) {
      return;
    }
    Set<Long> badgeIds = getBadgeIds(levelConfigs);

    Set<Long> avatarFrameIds = getAvatarFrameIds(levelConfigs);

    propsBackpackService.deleteProps(Sets.newHashSet(userId), avatarFrameIds,
        PropsCommodityType.AVATAR_FRAME);
    badgeBackpackService.deleteBadge(Sets.newHashSet(userId), badgeIds);
  }

  private Set<Long> getAvatarFrameIds(List<FamilyLevelConfig> levelConfigs) {

    Set<Long> ids = levelConfigs.stream().map(FamilyLevelConfig::getAvatarFrameId)
        .filter(Objects::nonNull).collect(Collectors.toSet());

    return CollectionUtils.isEmpty(ids) ? Sets.newHashSet() : ids;
  }

  private Set<Long> getBadgeIds(List<FamilyLevelConfig> levelConfigs) {

    Set<Long> ids = levelConfigs.stream().map(FamilyLevelConfig::getBadgeId)
        .filter(Objects::nonNull).collect(Collectors.toSet());

    return CollectionUtils.isEmpty(ids) ? Sets.newHashSet() : ids;
  }

  private List<FamilyLevelConfig> getFamilyLevelConfigs() {

    return familyLevelConfigService.listLevelConfig();
  }

}
