package com.red.circle.other.infra.database.mongo.service.activity.impl;

import com.red.circle.other.infra.database.mongo.entity.activity.ActivityAgentAnchorCount;
import com.red.circle.other.infra.database.mongo.service.activity.ActivityAgentAnchorCountService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import lombok.RequiredArgsConstructor;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

/**
 * 代理名下月活跃主播记录.
 *
 * @author pengshigang on 2023/2/14
 */
@Service
@RequiredArgsConstructor
public class ActivityAgentAnchorCountServiceImpl implements ActivityAgentAnchorCountService {

  private final MongoTemplate mongoTemplate;

  @Override
  public void incr(Long quantity, Long businessId, String group, Integer dateNumber) {

    ActivityAgentAnchorCount count = mongoTemplate
        .findOne(Query.query(Criteria.where("businessId").is(businessId)
                .and("group").is(group).and("dateNumber").is(dateNumber)),
            ActivityAgentAnchorCount.class);

    if (Objects.nonNull(count)) {

      mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(count.getId())),
          new Update().inc("quantity", quantity), ActivityAgentAnchorCount.class);
      return;
    }

    mongoTemplate.save(new ActivityAgentAnchorCount()
        .setId(IdWorkerUtils.getIdStr())
        .setQuantity(quantity)
        .setBusinessId(businessId)
        .setGroup(group)
        .setDateNumber(dateNumber)
        .setCreateTime(TimestampUtils.now()));
  }

  @Override
  public Long getCountQuantity(Long businessId, String group, Integer dateNumber) {

    return Optional.ofNullable(mongoTemplate
            .findOne(Query.query(Criteria.where("businessId").is(businessId)
                    .and("group").is(group).and("dateNumber").is(dateNumber)),
                ActivityAgentAnchorCount.class)).map(ActivityAgentAnchorCount::getQuantity)
        .orElse(0L);
  }

  @Override
  public void initZero(Long acceptUserId, Long teamId) {

    // 主播月收礼，永久活动
    Long quantity1 = getCountQuantity(acceptUserId, "ACTIVE_ANCHOR_MONTH_TARGET_REWARD",
        getThisMonthDate());
    if (Objects.nonNull(quantity1) && quantity1 > 0) {
      incr(-quantity1, acceptUserId, "ACTIVE_ANCHOR_MONTH_TARGET_REWARD", getThisMonthDate());

      // 代理名下主播当月总积分, 永久活动
      incr(-quantity1, teamId, "ACTIVE_AGENT_MONTH_TARGET_REWARD", getThisMonthDate());
    }

    // 主播日收礼，永久活动
    Long quantity2 = getCountQuantity(acceptUserId, "ACTIVE_ANCHOR_DAY_TARGET_REWARD",
        getThisDayDate());
    if (Objects.nonNull(quantity2) && quantity2 > 0) {
      incr(-quantity2, acceptUserId, "ACTIVE_ANCHOR_DAY_TARGET_REWARD", getThisDayDate());
    }

  }


  @Override
  public void initZeroTeam(Long teamId) {

    mongoTemplate.updateFirst(Query.query(Criteria.where("businessId").is(teamId)
            .and("group").is("ACTIVE_AGENT_MONTH_TARGET_REWARD")
            .and("dateNumber").is(getThisMonthDate())),
        new Update().set("quantity", 0), ActivityAgentAnchorCount.class);
  }


  @Override
  public void initZeroMember(Set<Long> acceptUserIds) {

    if (CollectionUtils.isEmpty(acceptUserIds)) {
      return;
    }

    mongoTemplate.updateFirst(Query.query(Criteria.where("businessId").in(acceptUserIds)
            .and("group").is("ACTIVE_ANCHOR_DAY_TARGET_REWARD")
            .and("dateNumber").is(getThisDayDate())),
        new Update().set("quantity", 0), ActivityAgentAnchorCount.class);

    mongoTemplate.updateFirst(Query.query(Criteria.where("businessId").in(acceptUserIds)
            .and("group").is("ACTIVE_ANCHOR_MONTH_TARGET_REWARD")
            .and("dateNumber").is(getThisMonthDate())),
        new Update().set("quantity", 0), ActivityAgentAnchorCount.class);

  }

  private Integer getThisMonthDate() {
    return ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt();
  }

  private Integer getThisDayDate() {
    return ZonedDateTimeAsiaRiyadhUtils.nowDateToInt();
  }

}
