package com.red.circle.console.app.service.app.sys;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.red.circle.common.business.core.ImageSizeConst;
import com.red.circle.console.app.convertor.sys.GiftAppConvertor;
import com.red.circle.console.app.dto.clienobject.sys.SysGiftConfigCO;
import com.red.circle.console.app.dto.cmd.app.sys.GiftConsoleQryCmd;
import com.red.circle.console.app.dto.cmd.app.sys.GiftRegionAddCmd;
import com.red.circle.console.infra.enums.sys.SysGiftTypeEnum;
import com.red.circle.console.inner.error.ConsoleErrorCode;
import com.red.circle.external.inner.endpoint.oss.OssServiceClient;
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.inner.asserts.GiftErrorCode;
import com.red.circle.other.inner.endpoint.material.gift.GiftConfigClient;
import com.red.circle.other.inner.endpoint.user.user.UserProfileClient;
import com.red.circle.other.inner.enums.material.GiftTabEnum;
import com.red.circle.other.inner.model.dto.material.GiftConfigDTO;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.other.inner.endpoint.user.region.RegionConfigClient;
import java.sql.Timestamp;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

/**
 * 系统礼物配置
 *
 * @author zongpubin on 2023/10/12
 */
@Service
@RequiredArgsConstructor
public class SysGiftConfigServiceImpl implements SysGiftConfigService {

  private final OssServiceClient ossServiceClient;
  private final GiftAppConvertor giftAppConvertor;
  private final GiftConfigClient giftConfigClient;
  private final UserProfileClient userProfileClient;
  private final RegionConfigClient regionConfigClient;

  @Override
  public List<SysGiftConfigCO> listBySysOrigin(String sysOrigin) {
    List<GiftConfigDTO> giftConfig = ResponseAssert.requiredSuccess(
        giftConfigClient.listBySysOrigin(sysOrigin));

    if (CollectionUtils.isEmpty(giftConfig)) {
      return Lists.newArrayList();
    }

    Map<String, String> mapRegion = ResponseAssert.requiredSuccess(
        regionConfigClient.mapRegionNameBySysOrigin(sysOrigin));
    return giftConfig.stream().map(getGiftConfigVOFunction(mapRegion, Maps.newHashMap()))
        .collect(Collectors.toList());
  }

  @Override
  public PageResult<SysGiftConfigCO> pageGiftInfo(GiftConsoleQryCmd query) {

    PageResult<GiftConfigDTO> giftConfig = giftConfigClient.pageGiftInfo(
        giftAppConvertor.toGiftQryCmd(query)).getBody();
    if (giftConfig.checkRecordsEmpty()) {
      return giftConfig.emptyRecords();
    }

    Map<String, String> mapRegion = regionConfigClient.mapRegionNameBySysOrigin(
        query.getSysOrigin()).getBody();

    Set<Long> userIds = giftConfig.getRecords().stream()
        .map(customGift -> customGift.getUserId()).filter(Objects::nonNull).collect(
            Collectors.toSet());
    Map<Long, UserProfileDTO> userMap = userProfileClient.mapByUserIds(userIds).getBody();

    return giftConfig.convert(getGiftConfigVOFunction(mapRegion,userMap));
  }

  @Override
  public void updateGift(SysGiftConfigCO param) {
    ResponseAssert.notNull(GiftErrorCode.BAD_REQUEST, param.getId());
    GiftConfigDTO orlGiftConfig = ResponseAssert.requiredSuccess(
        giftConfigClient.getById(param.getId()));
    ResponseAssert.notNull(GiftErrorCode.GIFT_NOT_FOUND, orlGiftConfig);
    GiftConfigDTO newGiftConfig = getGiftConfig(param);
    if (StringUtils.isNotBlank(param.getAccount())){
      UserProfileDTO userProfile = userProfileClient.getByAccount(param.getSysOrigin(),
              param.getAccount()).getBody();
      if (Objects.nonNull(userProfile)) {
        newGiftConfig.setUserId(userProfile.getId());
      }
    }
    ResponseAssert.isTrue(CommonErrorCode.UPDATE_FAILURE,
        ResponseAssert.requiredSuccess(giftConfigClient.updateGift(newGiftConfig)));
    giftConfigClient.removeGiftCache();

    removeRemainingInventory(orlGiftConfig, newGiftConfig);
  }

  @Override
  public void addGift(SysGiftConfigCO param) {
    GiftConfigDTO giftConfig = getGiftConfig(param);
    if (GiftTabEnum.EXCLUSIVE.equals(param.getGiftTab())) {
      UserProfileDTO userProfile = userProfileClient.getByAccount(param.getSysOrigin(),
          param.getAccount()).getBody();
      if (Objects.nonNull(userProfile)){
        giftConfig.setUserId(userProfile.getId());
      }
    }
    ResponseAssert.isTrue(CommonErrorCode.SAVE_FAILURE,
        ResponseAssert.requiredSuccess(giftConfigClient.saveGift(giftConfig)));
    giftConfigClient.removeGiftCache();
  }

  @Override
  public void switchDelStatus(Long id, Boolean status) {
    GiftConfigDTO giftConfig = ResponseAssert.requiredSuccess(
        giftConfigClient.getById(id));
    ResponseAssert.notNull(CommonErrorCode.DELETE_FAILURE, giftConfig);

    ResponseAssert.isTrue(CommonErrorCode.DELETE_FAILURE,
        ResponseAssert.requiredSuccess(giftConfigClient.switchDelStatus(id, status)));

    giftConfigClient.removeGiftCache();
    if (Objects.nonNull(giftConfig.getStandardId())) {
      giftConfigClient.removeRemainingInventory(id, giftConfig.getStandardId());
    }
  }

  @Override
  public List<GiftConfigDTO> listByTab(String sysOrigin, String giftTab) {
    return ResponseAssert.requiredSuccess(giftConfigClient.listByTab(sysOrigin, giftTab));
  }

  @Override
  public String getPairCpGiveGiftId(String sysOrigin) {
    return ResponseAssert.requiredSuccess(
        giftConfigClient.getPairCpGiveGiftId(sysOrigin));
  }

  @Override
  public void pushPairCpGiveGiftId(Long giftId, String sysOrigin) {
    GiftConfigDTO giftConfig = ResponseAssert.requiredSuccess(
        giftConfigClient.getById(giftId));
    ResponseAssert.notNull(ConsoleErrorCode.NOT_FOUND_RECORD, giftConfig);
    ResponseAssert.isTrue(ConsoleErrorCode.SUPPORT_ASWAT_ERROR,
        Objects.equals(giftConfig.getSysOrigin(), sysOrigin));
    giftConfigClient
        .pushPairCpGiveGiftId(giftConfig.getSysOrigin(), giftId);
  }

  @Override
  public List<GiftConfigDTO> listByTabV2(GiftConsoleQryCmd query) {
    return ResponseAssert.requiredSuccess(
        giftConfigClient.listByTabV2(giftAppConvertor.toGiftQryCmd(query)));
  }

  @Override
  public void addAllGiftRegion(GiftRegionAddCmd param) {
    ResponseAssert.notNull(GiftErrorCode.BAD_REQUEST, param);
    ResponseAssert.isTrue(GiftErrorCode.BAD_REQUEST, StringUtils.isNotBlank(param.getSysOrigin()));
    ResponseAssert.isTrue(GiftErrorCode.BAD_REQUEST, StringUtils.isNotBlank(param.getRegionId()));

    Map<String, String> mapRegion = ResponseAssert.requiredSuccess(
        regionConfigClient.mapRegionNameBySysOrigin(param.getSysOrigin()));
    ResponseAssert.isTrue(GiftErrorCode.BAD_REQUEST, mapRegion.containsKey(param.getRegionId()));

    ResponseAssert.isTrue(CommonErrorCode.UPDATE_FAILURE,
        ResponseAssert.requiredSuccess(giftConfigClient.addAllGiftRegion(
            param.getSysOrigin(), param.getRegionId())));
    giftConfigClient.removeGiftCache();
  }

  @Override
  public List<SysGiftConfigCO> listByExpiredTime(Timestamp now) {
    return giftAppConvertor.toSysGiftConfigCOList(ResponseAssert.requiredSuccess(giftConfigClient.listByExpiredTime(now)));
  }

  private Function<GiftConfigDTO, SysGiftConfigCO> getGiftConfigVOFunction(
      Map<String, String> mapRegion, Map<Long, UserProfileDTO> userMap) {

    return giftConfigDTO -> {
      SysGiftConfigCO co = giftAppConvertor.toSysGiftConfigCO(giftConfigDTO);
      co.setTypeName(SysGiftTypeEnum.getDescValue(giftConfigDTO.getType()));
      co.setSpecialList(StringUtils.splitAsList(giftConfigDTO.getSpecial(), ","));
      co.setRegionList(StringUtils.splitAsList(giftConfigDTO.getRegions(), ","));
      co.setUserBaseInfo(userMap.get(co.getUserId()));
      co.setAccount(
          Objects.nonNull(userMap.get(co.getUserId())) ? userMap.get(co.getUserId()).getAccount()
              .toString() : null);

      if (CollectionUtils.isEmpty(co.getRegionList())) {
        return co;
      }
      StringBuilder regionBuilder = new StringBuilder();
      co.getRegionList()
          .forEach(regionId -> regionBuilder.append(",").append(mapRegion.get(regionId)));
      co.setRegionNameStr(regionBuilder.substring(1));
      return co;
    };
  }

  private GiftConfigDTO getGiftConfig(SysGiftConfigCO param) {
    GiftConfigDTO sysGiftConfig = giftAppConvertor.toGiftConfigDTO(param);
    sysGiftConfig.setGiftPhoto(ResponseAssert.requiredSuccess(
        ossServiceClient.processImgSaveAsCompressZoom(param.getGiftPhoto(),
            ImageSizeConst.COVER_HEIGHT)
    ));
    if (Objects.nonNull(param.getGiftSourceUrl())) {
      sysGiftConfig.setGiftSourceUrl(ResponseAssert.requiredSuccess(
          ossServiceClient.getAccessUrl(param.getGiftSourceUrl())
      ));
    }
    sysGiftConfig.setSpecial(StringUtils.join(param.getSpecialList(), ","));
    sysGiftConfig.setRegions(StringUtils.join(param.getRegionList(), ","));
    return sysGiftConfig;
  }

  private void removeRemainingInventory(GiftConfigDTO orlGiftConfig, GiftConfigDTO newGiftConfig) {

    // 以前不是幸运礼物,现在也不是
    if (!Objects.equals(orlGiftConfig.getGiftTab(), GiftTabEnum.LUCKY_GIFT.name()) &&
        !Objects.equals(newGiftConfig.getGiftTab(), GiftTabEnum.LUCKY_GIFT.name())) {
      return;
    }

    // 以前不是幸运礼物,现在是
    if (!Objects.equals(orlGiftConfig.getGiftTab(), GiftTabEnum.LUCKY_GIFT.name()) &&
        Objects.equals(newGiftConfig.getGiftTab(), GiftTabEnum.LUCKY_GIFT.name())) {
      return;
    }

    // 以前是幸运礼物,现在不是
    if (Objects.equals(orlGiftConfig.getGiftTab(), GiftTabEnum.LUCKY_GIFT.name()) &&
        !Objects.equals(newGiftConfig.getGiftTab(), GiftTabEnum.LUCKY_GIFT.name())) {
      giftConfigClient.removeRemainingInventory(orlGiftConfig.getId(),
          orlGiftConfig.getStandardId());
      return;
    }

    // 以前是幸运礼物, 现在也是
    if (Objects.equals(orlGiftConfig.getStandardId(), newGiftConfig.getStandardId())) {
      return;
    }

    // 切换了幸运礼物规格则移除剩余签库存
    giftConfigClient.removeRemainingInventory(orlGiftConfig.getId(),
        orlGiftConfig.getStandardId());

  }
}
