package com.huangzj.server.mongo;

import com.huangzj.server.config.AppProperties;
import lombok.extern.slf4j.Slf4j;
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.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class DemoMongoService {

    private final MongoTemplate mongoTemplate;
    private final AppProperties appProperties;
    private volatile DemoPayloadDoc scheduledDoc;

    public DemoMongoService(MongoTemplate mongoTemplate, AppProperties appProperties) {
        this.mongoTemplate = mongoTemplate;
        this.appProperties = appProperties;
    }

    @Scheduled(fixedDelayString = "${app.save.interval-ms}")
    public void flushScheduled() {
        DemoPayloadDoc doc = scheduledDoc;
        if (doc == null) {
            return;
        }
        scheduledDoc = null;
        try {
            saveImmediate(doc);
            log.info("scheduled mongo save playerId={}", doc.getPlayerId());
        } catch (Exception e) {
            log.error("scheduled save failed", e);
        }
    }

    public void scheduleSave(DemoPayloadDoc doc) {
        this.scheduledDoc = doc;
    }

    public DemoPayloadDoc saveImmediate(DemoPayloadDoc doc) {
        return mongoTemplate.save(doc, appProperties.getMongo().getCollection());
    }

    public DemoPayloadDoc findLatestByPlayer(long playerId) {
        Query q = new Query(Criteria.where("playerId").is(playerId))
                .with(Sort.by(Sort.Direction.DESC, "_id"))
                .limit(1);
        return mongoTemplate.findOne(q, DemoPayloadDoc.class, appProperties.getMongo().getCollection());
    }
}
