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

import com.red.circle.component.mongodb.page.MongoPageHelper;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.mybatis.constant.PageConstant;
import com.red.circle.other.infra.database.mongo.entity.live.RoomTopFixed;
import com.red.circle.other.infra.database.mongo.service.live.RoomTopFixedService;
import com.red.circle.other.inner.model.cmd.sys.RoomTopFixedQryCmd;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.sql.Timestamp;
import java.util.Objects;
import java.util.Optional;
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 pengliang on 2022/11/16
 */
@Service
@RequiredArgsConstructor
public class RoomTopFixedServiceImpl implements RoomTopFixedService {

  private final MongoTemplate mongoTemplate;
  private final MongoPageHelper mongoPageHelper;

  @Override
  public void add(RoomTopFixed param) {
    mongoTemplate.save(param);
  }

  @Override
  public void removeById(Long id) {
    mongoTemplate.remove(Query.query(Criteria.where("id").is(id)), RoomTopFixed.class);
  }

  @Override
  public PageResult<RoomTopFixed> list(RoomTopFixedQryCmd query) {
    Criteria criteria = Criteria.where("sysOrigin").is(query.getSysOrigin());
    if (Objects.nonNull(query.getRoomId())) {
      criteria.and("id").is(query.getRoomId());
    }

    if (StringUtils.isNotBlank(query.getRegion())) {
      criteria.and("region").is(query.getRegion());
    }

    if (Objects.isNull(query.getLimit())) {
      query.setLimit(PageConstant.DEFAULT_LIMIT_SIZE);
    }

    if (Objects.isNull(query.getCursor())) {
      query.setCursor(1);
    }
    return mongoPageHelper.query(Query.query(criteria), RoomTopFixed.class, query.getLimit(),
        query.getCursor(), Sort.Order.desc("weights"));
  }


  @Override
  public RoomTopFixed getByRoomId(Long roomId) {
    return mongoTemplate.findOne(Query.query(Criteria.where("id").is(roomId)), RoomTopFixed.class);
  }

  @Override
  public RoomTopFixed getEffectiveByRoomId(Long roomId) {
    return mongoTemplate.findOne(Query.query(effectiveCriteria(roomId)), RoomTopFixed.class);
  }

  @Override
  public Integer getWeights(Long roomId) {
    return Optional.ofNullable(getEffectiveByRoomId(roomId))
        .map(top -> Objects.nonNull(top.getWeights()) ? top.getWeights() : 0)
        .orElse(0);
  }

  private Criteria effectiveCriteria(Long roomId) {
    Timestamp now = TimestampUtils.now();
    return new Criteria().andOperator(
        Criteria.where("id").is(roomId),
        Criteria.where("startTime").lte(now),
        new Criteria().orOperator(
            Criteria.where("expiredTime").is(null),
            Criteria.where("expiredTime").gt(now)
        )
    );
  }

}
