package cn.reghao.tnb.search.app.comment.db.mongo;

import cn.reghao.jutil.jdk.web.db.BaseCrud;
import cn.reghao.jutil.jdk.web.db.BaseQuery;
import cn.reghao.tnb.search.app.comment.model.po.UserDanmaku;
import cn.reghao.tnb.content.api.dto.DanmakuRetVo;
import com.mongodb.MongoBulkWriteException;
import com.mongodb.client.model.InsertManyOptions;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.InsertManyResult;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.convert.MongoConverter;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2023-02-02 11:04:02
 */
@Slf4j
@Repository
public class UserDanmakuMongo implements BaseCrud<UserDanmaku>, BaseQuery<UserDanmaku> {
    private final String colName = "UserDanmaku";
    private final MongoTemplate mongoTemplate;
    private final MongoConverter mongoConverter;
    private final int pageSize = 20;

    public UserDanmakuMongo(MongoTemplate mongoTemplate, MongoConverter mongoConverter) {
        this.mongoTemplate = mongoTemplate;
        this.mongoConverter = mongoConverter;
    }

    @Override
    public UserDanmaku save(UserDanmaku userDanmaku) {
        Document doc = new Document();
        mongoConverter.write(userDanmaku, doc);
        mongoTemplate.getCollection(colName).insertOne(doc);
        return null;
    }

    @Override
    public void saveAll(List<UserDanmaku> list) {
        List<Document> documents = list.stream()
                .map(t -> {
                    Document doc = new Document();
                    mongoConverter.write(t, doc);
                    return doc;
                })
                .collect(Collectors.toList());

        InsertManyOptions options = new InsertManyOptions();
        // 忽略 insert 失败的文档
        options.ordered(false);
        try {
            InsertManyResult result = mongoTemplate.getCollection(colName).insertMany(documents, options);
        }  catch (MongoBulkWriteException ignore) {
        }
    }

    @Override
    public void update(UserDanmaku userDanmaku) {
        userDanmaku.setUpdateTime(LocalDateTime.now());

        Document document = new Document();
        mongoConverter.write(userDanmaku, document);
        Document filter = new Document();
        mongoTemplate.getCollection(colName).replaceOne(filter, document);
    }

    @Override
    public void delete(UserDanmaku userDanmaku) {
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(userDanmaku.getId()));
        DeleteResult deleteResult = mongoTemplate.remove(query, UserDanmaku.class);
    }

    public List<DanmakuRetVo> findByVideoId(String videoId, int size) {
        Query query = new Query();
        query.addCriteria(Criteria.where("videoId").is(videoId));
        query.limit(size);
        query.fields()
                .include("time")
                .include("type")
                .include("color")
                .include("userId")
                .include("text");
        return mongoTemplate.find(query, DanmakuRetVo.class, colName);
    }
}
