package com.liquidnet.service.merchant.util;

import com.liquidnet.service.kylin.dto.param.PerformancePartnerVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.partner.KylinTicketPartnerVo;
import com.liquidnet.service.kylin.dto.vo.partner.KylinTicketTimesPartnerVo;
import com.mongodb.BasicDBObject;
import com.mongodb.client.model.FindOneAndUpdateOptions;
import com.mongodb.client.model.ReturnDocument;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
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.Component;

import java.util.HashMap;
import java.util.List;

@Component
public class MongoMerchantUtils {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private MongoConverter mongoConverter;


    public PerformancePartnerVo getPerformancePartnerVo(String performanceId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("performancesId").is(performanceId)), PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName());
    }

    public long getPerformancePartnerCount(Query query) {
        return mongoTemplate.count(query, PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName());
    }

    public List<PerformancePartnerVo> getPerformancePartnerList(Query query) {
        return mongoTemplate.find(query, PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName());
    }

    public PerformancePartnerVo insertPerformancePartnerVo(PerformancePartnerVo data) {
        return mongoTemplate.insert(data, PerformancePartnerVo.class.getSimpleName());
    }

    public KylinTicketTimesPartnerVo insertTicketTimesPartnerVo(KylinTicketTimesPartnerVo data) {
        return mongoTemplate.insert(data, KylinTicketTimesPartnerVo.class.getSimpleName());
    }

    public KylinTicketTimesPartnerVo getTicketTimesPartnerVo(String ticketTimesId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("ticketTimesId").is(ticketTimesId)), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
    }

    public List<KylinTicketTimesPartnerVo> getTicketTimesPartnerVoList(String performancesId) {
        return mongoTemplate.find(Query.query(Criteria.where("performancesId").is(performancesId)), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
    }

    public void updateTicketTimesPartnerVo(KylinTicketTimesPartnerVo data) {
        Query query = Query.query(Criteria.where("ticketTimesId").is(data.getTicketTimesId()));
        BasicDBObject objectTicketVo = new BasicDBObject("$set", mongoConverter.convertToMongoType(data));
        mongoTemplate.getCollection(KylinTicketTimesPartnerVo.class.getSimpleName()).updateOne(
                query.getQueryObject(),
                objectTicketVo
        );
    }

    public Object delTicketTimesPartnerVo(String ticketTimesId) {
        return mongoTemplate.remove(Query.query(Criteria.where("ticketTimesId").is(ticketTimesId)), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
    }

    public KylinTicketPartnerVo insertTicketPartnerVo(KylinTicketPartnerVo data) {
        return mongoTemplate.insert(data, KylinTicketPartnerVo.class.getSimpleName());
    }

    public void updateTicketPartnerVo(KylinTicketPartnerVo data) {
        Query query = Query.query(Criteria.where("ticketsId").is(data.getTicketsId()));
        BasicDBObject objectTicketVo = new BasicDBObject("$set", mongoConverter.convertToMongoType(data));
        mongoTemplate.getCollection(KylinTicketPartnerVo.class.getSimpleName()).updateOne(
                query.getQueryObject(),
                objectTicketVo
        );
    }

    public void submitTicketByTimes(KylinTicketPartnerVo data) {
        Query query = Query.query(Criteria.where("timesId").is(data.getTimesId()).and("status").nin(-2, 7));
        BasicDBObject objectTicketVo = new BasicDBObject("$set", mongoConverter.convertToMongoType(data));
        mongoTemplate.getCollection(KylinTicketPartnerVo.class.getSimpleName()).updateOne(
                query.getQueryObject(),
                objectTicketVo
        );
    }

    public long getCountTicketPartnerByTimes(String timesId) {
        return mongoTemplate.count((Query.query(Criteria.where("timesId").is(timesId))), KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
    }

    public List<KylinTicketPartnerVo> getTicketMongoList(String timesId) {
        return mongoTemplate.find(Query.query(Criteria.where("timesId").is(timesId).and("status").ne(-1))
                        .with(Sort.by(Sort.Direction.ASC, "createdAt")),
                KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
    }

    public KylinTicketPartnerVo getTicketsMongo(String ticketsId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("ticketsId").is(ticketsId)), KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
    }

    public KylinTicketPartnerVo getTicketPartnerVo(String ticketsId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("ticketsId").is(ticketsId)), KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
    }

    public List<KylinTicketPartnerVo> getTicketPartnerVoList(String timesId) {
        return mongoTemplate.find(Query.query(Criteria.where("timesId").is(timesId)), KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
    }

    public void updatePerformancePartnerVoById(PerformancePartnerVo data) {
        Query query = Query.query(Criteria.where("performancesId").is(data.getPerformancesId()));
        BasicDBObject objectTicketVo = new BasicDBObject("$set", mongoConverter.convertToMongoType(data));
        mongoTemplate.getCollection(PerformancePartnerVo.class.getSimpleName()).updateOne(
                query.getQueryObject(),
                objectTicketVo
        );
    }

    public void updateSubmitTicketVoById(KylinTicketPartnerVo data) {
        Query query = Query.query(Criteria.where("ticketsId").is(data.getTicketsId()).and("status").in(3, 6, 8, 9, 10));
        BasicDBObject objectTicketVo = new BasicDBObject("$set", mongoConverter.convertToMongoType(data));
        mongoTemplate.getCollection(KylinTicketPartnerVo.class.getSimpleName()).updateOne(
                query.getQueryObject(),
                objectTicketVo
        );
    }

    public void deleteTicketPartnerVo(String ticketsId) {
        mongoTemplate.remove(Query.query(Criteria.where("ticketsId").is(ticketsId)), KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
    }

    public boolean isExistsSubmitPerformancePartner(String performanceId) {
        return mongoTemplate.exists(Query.query(Criteria.where("performancesId").is(performanceId).and("auditStatus").is(0)),
                PerformancePartnerVo.class,
                PerformancePartnerVo.class.getSimpleName());
    }

    public boolean isExistsAddTicket(String timesId) {
        return mongoTemplate.exists(Query.query(Criteria.where("status").is(-2).and("timesId").is(timesId)), KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
    }

    public boolean isExistsAddTime(String performanceId) {
        return mongoTemplate.exists(Query.query(Criteria.where("status").is(-1).and("performancesId").is(performanceId)), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
    }

    public List<KylinTicketTimesPartnerVo> getTimesMongoList(String performanceId) {
        return mongoTemplate.find(Query.query(Criteria.where("performancesId").is(performanceId)).with(Sort.by(Sort.Direction.ASC, "createdAt")),
                KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
    }

    public KylinTicketTimesPartnerVo getTimesMongo(String timesId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("ticketTimesId").is(timesId).and("status")), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
    }

    public KylinPerformanceVo insertPerformanceVo(KylinPerformanceVo data) {
        return mongoTemplate.insert(data, KylinPerformanceVo.class.getSimpleName());
    }

    public Object delPerformanceVo(String performanceId) {
        return mongoTemplate.remove(Query.query(Criteria.where("performancesId").is(performanceId)), KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());
    }

    public KylinPerformanceVo getPerformanceVo(String performanceId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("performancesId").is(performanceId)), KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());
    }

    public List<KylinPerformanceVo> getPerformanceVoOnlineList() {
        return mongoTemplate.find(Query.query(Criteria.where("appStatus").in(6, 8, 9)), KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());
    }

    public Document getObjectTicketVo(HashMap<String, Object> map, String ticketsId) {
        BasicDBObject objectTicketVo = new BasicDBObject("$set", mongoConverter.convertToMongoType(map));
        Document docTicket = mongoTemplate.getCollection(KylinTicketPartnerVo.class.getSimpleName()).findOneAndUpdate(
                Query.query(Criteria.where("ticketsId").is(ticketsId)).getQueryObject(),
                objectTicketVo,
                new FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER)
        );
        return docTicket;
    }
}
