package com.liquidnet.service.slime.util;

import com.liquidnet.commons.lang.util.CollectionUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.service.kylin.dao.PerformancePartnerListDao;
import com.liquidnet.service.kylin.dto.param.PerformancePartnerListParam;
import com.liquidnet.service.kylin.dto.param.PerformancePartnerVo;
import com.liquidnet.service.kylin.dto.vo.KylinTimePerformanceVo;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketTimesVo;
import com.liquidnet.service.kylin.dto.vo.middle.KylinTicketVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinOrderTicketVo;
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.liquidnet.service.slime.constant.SlimeAuthorizationConst;
import com.liquidnet.service.slime.dto.vo.SlimeAuthorizationPerformanceVo;
import com.liquidnet.service.slime.dto.vo.SlimeFieldAppliesVo;
import com.liquidnet.service.slime.service.SlimeRdmService;
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.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
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.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class MongoSlimeUtils {
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private MongoConverter mongoConverter;
    @Autowired
    private RedisSlimeUtils redisSlimeUtils;
    @Autowired
    private SlimeRdmService slimeRdmService;


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

    public PerformancePartnerVo getPerformancePartnerVoNoMerchant(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 = ObjectUtil.cloneBasicDBObject().append("$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 = ObjectUtil.cloneBasicDBObject().append("$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 = ObjectUtil.cloneBasicDBObject().append("$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 = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(data));
        mongoTemplate.getCollection(PerformancePartnerVo.class.getSimpleName()).updateOne(
                query.getQueryObject(),
                objectTicketVo
        );
    }

    public void updateKylinPerformanceVoById(KylinPerformanceVo data) {
        Query query = Query.query(Criteria.where("performancesId").is(data.getPerformancesId()));
        BasicDBObject objectTicketVo = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(data));
        mongoTemplate.getCollection(KylinPerformanceVo.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 = ObjectUtil.cloneBasicDBObject().append("$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) {
        redisSlimeUtils.delPerformanceVo(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 KylinPerformanceVo getPerformanceVoNoMerchant(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 KylinTimePerformanceVo insertTimeLine(KylinTimePerformanceVo data) {
        return mongoTemplate.insert(data, KylinTimePerformanceVo.class.getSimpleName());
    }

    //获取 演唱定时任务
    public List<KylinTimePerformanceVo> getTimeLine(String performanceId) {
        return mongoTemplate.find(Query.query(Criteria.where("performanceId").is(performanceId)), KylinTimePerformanceVo.class, KylinTimePerformanceVo.class.getSimpleName());
    }

    //删除 演出定时任务
    public Object delTimeLine(String performances) {
        return mongoTemplate.remove(Query.query(Criteria.where("performanceId").is(performances)), KylinTimePerformanceVo.class, KylinTimePerformanceVo.class.getSimpleName());
    }

    /**
     * 判断该用户对于此演出是否有权限
     *
     * @param performanceId 演出id
     * @param merchantId    用户id(第三方id)
     * @param permissionIds 权限id
     * @return
     */
    public boolean judgeIsPermission(String performanceId, String merchantId, String[] permissionIds) {
        if (redisSlimeUtils.superAccount(merchantId)) {
            return true;
        } else {
            return mongoTemplate.exists(Query.query(Criteria.where("performanceId").is(performanceId)
                            .and("uid").is(merchantId)
                            .and("permissionIds").in(permissionIds))
                    , SlimeAuthorizationPerformanceVo.class, SlimeAuthorizationPerformanceVo.class.getSimpleName());
        }
    }

    public Document getObjectTicketVo(HashMap<String, Object> map, String ticketsId) {
        BasicDBObject objectTicketVo = ObjectUtil.cloneBasicDBObject().append("$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;
    }

    public HashMap<String,Object> getPerformanceList(PerformancePartnerListParam performancePartnerListParam) {
        performancePartnerListParam.setOrderType(performancePartnerListParam.getOrderType());
        //分页排序
        Sort.Direction orderBy = Sort.Direction.DESC;
        if (performancePartnerListParam.getOrderSc().equals("asc")) {
            orderBy = Sort.Direction.ASC;
        }

        List<String> performanceIdList = null;
        List<SlimeAuthorizationPerformanceVo> permissionVoList = ObjectUtil.getPermissionVoList();
        if (!redisSlimeUtils.superAccount(performancePartnerListParam.getMerchantId())) {
            //根据权限查询演出id
            permissionVoList = mongoTemplate.find(Query.query(Criteria.where("uid").is(performancePartnerListParam.getMerchantId())
                            .and("permissionIds").in(
                            SlimeAuthorizationConst.PerformancePermission.READ.getId(),
                            SlimeAuthorizationConst.PerformancePermission.EDIT.getId(),
//                            SlimeAuthorizationConst.PerformancePermission.SALES.getId(),
                            SlimeAuthorizationConst.PerformancePermission.LINE.getId())
                    ),
//                            .skip(((performancePartnerListParam.getPage() - 1) * performancePartnerListParam.getSize()))
//                            .limit(performancePartnerListParam.getSize()),
                    SlimeAuthorizationPerformanceVo.class, SlimeAuthorizationPerformanceVo.class.getSimpleName());
            performanceIdList = permissionVoList.stream().map(SlimeAuthorizationPerformanceVo::getPerformanceId).collect(Collectors.toList());
        }
        //查询演出
        Criteria criteriaPerformanceId = performanceIdList == null ? Criteria.where("performancesId").ne(null) : Criteria.where("performancesId").in(performanceIdList);
        Criteria criteria = Criteria.where("performancesId").ne(null);
        if (performancePartnerListParam.getTitle() != null && !performancePartnerListParam.getTitle().isEmpty()) {
            criteria = criteria.and("title").regex(".*" + performancePartnerListParam.getTitle() + ".*");
        }
        if (performancePartnerListParam.getStatus() != null) {
            if (performancePartnerListParam.getAuditStatus() == 0) {
                criteria = criteria.and("auditStatus").is(0);
            } else {
                if (performancePartnerListParam.getAuditStatus() != -2) {
                    criteria = criteria.and("auditStatus").is(performancePartnerListParam.getAuditStatus());
                }
                if (performancePartnerListParam.getTimeStart() != null && !performancePartnerListParam.getTimeStart().isEmpty()) {
                    criteria = criteria.and("timeStart").gte(performancePartnerListParam.getTimeStart()).lte(performancePartnerListParam.getTimeEnd());
                }
            }
        }
        List<KylinPerformanceVo> performanceVos = mongoTemplate.find(
                Query.query(new Criteria().andOperator(criteria).orOperator(criteriaPerformanceId, Criteria.where("merchantId").is(performancePartnerListParam.getMerchantId())))
                        .with(Sort.by(orderBy, performancePartnerListParam.getOrderItem()))
                        .skip(((performancePartnerListParam.getPage() - 1) * performancePartnerListParam.getSize()))
                        .limit(performancePartnerListParam.getSize()),
                KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());

        long total = mongoTemplate.count(
                Query.query(new Criteria().andOperator(criteria).orOperator(criteriaPerformanceId, Criteria.where("merchantId").is(performancePartnerListParam.getMerchantId())))
                        .with(Sort.by(orderBy, performancePartnerListParam.getOrderItem())),
                KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());
        //查询销量
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("status").in(0, 1, 3, 6).and("couponType").is("no").and("transferStatus").in(0, 1, 2, 5).and("performanceId").in(performanceIdList)),
                Aggregation.group("performanceId")
                        .first("performanceId").as("performancesId")
                        .sum("number").as("number")
                        .sum("refundNumber").as("refundNumber")
                        .sum("priceActual").as("priceActual")
                        .sum("priceRefund").as("priceRefund")

        );
        AggregationResults<PerformancePartnerListDao> outputType = mongoTemplate.aggregate(aggregation, KylinOrderTicketVo.class.getSimpleName(), PerformancePartnerListDao.class);
        List<PerformancePartnerListDao> dataList = new ArrayList(outputType.getMappedResults());
        List<PerformancePartnerListDao> list = ObjectUtil.getPerformancePartnerListDaoArrayList();
        for (KylinPerformanceVo item : performanceVos) {
            boolean findData = false;
            PerformancePartnerListDao dao = PerformancePartnerListDao.getNew();
            dao.setPerformancesId(item.getPerformancesId());
            dao.setTitle(item.getTitle());
            dao.setTimeStart(item.getTimeStart());
            dao.setTimeEnd(item.getTimeEnd());
            dao.setStatus(item.getAppStatus());
            dao.setType(item.getType());
            dao.setPayCountdownMinute(item.getPayCountdownMinute());
            dao.setAuditStatus(item.getAuditStatus());
            dao.setRejectTxt(item.getRejectTxt());
            dao.setCreatedAt(item.getCreatedAt());
            dao.setFieldAuditStatus(item.getFieldAuditStatus());
            int totalGeneral = 0;
            String timeSell = null;
            String timeStop = null;
            for (KylinTicketTimesVo timeItem : item.getTicketTimeList()) {
                for (KylinTicketVo ticketItem : timeItem.getTicketList()) {
                    if (timeSell == null) {
                        timeSell = ticketItem.getTimeStart();
                    } else if (DateUtil.compareStrDay(timeSell, ticketItem.getTimeStart()) > 0) {
                        timeSell = ticketItem.getTimeStart();
                    }
                    if (timeStop == null) {
                        timeStop = ticketItem.getTimeEnd();
                    } else if (DateUtil.compareStrDay(timeStop, ticketItem.getTimeEnd()) < 0) {
                        timeStop = ticketItem.getTimeEnd();
                    }
                    totalGeneral += ticketItem.getTotalGeneral();
                }
            }
            dao.setTotalGeneral(totalGeneral);
            dao.setTimeSell(timeSell);
            dao.setTimeStop(timeStop);

            if (item.getMerchantId().equals(performancePartnerListParam.getMerchantId()) || redisSlimeUtils.superAccount(performancePartnerListParam.getMerchantId())) {
                dao.setPermissionId(new ArrayList<String>() {{
                    add(SlimeAuthorizationConst.PerformancePermission.READ.getId());
                    add(SlimeAuthorizationConst.PerformancePermission.EDIT.getId());
                    add(SlimeAuthorizationConst.PerformancePermission.LINE.getId());
                    add(SlimeAuthorizationConst.PerformancePermission.SALES.getId());
                    add(SlimeAuthorizationConst.PerformancePermission.CHECK.getId());
                    add(SlimeAuthorizationConst.PerformancePermission.GRANT.getId());
                }});
            }

            for (SlimeAuthorizationPerformanceVo permission : permissionVoList) {
                if (item.getMerchantId().equals(performancePartnerListParam.getMerchantId()) || redisSlimeUtils.superAccount(performancePartnerListParam.getMerchantId())) {
                    dao.setPermissionId(new ArrayList<String>() {{
                        add(SlimeAuthorizationConst.PerformancePermission.READ.getId());
                        add(SlimeAuthorizationConst.PerformancePermission.EDIT.getId());
                        add(SlimeAuthorizationConst.PerformancePermission.LINE.getId());
                        add(SlimeAuthorizationConst.PerformancePermission.SALES.getId());
                        add(SlimeAuthorizationConst.PerformancePermission.CHECK.getId());
                        add(SlimeAuthorizationConst.PerformancePermission.GRANT.getId());
                    }});
                    break;
                }
                if (permission.getPerformanceId().equals(item.getPerformancesId())) {
                    dao.setPermissionId(permission.getPermissionIds());
                    permissionVoList.remove(permission);
                    break;
                }
            }

            for (int i = 0; i < dataList.size(); i++) {
                PerformancePartnerListDao data = dataList.get(i);
                if (data.getPerformancesId().equals(item.getPerformancesId())) {
                    findData = true;
                    dao.setNumber(data.getNumber());
                    dao.setRefundNumber(data.getRefundNumber());
                    dao.setPriceActual(data.getPriceActual());
                    dao.setPriceRefund(data.getPriceRefund());
                    dataList.remove(i);
                    break;
                }
            }

            if (!findData) {
                dao.setNumber(0);
                dao.setRefundNumber(0);
                dao.setPriceActual(BigDecimal.ZERO);
                dao.setPriceRefund(BigDecimal.ZERO);
            }
            list.add(dao);
        }
        HashMap<String ,Object> map = CollectionUtil.mapStringObject();
        map.put("data",list);
        map.put("total",total);
        return map;
    }

    public List<PerformancePartnerListDao> getPerformanceListField(PerformancePartnerListParam performancePartnerListParam) {
        //分页排序
        Sort.Direction orderBy = Sort.Direction.DESC;
        if (performancePartnerListParam.getOrderSc().equals("asc")) {
            orderBy = Sort.Direction.ASC;
        }
        //根据用户id获取场地拥有那些演出
        List<String> fieldsIdList = slimeRdmService.getFieldAppliesVosByUid(performancePartnerListParam.getMerchantId()).stream().map(SlimeFieldAppliesVo::getFieldId).collect(Collectors.toList());
        //查询演出
        Criteria criteria = fieldsIdList == null ? Criteria.where("fieldId").ne(null) : Criteria.where("fieldId").in(fieldsIdList);
        if (performancePartnerListParam.getTitle() != null && !performancePartnerListParam.getTitle().isEmpty()) {
            criteria = criteria.and("title").regex(".*" + performancePartnerListParam.getTitle() + ".*");
        }
        if (performancePartnerListParam.getTimeStart() != null && !performancePartnerListParam.getTimeStart().isEmpty()) {
            criteria = criteria.and("timeStart").gte(performancePartnerListParam.getTimeStart()).and("timeStart").lte(performancePartnerListParam.getTimeEnd());
        }
        List<KylinPerformanceVo> performanceVos = mongoTemplate.find(
                Query.query(criteria.and("fieldAuditStatus").is(1)).with(Sort.by(orderBy, performancePartnerListParam.getOrderItem())),
                KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());
        //查询销量
        Aggregation aggregation = Aggregation.newAggregation(
                Aggregation.match(Criteria.where("status").in(0, 1, 3, 6).and("couponType").is("no").and("transferStatus").in(0, 1, 2, 5).and("performanceId").in(performanceVos.stream().map(KylinPerformanceVo::getPerformancesId).collect(Collectors.toList()))),
                Aggregation.group("performanceId")
                        .first("performanceId").as("performancesId")
                        .sum("number").as("number")
                        .sum("refundNumber").as("refundNumber")
                        .sum("priceActual").as("priceActual")
                        .sum("priceRefund").as("priceRefund")
        );
        AggregationResults<PerformancePartnerListDao> outputType = mongoTemplate.aggregate(aggregation, KylinOrderTicketVo.class.getSimpleName(), PerformancePartnerListDao.class);
        List<PerformancePartnerListDao> dataList = new ArrayList(outputType.getMappedResults());
        List<PerformancePartnerListDao> list = ObjectUtil.getPerformancePartnerListDaoArrayList();
        for (KylinPerformanceVo item : performanceVos) {
            boolean findData = false;
            PerformancePartnerListDao dao = PerformancePartnerListDao.getNew();
            dao.setPerformancesId(item.getPerformancesId());
            dao.setTitle(item.getTitle());
            dao.setTimeStart(item.getTimeStart());
            dao.setTimeEnd(item.getTimeEnd());
            dao.setStatus(item.getAppStatus());
            dao.setType(item.getType());
            dao.setPayCountdownMinute(item.getPayCountdownMinute());
            dao.setAuditStatus(item.getAuditStatus());
            dao.setRejectTxt(item.getRejectTxt());
            dao.setCreatedAt(item.getCreatedAt());
            dao.setFieldAuditStatus(item.getFieldAuditStatus());
            int totalGeneral = 0;
            String timeSell = null;
            String timeStop = null;
            for (KylinTicketTimesVo timeItem : item.getTicketTimeList()) {
                for (KylinTicketVo ticketItem : timeItem.getTicketList()) {
                    if (timeSell == null) {
                        timeSell = ticketItem.getTimeStart();
                    } else if (DateUtil.compareStrDay(timeSell, ticketItem.getTimeStart()) > 0) {
                        timeSell = ticketItem.getTimeStart();
                    }
                    if (timeStop == null) {
                        timeStop = ticketItem.getTimeEnd();
                    } else if (DateUtil.compareStrDay(timeStop, ticketItem.getTimeEnd()) < 0) {
                        timeStop = ticketItem.getTimeEnd();
                    }
                    totalGeneral += ticketItem.getTotalGeneral();
                }
            }
            dao.setTotalGeneral(totalGeneral);
            dao.setTimeSell(timeSell);
            dao.setTimeStop(timeStop);

            for (int i = 0; i < dataList.size(); i++) {
                PerformancePartnerListDao data = dataList.get(i);
                if (data.getPerformancesId().equals(item.getPerformancesId())) {
                    findData = true;
                    dao.setNumber(data.getNumber());
                    dao.setRefundNumber(data.getRefundNumber());
                    dao.setPriceActual(data.getPriceActual());
                    dao.setPriceRefund(data.getPriceRefund());
                    dataList.remove(i);
                    break;
                }
            }

            if (!findData) {
                dao.setNumber(0);
                dao.setRefundNumber(0);
                dao.setPriceActual(BigDecimal.ZERO);
                dao.setPriceRefund(BigDecimal.ZERO);
            }
            list.add(dao);
        }

        return list;
    }
}
