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

import com.mongodb.client.model.Filters;
import com.red.circle.component.mongodb.config.MongoPrimaryService;
import com.red.circle.component.mongodb.page.MongoPageHelper;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.other.infra.database.mongo.entity.game.ktv.GameKtvHotSongCount;
import com.red.circle.other.infra.database.mongo.entity.game.ktv.query.GameKtvHotSongQuery;
import com.red.circle.other.infra.database.mongo.service.game.GameKtvHotSongCountService;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
import com.red.circle.tool.core.text.StringUtils;
import java.util.Objects;
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.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

/**
 * Ktv用户已点歌单.
 *
 * @author pengshigang on 2023/5/5
 */
@Service
@RequiredArgsConstructor
public class GameKtvHotSongCountServiceImpl implements GameKtvHotSongCountService {

  private final MongoTemplate mongoTemplate;
  private final MongoPageHelper mongoPageHelper;
  private final MongoPrimaryService mongoPrimaryService;

  @Override
  public void incPopularityValue(String sysOrigin, String regionId, Long songId,
      Long popularityValue) {

    String id = songId + "_" + regionId + "_" + ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt();

    if (mongoPrimaryService.exists("game_ktv_hot_song_count", Filters.and(
        Filters.eq("_id", id)
    ))) {

      mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(id)),
          new Update()
              .inc("popularityValue", popularityValue)
              .set("updateTime", TimestampUtils.now()),
          GameKtvHotSongCount.class);
      return;
    }

    mongoTemplate.save(new GameKtvHotSongCount()
        .setId(id)
        .setPopularityValue(popularityValue)
        .setFrequency(1L)
        .setRegionId(regionId)
        .setSongId(songId)
        .setSysOrigin(sysOrigin)
        .setDateNumber(ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt())
        .setCreateTime(TimestampUtils.now())
        .setExpiredTime(TimestampUtils.nowPlusDays(120))
    );
  }


  @Override
  public void add(String sysOrigin, String regionId, Long songId) {

    String id = songId + "_" + regionId + "_" + ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt();

    if (mongoPrimaryService.exists(
        "game_ktv_hot_song_count", Filters.eq("_id", id))) {

      mongoTemplate.updateFirst(Query.query(Criteria.where("id").is(id)),
          new Update()
              .inc("frequency", 1L)
              .set("updateTime", TimestampUtils.now()),
          GameKtvHotSongCount.class);
      return;
    }

    mongoTemplate.save(new GameKtvHotSongCount()
        .setId(id)
        .setPopularityValue(0L)
        .setFrequency(1L)
        .setRegionId(regionId)
        .setSongId(songId)
        .setSysOrigin(sysOrigin)
        .setDateNumber(ZonedDateTimeAsiaRiyadhUtils.nowYearMonthToInt())
        .setCreateTime(TimestampUtils.now())
        .setExpiredTime(TimestampUtils.nowPlusDays(120))
    );

  }

  @Override
  public PageResult<GameKtvHotSongCount> pageCount(GameKtvHotSongQuery query) {

    Criteria criteria = Criteria.where("sysOrigin").is(query.getSysOrigin());

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

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

    return mongoPageHelper
        .query(new Query(criteria),
            GameKtvHotSongCount.class,
            query.getPageSize(),
            query.getPageNumber(),
            Sort.Order.desc("createTime"));

  }
}
