package com.red.circle.other.app.inner.service.sys.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.material.GiftInnerConvertor;
import com.red.circle.other.app.inner.convertor.sys.SysWeekStarGroupInnerConvertor;
import com.red.circle.other.app.inner.service.sys.SysWeekStarGroupClientService;
import com.red.circle.other.infra.database.cache.service.other.GiftCacheService;
import com.red.circle.other.infra.database.rds.entity.gift.GiftConfig;
import com.red.circle.other.infra.database.rds.entity.sys.WeekStarGift;
import com.red.circle.other.infra.database.rds.entity.sys.WeekStarGroup;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.sys.WeekStarGiftService;
import com.red.circle.other.infra.database.rds.service.sys.WeekStarGroupService;
import com.red.circle.other.inner.model.cmd.sys.SysWeekStarGroupAddParamCmd;
import com.red.circle.other.inner.model.cmd.sys.SysWeekStarGroupQryCmd;
import com.red.circle.other.inner.model.dto.material.GiftConfigDTO;
import com.red.circle.other.inner.model.dto.sys.SysWeekStarGroupDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 周星分组
 *
 * @author zongpubin on 2023/11/3
 */

@Service
@RequiredArgsConstructor
public class SysWeekStarGroupClientServiceImpl implements SysWeekStarGroupClientService {

  private final GiftCacheService giftCacheService;
  private final GiftConfigService giftConfigService;
  private final GiftInnerConvertor giftInnerConvertor;
  private final WeekStarGiftService weekStarGiftService;
  private final WeekStarGroupService weekStarGroupService;
  private final SysWeekStarGroupInnerConvertor weekStarGroupAppConvertor;

  @Override
  public PageResult<SysWeekStarGroupDTO> getPage(SysWeekStarGroupQryCmd query) {

    PageResult<WeekStarGroup> pageResult = weekStarGroupService.getPage(query);

    if (CollectionUtils.isEmpty(pageResult.getRecords())) {
      return pageResult.convert(
          weekStarGroupAppConvertor::toSysWeekStarGroupDTO);
    }

    Map<Long, List<WeekStarGift>> sysWeekStarGiftMap = weekStarGiftService.mapGroupByGroupId(
        getGroupIds(pageResult));

    Map<Long, GiftConfig> sysGiftConfigMap = giftConfigService
        .mapByIds(getGiftIds(sysWeekStarGiftMap));

    return pageResult.convert(sysWeekStarGroup -> {
      SysWeekStarGroupDTO weekStarGroupDTO = weekStarGroupAppConvertor.toSysWeekStarGroupDTO(
          sysWeekStarGroup);
      weekStarGroupDTO.setSysGiftConfigs(
          toSysWeekStarGifts(sysGiftConfigMap, sysWeekStarGiftMap.get(weekStarGroupDTO.getId())));
      return weekStarGroupDTO;
    });
  }

  @Override
  public void addGroup(SysWeekStarGroupAddParamCmd param) {
    weekStarGiftService
        .saveBatch(getSysWeekStarGift(param.getGiftIds(), saveGroup(param.getSysOrigin())));
  }

  @Override
  public void deleteAndAssociateGroup(Long id) {
    weekStarGroupService.deleteById(id);
    weekStarGiftService.deleteByGroupId(id);
    giftCacheService.remove();

  }


  private WeekStarGroup saveGroup(String sysOrigin) {
    WeekStarGroup sysWeekStarGroup = new WeekStarGroup()
        .setSysOrigin(sysOrigin)
        .setDisplayNumber(0);
    weekStarGroupService.save(sysWeekStarGroup);
    ResponseAssert.notNull(CommonErrorCode.SAVE_FAILURE, sysWeekStarGroup.getId());
    return sysWeekStarGroup;
  }

  private List<WeekStarGift> getSysWeekStarGift(List<Long> giftIds,
      WeekStarGroup sysWeekStarGroup) {
    return giftIds.stream().map(giftId -> {
      WeekStarGift sysWeekStarGift = new WeekStarGift()
          .setGiftId(giftId)
          .setGroupId(sysWeekStarGroup.getId());
      sysWeekStarGift.setCreateTime(TimestampUtils.now());
      sysWeekStarGift.setUpdateTime(TimestampUtils.now());
      return sysWeekStarGift;
    }).collect(Collectors.toList());
  }

  private Set<Long> getGiftIds(Map<Long, List<WeekStarGift>> sysWeekStarGiftMap) {
    return sysWeekStarGiftMap.values().stream().flatMap(Collection::stream)
        .map(WeekStarGift::getGiftId).collect(Collectors.toSet());
  }

  private List<Long> getGroupIds(PageResult<WeekStarGroup> sysWeekStarGroupPage) {
    return sysWeekStarGroupPage.getRecords().stream().map(WeekStarGroup::getId).collect(
        Collectors.toList());
  }

  private List<GiftConfigDTO> toSysWeekStarGifts(Map<Long, GiftConfig> sysGiftConfigMap,
      List<WeekStarGift> sysWeekStarGifts) {
    return sysWeekStarGifts.stream().map(sysWeekStarGift -> {
      GiftConfig sysGiftConfig = sysGiftConfigMap.get(sysWeekStarGift.getGiftId());
      return giftInnerConvertor.toGiftConfigDTO(sysGiftConfig);
    }).sorted(Comparator.comparing(GiftConfigDTO::getGiftCandy)).collect(Collectors.toList());
  }

}
