package com.red.circle.other.app.command.room.query;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.red.circle.common.business.core.enums.ApprovalStatusEnum;
import com.red.circle.framework.core.dto.CommonCommand;
import com.red.circle.other.app.dto.clientobject.room.RoomThemeCO;
import com.red.circle.other.infra.database.rds.entity.props.PropsSourceRecord;
import com.red.circle.other.infra.database.rds.entity.props.RoomThemeUserBackpack;
import com.red.circle.other.infra.database.rds.entity.props.RoomThemeUserCustomize;
import com.red.circle.other.infra.database.rds.service.props.PropsSourceRecordService;
import com.red.circle.other.infra.database.rds.service.props.RoomThemeUserBackpackService;
import com.red.circle.other.infra.database.rds.service.props.RoomThemeUserCustomizeService;
import com.red.circle.tool.core.collection.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 获取用户房间主题-背包
 *
 * @author houyong on 2020/12/9
 */
@Component
@RequiredArgsConstructor
public class RoomThemeUserBackpackListQryExe {

  private final PropsSourceRecordService propsSourceRecordService;
  private final RoomThemeUserBackpackService roomThemeUserBackpackService;
  private final RoomThemeUserCustomizeService roomThemeUserCustomizeService;

  public List<RoomThemeCO> execute(CommonCommand cmd) {
    List<RoomThemeUserBackpack> roomThemeUserBackpacks = getRoomThemeUserBackpacks(cmd);
    if (CollectionUtils.isEmpty(roomThemeUserBackpacks)) {
      return Lists.newArrayList();
    }

    Map<Long, PropsSourceRecord> mapPopsThemeStore = mapPropsTheme(roomThemeUserBackpacks);

    Map<Long, RoomThemeUserCustomize> customizeThemeMap = mapCustomizeTheme(
        roomThemeUserBackpacks);

    return roomThemeUserBackpacks.stream().map(theme -> {
      if (Objects.equals(theme.getThemeType(), 0)) {
        PropsSourceRecord propsThemeStore = mapPopsThemeStore.get(theme.getThemeId());
        if (Objects.isNull(propsThemeStore)) {
          return null;
        }
        return new RoomThemeCO()
            .setId(propsThemeStore.getId())
            .setThemeBack(propsThemeStore.getCover())
            .setThemeStatus(ApprovalStatusEnum.PASS.name())
            .setUseTheme(theme.getUseTheme())
            .setExpireTime(theme.getExpireTime());
      }
      if (Objects.equals(theme.getThemeType(), 1)) {
        RoomThemeUserCustomize customizeTheme = customizeThemeMap.get(theme.getThemeId());
        if (Objects.isNull(customizeTheme)) {
          return null;
        }
        return new RoomThemeCO()
            .setId(customizeTheme.getId())
            .setThemeBack(customizeTheme.getThemeBack())
            .setThemeStatus(customizeTheme.getThemeStatus())
            .setExpireTime(theme.getExpireTime())
            .setUseTheme(theme.getUseTheme());
      }
      throw new IllegalArgumentException("get user theme [data] error");
    }).filter(Objects::nonNull).collect(Collectors.toList());
  }

  private Map<Long, PropsSourceRecord> mapPropsTheme(
      List<RoomThemeUserBackpack> roomThemeUserBackpacks) {

    if (CollectionUtils.isEmpty(roomThemeUserBackpacks)) {
      return Maps.newHashMap();
    }

    Set<Long> storeThemeIds = getThemeIds(roomThemeUserBackpacks, 0);

    if (CollectionUtils.isEmpty(storeThemeIds)) {
      return Maps.newHashMap();
    }
    return propsSourceRecordService.mapByIds(storeThemeIds);

  }

  private Map<Long, RoomThemeUserCustomize> mapCustomizeTheme(
      List<RoomThemeUserBackpack> roomThemeUserBackpacks) {

    if (CollectionUtils.isEmpty(roomThemeUserBackpacks)) {
      return Maps.newHashMap();
    }

    return roomThemeUserCustomizeService
        .mapByIds(getThemeIds(roomThemeUserBackpacks, 1));
  }

  private List<RoomThemeUserBackpack> getRoomThemeUserBackpacks(CommonCommand cmd) {
    return roomThemeUserBackpackService
        .listByUserIdOrderByUseThemeDesc(cmd.requiredReqUserId());
  }

  private Set<Long> getThemeIds(List<RoomThemeUserBackpack> roomThemeUserBackpacks,
      Integer themeType) {
    return Optional.of(roomThemeUserBackpacks.stream()
        .filter(roomThemeUserBackpack -> Objects
            .equals(roomThemeUserBackpack.getThemeType(), themeType))
        .map(RoomThemeUserBackpack::getThemeId)
        .collect(Collectors.toSet())).orElse(CollectionUtils.newHashSet());
  }

}
