package com.red.circle.other.app.command.family;

import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.family.FamilyMemberCO;
import com.red.circle.other.app.dto.cmd.family.FamilyMemberListQueryCmd;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.common.family.FamilyCommon;
import com.red.circle.other.infra.database.rds.dto.family.FamilyMemberExpDTO;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberWeekExpService;
import com.red.circle.other.infra.enums.family.FamilyRoleEnum;
import com.red.circle.other.inner.asserts.FamilyErrorCode;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.num.NumUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * <p>
 * 家族成员.
 * </p>
 *
 * @author pengshigang
 * @since 2021-07-23
 */
@Component
@RequiredArgsConstructor
public class FamilyMemberListExe {

  private final FamilyCommon familyCommon;
  private final UserProfileGateway userProfileGateway;
  private final UserProfileAppConvertor userProfileAppConvertor;
  private final FamilyMemberWeekExpService familyMemberWeekExpService;

  public List<FamilyMemberCO> execute(FamilyMemberListQueryCmd cmd) {

    ResponseAssert.isTrue(FamilyErrorCode.NOT_EXIST_FAMILY_INFO_DATA,
        familyCommon.isExistFamilyById(cmd.getFamilyId()));

    List<FamilyMemberExpDTO> members = pageList(cmd);
    if (CollectionUtils.isEmpty(members)) {
      return CollectionUtils.newArrayList();
    }

    Map<Long, UserProfileDTO> mapUserBase = mapUserProfile(members);
    if (CollectionUtils.isEmpty(mapUserBase)) {
      return CollectionUtils.newArrayList();
    }
    return getMemberCO(members, mapUserBase);
  }

  private List<FamilyMemberCO> getMemberCO(List<FamilyMemberExpDTO> members,
      Map<Long, UserProfileDTO> userProfileMap) {

    return members.stream().map(member -> {
      UserProfileDTO user = userProfileMap.get(member.getMemberUserId());
      return new FamilyMemberCO()
          .setFamilyId(member.getFamilyId())
          .setMemberId(member.getId())
          .setMemberUserId(member.getMemberUserId())
          .setMemberAvatar(user.getUserAvatar())
          .setMemberNickname(user.getUserNickname())
          .setMemberAge(user.getAge())
          .setMemberSex(Objects.equals(user.getUserSex(), 1))
          .setMemberExp(NumUtils.formatBigDecimal(member.getExp()))
          .setMemberRole(member.getMemberRole())
          ;

    }).filter(Objects::nonNull).toList();
  }

  private Map<Long, UserProfileDTO> mapUserProfile(List<FamilyMemberExpDTO> members) {
    return userProfileAppConvertor.toMapUserProfileDTO(userProfileGateway.mapByUserIds(
        members.stream().map(FamilyMemberExpDTO::getMemberUserId).collect(Collectors.toSet())));
  }

  private List<FamilyMemberExpDTO> pageList(FamilyMemberListQueryCmd cmd) {
    return familyMemberWeekExpService
        .pageByFamilyId(cmd.getFamilyId(),
            List.of(FamilyRoleEnum.MANAGE, FamilyRoleEnum.MEMBER), cmd.getPageNo(),
            cmd.getPageSize());
  }


}
