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

import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient;
import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExtTemplateTypeCmd;
import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.framework.core.response.ResponseErrorCode;
import com.red.circle.other.app.dto.cmd.material.PropsGiveAwayCmd;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.UserSVipGateway;
import com.red.circle.other.domain.model.user.UserConsumptionLevel;
import com.red.circle.other.infra.database.rds.entity.props.PropsBackpack;
import com.red.circle.other.infra.database.rds.entity.props.PropsGiveAwayUser;
import com.red.circle.other.infra.database.rds.service.props.PropsBackpackService;
import com.red.circle.other.infra.database.rds.service.props.PropsGiveAwayUserService;
import com.red.circle.other.infra.database.rds.service.props.PropsVipActualEquityService;
import com.red.circle.other.inner.asserts.PropsErrorCode;
import com.red.circle.other.inner.enums.material.PropsCommodityType;
import com.red.circle.tool.core.date.TimestampUtils;
import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;


/**
 * 背包内道具赠送.
 *
 * @author zongpubin on 2023/04/10
 */
@Component
@RequiredArgsConstructor
public class PropsGiveAwayCmdExe {

  private final UserSVipGateway userSVipGateway;
  private final UserProfileGateway userProfileGateway;
  private final PropsBackpackService propsBackpackService;
  private final OfficialNoticeClient officialNoticeClient;
  private final PropsGiveAwayUserService propsGiveAwayUserService;
  private final PropsVipActualEquityService propsVipActualEquityService;

  public void execute(PropsGiveAwayCmd cmd) {

    if (Objects.isNull(cmd.getAcceptUserId())) {
      ResponseAssert.failure(ResponseErrorCode.REQUEST_PARAMETER_ERROR,
          "acceptUserId is not null.");
    }

    giveAway(cmd, getCommodity(cmd.requiredReqUserId(), cmd.getPropsId()));
  }

  private void giveAway(PropsGiveAwayCmd cmd, PropsBackpack propsBackpack) {

    if (PropsCommodityType.NOBLE_VIP.eq(propsBackpack.getType())) {

      ResponseAssert.isTrue(PropsErrorCode.NOBLE_VIP_PROPS_NOT_ENOUGH,
          propsBackpackService.countUserNobleProps(cmd.requiredReqUserId()));

      UserConsumptionLevel userLevel = userProfileGateway.getUserConsumptionLevel(
          cmd.requireReqSysOriginEnum(),
          cmd.requiredReqUserId());

      if (userLevel.getWealthLevel() < 5) {
        ResponseAssert.failure(PropsErrorCode.USER_WEALTH_LEVEL_NOT_ENOUGH);
      }

      propsBackpackService.giveAwayProps(cmd.getAcceptUserId(), cmd.requiredReqUserId(),
          cmd.getPropsId(), propsBackpack.getType());

      propsVipActualEquityService.changeBelongUserId(cmd.getAcceptUserId(),
          cmd.requiredReqUserId(), cmd.getPropsId());

    } else {

      // 不允许赠送svip关联道具
      if (Boolean.TRUE.equals(
          userSVipGateway.existSVipProps(cmd.requireReqSysOrigin(), cmd.getPropsId()))) {
        ResponseAssert.failure(CommonErrorCode.SYSTEM_DOES_NOT_SUPPORT);
        return;
      }

      propsBackpackService.giveAwayProps(cmd.getAcceptUserId(), cmd.requiredReqUserId(),
          cmd.getPropsId(), propsBackpack.getType());
    }

    propsGiveAwayUserService.save(new PropsGiveAwayUser()
        .setAcceptUserId(cmd.getAcceptUserId())
        .setSendUserId(cmd.requiredReqUserId())
        .setPropsId(cmd.getPropsId())
        .setSysOrigin(cmd.requireReqSysOrigin())
        .setExpireTime(propsBackpack.getExpireTime())
    );

    sendGiveAwayNotice(cmd, propsBackpack);
  }


  private void sendGiveAwayNotice(PropsGiveAwayCmd cmd, PropsBackpack propsBackpack) {
    if (cmd.isGiveAway()) {
      return;
    }

    /*officialNoticeClient.send(NoticeExtTemplateTypeCmd.builder()
        .toAccount(cmd.getAcceptUserId())
        .noticeType(OfficialNoticeTypeEnum.GIVE_AWAY_PROPS)
        .templateParam(Map.of("nickname",
            userProfileGateway.getByUserId(cmd.requiredReqUserId())
                .getUserNickname()
            , "effectDuration",
            TimestampUtils.between(TimestampUtils.now(), propsBackpack.getExpireTime()).toDays()))
        .build());*/
  }


  private PropsBackpack getCommodity(Long userId, Long propsId) {
    PropsBackpack props = propsBackpackService.getUserPropsByUserIdByPropsId(
        userId, propsId);
    // 没有找到映射信息
    ResponseAssert.notNull(CommonErrorCode.NOT_FOUND_MAPPING_INFO, props);

    if (PropsCommodityType.THEME.eq(props.getType())) {
      ResponseAssert.failure(PropsErrorCode.USER_KNAPSACK_THEME_NOT_GIVE_AWAY);
    }
    ResponseAssert.isFalse(PropsErrorCode.USER_PROPS_IS_USEING_NOT_GIVE_AWAY, props.getUseProps());

    long days = TimestampUtils.expiredIntervalMillisecond(TimestampUtils.now(),
        props.getExpireTime());
    if (days <= 0L) {
      ResponseAssert.failure(PropsErrorCode.PROPS_OVERDUE_NOT_GIVE_AWAY);
    }
    ResponseAssert.isFalse(PropsErrorCode.USER_PROPS_ONLY_GIVEN_ONCE, props.getAllowGive());
    return props;
  }


}
