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


import com.red.circle.other.infra.database.mongo.entity.task.DailyTaskStorage;
import com.red.circle.other.infra.database.mongo.service.task.DailyTaskStorageService;
import com.red.circle.other.infra.enums.task.DailyTaskStorageStatus;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
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 pengliang on 2021/5/8
 */
@Service
@RequiredArgsConstructor
public class DailyTaskStorageServiceImpl implements DailyTaskStorageService {

  private final MongoTemplate mongoTemplate;

  @Override
  public void changeStatusCompleted(Long userId, String taskType) {
    if (Objects.equals(getTaskStatus(userId, taskType), DailyTaskStorageStatus.UNDONE)) {
      try {
        mongoTemplate.save(new DailyTaskStorage()
            .setId(userId + "_" + taskType)
            .setUserId(userId)
            .setTaskType(taskType)
            .setDateNumber(ZonedDateTimeAsiaRiyadhUtils.nowDateToInt())
            .setStatus(DailyTaskStorageStatus.COMPLETED)
            .setExpiredTime(TimestampUtils.nowPlusDays(1))
            .setCreateTime(TimestampUtils.now())
        );
      } catch (DuplicateKeyException ex) {
        // ignore
      }
    }
  }

  @Override
  public void changeStatusReceived(Long userId, String taskType) {
    mongoTemplate
        .updateFirst(Query.query(Criteria.where("userId").is(userId)
                .and("taskType").is(taskType)
                .and("dateNumber").is(ZonedDateTimeAsiaRiyadhUtils.nowDateToInt())),
            new Update().set("status", DailyTaskStorageStatus.RECEIVED), DailyTaskStorage.class);
  }

  @Override
  public DailyTaskStorageStatus getTaskStatus(Long userId, String taskType) {
    return Optional.ofNullable(
        mongoTemplate
            .findOne(Query.query(Criteria.where("userId").is(userId)
                    .and("taskType").is(taskType)
                    .and("dateNumber").is(ZonedDateTimeAsiaRiyadhUtils.nowDateToInt())),
                DailyTaskStorage.class)
    ).map(DailyTaskStorage::getStatus).orElse(DailyTaskStorageStatus.UNDONE);
  }

  @Override
  public List<DailyTaskStorage> getByUserId(Long userId) {
    return mongoTemplate
        .find(Query.query(Criteria.where("userId").is(userId)
                .and("dateNumber").is(ZonedDateTimeAsiaRiyadhUtils.nowDateToInt())),
            DailyTaskStorage.class);
  }
}
