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

import com.google.common.collect.Lists;
import com.red.circle.other.infra.database.mongo.entity.activity.ActivityRewardReceiveMark;
import com.red.circle.other.infra.database.mongo.service.activity.ActivityRewardReceiveMarkService;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Sort;
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.stereotype.Service;

/**
 * 活动奖励领取标记.
 *
 * @author pengshigang on 2023/2/14
 */
@Service
@RequiredArgsConstructor
public class ActivityRewardReceiveMarkServiceImpl implements
    ActivityRewardReceiveMarkService {

  private final MongoTemplate mongoTemplate;

  @Override
  public void add(Long businessId, String activityType, Integer dateNumber, Long rewardId,
      Long userId) {

    if (mongoTemplate.exists(Query.query(Criteria.where("businessId").is(businessId)
            .and("activityType").is(activityType)
            .and("dateNumber").is(dateNumber)
            .and("rewardId").is(rewardId))
        , ActivityRewardReceiveMark.class)) {
      return;
    }

    mongoTemplate.save(new ActivityRewardReceiveMark()
        .setId(IdWorkerUtils.getId())
        .setActivityType(activityType)
        .setBusinessId(businessId)
        .setDateNumber(dateNumber)
        .setRewardId(rewardId)
        .setUserId(userId)
        .setDateNumber(dateNumber)
        .setCreateTime(TimestampUtils.now())
    );

  }

  @Override
  public boolean exist(Long businessId, String activityType, Integer dateNumber, Long rewardId) {

    Criteria criteria = new Criteria();
    if (Objects.nonNull(businessId)) {
      criteria.and("businessId").is(businessId);
    }

    if (StringUtils.isNotBlank(activityType)) {
      criteria.and("activityType").is(activityType);
    }

    if (Objects.nonNull(dateNumber)) {
      criteria.and("dateNumber").is(dateNumber);
    }

    if (Objects.nonNull(rewardId)) {
      criteria.and("rewardId").is(rewardId);
    }

    return mongoTemplate.exists(Query.query(criteria), ActivityRewardReceiveMark.class);
  }

  @Override
  public List<Long> getRewardIdsByCondition(Long businessId, String activityType,
      Integer dateNumber) {

    Criteria criteria = new Criteria();
    if (Objects.nonNull(businessId)) {
      criteria.and("businessId").is(businessId);
    }

    if (StringUtils.isNotBlank(activityType)) {
      criteria.and("activityType").is(activityType);
    }

    if (Objects.nonNull(dateNumber)) {
      criteria.and("dateNumber").is(dateNumber);
    }
    List<ActivityRewardReceiveMark> marks = mongoTemplate
        .find(Query.query(criteria)
            .with(Sort.by(Sort.Order.desc("createTime")))
            .limit(200), ActivityRewardReceiveMark.class);

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

    return marks.stream().map(ActivityRewardReceiveMark::getRewardId).collect(Collectors.toList());
  }
}
