package com.red.circle.other.app.inner.service.family.impl;

import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.app.inner.convertor.FamilyInnerConvertor;
import com.red.circle.other.app.inner.service.family.FamilyMemberInfoClientService;
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.service.badge.BadgeBackpackService;
import com.red.circle.other.infra.database.rds.service.family.FamilyLevelConfigService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberWeekAwardRecordService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberWeekExpService;
import com.red.circle.other.infra.database.rds.service.family.FamilyMessageService;
import com.red.circle.other.infra.database.rds.service.props.PropsBackpackService;
import com.red.circle.other.infra.enums.family.FamilyRoleEnum;
import com.red.circle.other.inner.asserts.FamilyErrorCode;
import com.red.circle.other.inner.model.cmd.famliy.FamilyMemberQryCmd;
import com.red.circle.other.inner.model.dto.famliy.FamilyMemberDTO;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 家族成员 服务实现类.
 * </p>
 *
 * @author pengshigang
 * @since 2021-07-21
 */
@Service
@RequiredArgsConstructor
public class FamilyMemberInfoClientServiceImpl implements
    FamilyMemberInfoClientService {

  private final FamilyInnerConvertor familyInnerConvertor;
  private final BadgeBackpackService badgeBackpackService;
  private final FamilyMessageService familyMessageService;
  private final PropsBackpackService propsBackpackService;
  private final FamilyMemberInfoService familyMemberInfoService;
  private final FamilyLevelConfigService familyLevelConfigService;
  private final FamilyMemberWeekExpService familyMemberWeekExpService;
  private final FamilyMemberWeekAwardRecordService familyMemberWeekAwardRecordService;


  @Override
  public PageResult<FamilyMemberDTO> pageData(FamilyMemberQryCmd queryWhere) {
    return familyMemberInfoService.pageData(queryWhere)
        .convert(familyInnerConvertor::toFamilyMemberDTO);
  }

  @Override
  public void delMember(Long familyId, Long memberId) {
    ResponseAssert.isFalse(CommonErrorCode.DATA_ERROR, checkParams(familyId, memberId));

    FamilyMemberInfo familyMember = familyMemberInfoService.getFamilyMember(familyId, memberId);

    ResponseAssert.notNull(CommonErrorCode.DATA_ERROR, Objects.isNull(familyMember));

    ResponseAssert.isFalse(FamilyErrorCode.ADMIN_DEL_ERROR, isAdmin(familyMember));

    delMember(familyId, familyMember, getLevelConfigs(familyMember));


  }

  private boolean isAdmin(FamilyMemberInfo familyMember) {
    return Objects.equals(familyMember.getMemberRole(), FamilyRoleEnum.ADMIN.getKey());
  }

  private void delMember(Long familyId, FamilyMemberInfo familyMember,
      List<FamilyLevelConfig> levelConfigs) {

    familyMemberInfoService.deleteMemberById(familyMember);

    familyMemberWeekExpService.deleteByFamilyIdByMemberId(familyId, familyMember.getId());

    familyMessageService.deleteByFamilyIdByUserId(familyId, familyMember.getMemberUserId());

    familyMemberWeekAwardRecordService.deleteByFamilyIdByMemberId(familyId, familyMember.getId());

    propsBackpackService.deleteProps(familyMember.getMemberUserId(), getPropsIds(levelConfigs));

    badgeBackpackService.deleteBadges(familyMember.getMemberUserId(), getBadgeIds(levelConfigs));
  }


  private List<FamilyLevelConfig> getLevelConfigs(FamilyMemberInfo familyMember) {
    return familyLevelConfigService.listLevelBySysOrigin(familyMember.getSysOrigin());
  }

  private boolean checkParams(Long familyId, Long memberId) {
    return Objects.isNull(familyId) || Objects.isNull(memberId);
  }

  private Set<Long> getBadgeIds(List<FamilyLevelConfig> levelConfigs) {
    return levelConfigs.stream().map(FamilyLevelConfig::getBadgeId).collect(
        Collectors.toSet());
  }

  private Set<Long> getPropsIds(List<FamilyLevelConfig> levelConfigs) {
    return levelConfigs.stream().map(FamilyLevelConfig::getAvatarFrameId).collect(
        Collectors.toSet());
  }
}
