package com.liquidnet.service.platform.service.impl.partner;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.commons.lang.util.BeanUtil;
import com.liquidnet.commons.lang.util.DateUtil;
import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.ErrorMapping;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.UserPathDto;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dao.PerformanceOrderStatisticalDao;
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.param.PerformanceStep1Param;
import com.liquidnet.service.kylin.dto.param.PerformanceStep2Param;
import com.liquidnet.service.kylin.dto.vo.PerformanceOrderStatisticalVo;
import com.liquidnet.service.kylin.dto.vo.partner.*;
import com.liquidnet.service.kylin.entity.*;
import com.liquidnet.service.kylin.mapper.*;
import com.liquidnet.service.kylin.service.partner.IKylinPerformancesPartnerService;
import com.liquidnet.service.platform.utils.DataUtils;
import com.liquidnet.service.platform.utils.ObjectUtil;
import com.liquidnet.service.platform.utils.PerformanceVoTask;
import com.mongodb.BasicDBObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
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.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 演出 服务实现类
 * </p>
 *
 * @author liquidnet
 * @since 2021-05-05
 */
@Service
@Slf4j
public class KylinPerformancesPartnerServiceImpl extends ServiceImpl<KylinPerformancesMapper, KylinPerformances> implements IKylinPerformancesPartnerService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private MongoConverter mongoConverter;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private DataUtils dataUtils;

    @Autowired
    private PerformanceVoTask performanceVoTask;

    @Autowired
    private KylinPerformancesMapper performancesMapper;

    @Autowired
    private KylinPerformanceStatusMapper performanceStatusMapper;

    @Autowired
    private KylinPerformanceRelationsMapper performanceRelationsMapper;

    @Autowired
    private KylinTicketTimesMapper ticketTimesMapper;

    @Autowired
    private KylinTicketTimeRelationMapper ticketTimeRelationMapper;

    @Autowired
    private KylinTicketsMapper ticketsMapper;

    @Autowired
    private KylinTicketStatusMapper ticketStatusMapper;

    @Autowired
    private KylinTicketRelationsMapper ticketRelationsMapper;

    @Autowired
    private KylinTicketsPartnerServiceImpl ticketsPartnerService;

    @Autowired
    private KylinTicketTimesPartnerServiceImpl ticketTimesPartnerService;

    @Override
    public String step1(PerformanceStep1Param step1Param) {
        String result = null;
        // 无 performancesId 则 创建
        if (null == step1Param.getPerformancesId()) {
            result = createStep1(step1Param);
        } else { // 获取 create 数据 status = 0 或 无数据 创建
            PerformancePartnerVo createParam = mongoTemplate.findOne(Query.query(Criteria.where("performancesId").is(step1Param.getPerformancesId())), PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName());
            if (createParam == null) {
                result = createStep1(step1Param);
                log.info(UserPathDto.setPartnerData(step1Param.getMerchantId(), "createStep1", step1Param, result));
            } else {// 修改
                result = updateStep1(step1Param);
                log.info(UserPathDto.setPartnerData(step1Param.getMerchantId(), "updateStep1", step1Param, result));
            }
        }
        return result;
    }

    @Override
    public String createStep1(PerformanceStep1Param step1Param) {
        // 获取 主键id
        String performanceId = IDGenerator.nextSnowId().toString();
        // 获取 当前时间 -> 创建时间
        LocalDateTime createdAt = LocalDateTime.now();

        try {
            step1Param.setPerformancesId(performanceId);
            PerformancePartnerVo performancePartnerVo = PerformancePartnerVo.getNew();
            BeanUtils.copyProperties(step1Param, performancePartnerVo);
            performancePartnerVo.setIsTrueName(0);
            performancePartnerVo.setLimitCount(0);
            performancePartnerVo.setCreatedAt(createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            performancePartnerVo.setIsSubmit(0);
            performancePartnerVo.setStatus(0);
            performancePartnerVo.setStatusSell(1);
            performancePartnerVo.setAuditStatus(-1);
            performancePartnerVo.setRoadShowId("0");
            performancePartnerVo.setProjectId("0");
            performancePartnerVo.setIsShow(1);
            performancePartnerVo.setFieldName((String) redisUtil.getDB15RedisHGet(KylinRedisConst.FIELDS + ":" + performancePartnerVo.getFieldId(), "name"));
            performancePartnerVo.setNoticeImage(dataUtils.getBuyNoticeJsonString(step1Param.getNoticeIds()));

            mongoTemplate.insert(
                    performancePartnerVo, PerformancePartnerVo.class.getSimpleName()
            );
            return performanceId;
        } catch (Exception e) {
            e.printStackTrace();
            log.info(UserPathDto.setPartnerData(step1Param.getMerchantId(), "createStep1", step1Param, e));
            return null;
        }
    }

    @Override
    public String updateStep1(PerformanceStep1Param step1Param) {
        // 获取 当前时间 -> 创建时间
        LocalDateTime timeNow = LocalDateTime.now();
        String performanceId = step1Param.getPerformancesId();
        try {
            PerformancePartnerVo data = mongoTemplate.findOne(Query.query(Criteria.where("performancesId").is(performanceId)),
                    PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName());
            if (data == null || data.getAuditStatus() == null || data.getAuditStatus() == 0) {
                return "不可修改";
            }

            step1Param.setPerformancesId(performanceId);
            PerformancePartnerVo performancePartnerVo = PerformancePartnerVo.getNew();
            BeanUtils.copyProperties(step1Param, performancePartnerVo);
            performancePartnerVo.setCreatedAt(timeNow.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            performancePartnerVo.setUpdatedAt(timeNow.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            performancePartnerVo.setIsSubmit(0);
            performancePartnerVo.setStatus(0);
            performancePartnerVo.setNoticeImage(dataUtils.getBuyNoticeJsonString(step1Param.getNoticeIds()));
            performancePartnerVo.setFieldName((String) redisUtil.getDB15RedisHGet(KylinRedisConst.FIELDS + ":" + performancePartnerVo.getFieldId(), "name"));
            performancePartnerVo.setNoticeImage(dataUtils.getBuyNoticeJsonString(step1Param.getNoticeIds()));
            if (data != null) { // 有修改记录
                performancePartnerVo.setIsTrueName(data.getIsTrueName());
                performancePartnerVo.setLimitCount(data.getLimitCount());
                performancePartnerVo.setStatusSell(data.getStatusSell());
                performancePartnerVo.setRoadShowId(data.getRoadShowId());
                performancePartnerVo.setProjectId(data.getProjectId());
                BasicDBObject object = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(performancePartnerVo));
                mongoTemplate.getCollection(PerformancePartnerVo.class.getSimpleName()).updateOne(
                        Query.query(Criteria.where("performancesId").is(performanceId)).getQueryObject(),
                        object
                );
            } else { // 无修改记录
                KylinPerformanceStatus statusData = performanceStatusMapper.selectOne(Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performanceId));
                KylinPerformanceRelations relationsData = performanceRelationsMapper.selectOne(Wrappers.lambdaQuery(KylinPerformanceRelations.class).eq(KylinPerformanceRelations::getPerformanceId, performanceId));
                performancePartnerVo.setIsTrueName(statusData.getIsTrueName());
                performancePartnerVo.setLimitCount(statusData.getLimitCount());
                performancePartnerVo.setStatusSell(statusData.getStatusSell());
                performancePartnerVo.setRoadShowId(relationsData.getRoadShowId());
                performancePartnerVo.setProjectId(relationsData.getProjectId());
                mongoTemplate.insert(
                        performancePartnerVo, PerformancePartnerVo.class.getSimpleName()
                );
            }
            return performanceId;
        } catch (Exception e) {
            e.printStackTrace();
            log.info(UserPathDto.setPartnerData(step1Param.getMerchantId(), "updateStep1", step1Param, e));
            return null;
        }
    }

    @Override
    public ResponseDto<PerformancePartnerVo> getStep1(String performancesId) {
        PerformancePartnerVo data = mongoTemplate.findOne(
                Query.query(Criteria.where("performancesId").is(performancesId)), PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName()
        );
        KylinPerformanceStatus performanceStatus = performanceStatusMapper.selectOne(Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performancesId));
        if (data == null) {
            return ResponseDto.failure(ErrorMapping.get(20104));
        }
        if (null != performanceStatus) {
            data.setStatus(performanceStatus.getStatus());
        }
        log.info(UserPathDto.setPartnerData("0", "getStep1", "performancesId=" + performancesId, data));
        return ResponseDto.success(data);
    }

    @Override
    public ResponseDto<String> step2(PerformanceStep2Param step2Param) {
        ResponseDto<String> result = null;
        // 无 performancesId 则 创建
        if (step2Param.getPerformancesId().isEmpty()) {
        } else { // 获取 create 数据 status = 0 或 无数据 创建
            KylinPerformanceStatus performanceStatus = performanceStatusMapper.selectOne(Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, step2Param.getPerformancesId()));
            if (performanceStatus == null || performanceStatus.getStatus() == 0 || performanceStatus.getStatus() == 4) {
                result = createStep2(step2Param);
                log.info(UserPathDto.setPartnerData("0", "createStep2", step2Param, result));
            } else if (performanceStatus.getStatus() == 1 || performanceStatus.getStatus() == 3 || performanceStatus.getStatus() == 6 || performanceStatus.getStatus() == 7 || performanceStatus.getStatus() == 8 || performanceStatus.getStatus() == 9) {// 修改
                result = updateStep2(step2Param);
                log.info(UserPathDto.setPartnerData("0", "updateStep2(step2Param", step2Param, result));
            } else if (performanceStatus.getStatus() == 10) {
                result = ResponseDto.failure("演出已结束不可修改");
            }
        }
        return result;
    }

    @Override
    public ResponseDto<String> createStep2(PerformanceStep2Param step2Param) {
        try {
            // 获取 主键id
            String performanceId = step2Param.getPerformancesId();
            // 获取 当前时间 -> 创建时间
            LocalDateTime createdAt = LocalDateTime.now();

            boolean isExistsSubmit = mongoTemplate.exists(Query.query(Criteria.where("performancesId").is(performanceId).and("auditStatus").is(0)),
                    PerformancePartnerVo.class,
                    PerformancePartnerVo.class.getSimpleName());

            if (isExistsSubmit) {
                return ResponseDto.failure(ErrorMapping.get(20112));
            }

            //演出修改数据
            HashMap<String, Object> map = ObjectUtil.cloneHashMapStringAndObject();
            map.put("isTrueName", step2Param.getIsTrueName());
            map.put("limitCount", step2Param.getLimitCount());
            map.put("createdAt", createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            map.put("isSubmit", step2Param.getIsSubmit());
            map.put("statusSell", 1);

            // 获取第一步数据
            if (step2Param.getIsSubmit() == 1) { // 提交
                map.put("status", 1);
                map.put("isCreateSave", 0);
                map.put("auditStatus", 0);
                BasicDBObject object = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(map));
                mongoTemplate.getCollection(PerformancePartnerVo.class.getSimpleName()).updateOne(
                        Query.query(Criteria.where("performancesId").is(performanceId)).getQueryObject(),
                        object
                );
                //提交 票
                List<KylinTicketTimesPartnerVo> kylinTicketTimesPartnerVoList = ticketTimesPartnerService.getTimesMongoList(performanceId);
                for (KylinTicketTimesPartnerVo ticketTimes : kylinTicketTimesPartnerVoList) {
                    boolean boolResult = ticketsPartnerService.submitTicketByTimes(ticketTimes.getTicketTimesId(), null);
                    if (boolResult) {
                        return ResponseDto.failure(ErrorMapping.get(20114));
                    }
                }
                if (kylinTicketTimesPartnerVoList.size() <= 0) {
                    return ResponseDto.failure(ErrorMapping.get(20113));
                } else {
                    KylinPerformanceMisVo kylinPerformanceMisVo = performanceVoTask.getPerformanceMisVo(performanceId);

                    HashMap<String, Object> mapSql = ObjectUtil.cloneHashMapStringAndObject();
                    mapSql.put("isCreateSave", 0);
                    mapSql.put("rejectTxt", "");
                    mapSql.put("status", 1);
                    mapSql.put("updatedAt", createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    performanceVoTask.createPerformanceMySql(performanceId, mapSql, kylinPerformanceMisVo, createdAt);
                    KylinPerformances performances = KylinPerformances.getNew();
                    performances.setAuditTime(LocalDateTime.now());
                    performancesMapper.update(performances, Wrappers.lambdaQuery(KylinPerformances.class).eq(KylinPerformances::getPerformancesId, performanceId));
                }
                return ResponseDto.success("操作成功");
            } else { //保存
                map.put("status", 0);
                map.put("isCreateSave", 1);
                map.put("auditStatus", -1);
                BasicDBObject object = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(map));
                mongoTemplate.getCollection(PerformancePartnerVo.class.getSimpleName()).updateMany(
                        Query.query(Criteria.where("performancesId").is(performanceId)).getQueryObject(),
                        object
                );
                return ResponseDto.success("保存成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info(UserPathDto.setPartnerData("0", "createStep2", step2Param, e));
            return ResponseDto.failure(ErrorMapping.get(20115));
        }
    }

    @Override
    public ResponseDto<String> updateStep2(PerformanceStep2Param step2Param) {
        try {
            // 获取 主键id
            String performanceId = step2Param.getPerformancesId();
            // 获取 当前时间 -> 创建时间
            LocalDateTime createdAt = LocalDateTime.now();

            boolean isExistsSubmit = mongoTemplate.exists(Query.query(Criteria.where("performancesId").is(performanceId).and("auditStatus").is(0)),
                    PerformancePartnerVo.class,
                    PerformancePartnerVo.class.getSimpleName());

            if (isExistsSubmit) {
                return ResponseDto.failure(ErrorMapping.get(20112));
            }

            //演出修改数据
            HashMap<String, Object> map = ObjectUtil.cloneHashMapStringAndObject();
            map.put("isTrueName", step2Param.getIsTrueName());
            map.put("limitCount", step2Param.getLimitCount());
            map.put("createdAt", createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            map.put("updatedAt", createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            map.put("isSubmit", step2Param.getIsSubmit());

            // 获取第一步数据
            if (step2Param.getIsSubmit() == 1) { // 提交
                if (performanceVoTask.judgeIsAudit(performanceId)) {
                    map.put("auditStatus", 0);
                    map.put("status", 1);
                } else {
                    map.put("auditStatus", 1);
                    map.put("status", 9);
                }
                BasicDBObject object = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(map));
                mongoTemplate.getCollection(PerformancePartnerVo.class.getSimpleName()).updateOne(
                        Query.query(Criteria.where("performancesId").is(performanceId)).getQueryObject(),
                        object
                );
                //提交 票
                List<KylinTicketTimesPartnerVo> kylinTicketTimesPartnerVoList = ticketTimesPartnerService.getTimesMongoList(performanceId);
                for (KylinTicketTimesPartnerVo ticketTimes : kylinTicketTimesPartnerVoList) {
                    boolean boolResult = ticketsPartnerService.submitTicketByTimes(ticketTimes.getTicketTimesId(), (int) (map.get("status")));
                    if (boolResult) {
                        return ResponseDto.failure(ErrorMapping.get(20114));
                    }
                }
                if (kylinTicketTimesPartnerVoList.size() <= 0) {
                    return ResponseDto.failure(ErrorMapping.get(20113));
                } else {
                    KylinPerformanceMisVo kylinPerformanceMisVo = performanceVoTask.getPerformanceMisVo(performanceId);


                    HashMap<String, Object> mapSql = ObjectUtil.cloneHashMapStringAndObject();
                    mapSql.put("rejectTxt", "");
                    mapSql.put("status", map.get("status"));
                    mapSql.put("updatedAt", createdAt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    KylinPerformances performances = KylinPerformances.getNew();
                    performances.setAuditTime(LocalDateTime.now());
                    performances.setNoticeImage(kylinPerformanceMisVo.getNoticeImage());
                    performancesMapper.update(performances, Wrappers.lambdaQuery(KylinPerformances.class).eq(KylinPerformances::getPerformancesId, performanceId));
                    KylinPerformanceStatus performanceStatus = KylinPerformanceStatus.getNew();
                    performanceStatus.setAuditStatus((int) map.get("auditStatus"));
                    performanceStatus.setIsTrueName(step2Param.getIsTrueName());
                    performanceStatus.setLimitCount(step2Param.getLimitCount());
                    performanceStatusMapper.update(performanceStatus, Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performanceId));

                    dataUtils.setPerformanceIsTrueName(performanceId, step2Param.getIsTrueName());

                    //提示：票种价格、售票时间、票种购票限制 直接生效 (演出购票限制，购票须知 演出是否实名 票种缺货登记 票种是否电子票 票种是否快递票 票种最低购买张数 票种是否显示二维码)
                    List<TicketTimesTicketCreatePartnerVo> timeList = kylinPerformanceMisVo.getTicketTimes();
                    for (TicketTimesTicketCreatePartnerVo timesItem : timeList) {
                        List<KylinTicketPartnerVo> ticketList = timesItem.getTicket();
                        for (KylinTicketPartnerVo ticketItem : ticketList) {
                            //修改 redis库存
                            if (redisUtil.hasKey(KylinRedisConst.PERFORMANCES_INVENTORY + ticketItem.getTicketsId() + ":" + KylinRedisConst.SURPLUS_GENERAL)) {
                                KylinTicketStatus ticketStatus = ticketStatusMapper.selectOne(Wrappers.lambdaQuery(KylinTicketStatus.class).eq(KylinTicketStatus::getTicketId, ticketItem.getTicketsId()));
                                int changeGeneral = ticketItem.getTotalGeneral() - ticketStatus.getTotalGeneral();
                                int changeExchange = ticketItem.getTotalExchange() - ticketStatus.getTotalExchange();
                                log.debug("ticketItem.getTotalGeneral() = " + ticketItem.getTotalGeneral());
                                log.debug("ticketStatus.getTotalGeneral() = " + ticketStatus.getTotalGeneral());
                                dataUtils.changeSurplusGeneral(ticketItem.getTicketsId(), changeGeneral);
                                dataUtils.changeSurplusExchange(ticketItem.getTicketsId(), changeExchange);
                            }
                            //修改 mysql 库存
                            KylinTicketStatus inventory = KylinTicketStatus.getNew();
                            inventory.setTotalExchange(ticketItem.getTotalExchange());
                            inventory.setTotalGeneral(ticketItem.getTotalGeneral());
                            inventory.setIsTrueName(kylinPerformanceMisVo.getIsTrueName());
                            inventory.setLimitCount(ticketItem.getLimitCount());
                            inventory.setIsLackRegister(ticketItem.getIsLackRegister());
                            inventory.setIsExpress(ticketItem.getIsExpress());
                            inventory.setIsElectronic(ticketItem.getIsElectronic());
                            inventory.setCounts(ticketItem.getCounts());
                            inventory.setIsShowCode(ticketItem.getIsShowCode());
                            inventory.setMemberLimitCount(null);
                            inventory.setQrCodeShowTime(DateUtil.Formatter.yyyyMMddHHmmss.parse(ticketItem.getQrCodeShowTime()));

                            //修改 mysql 售卖时间
                            KylinTickets ticketSellTime = KylinTickets.getNew();
                            ticketSellTime.setTimeEnd(DateUtil.Formatter.yyyyMMddHHmmss.parse(ticketItem.getTimeEnd()));
                            ticketSellTime.setTimeStart(DateUtil.Formatter.yyyyMMddHHmmss.parse(ticketItem.getTimeStart()));
                            ticketSellTime.setAdvanceMinuteMember(null);
                            ticketSellTime.setTimeEndExpress(DateUtil.Formatter.yyyyMMddHHmmss.parse(ticketItem.getTimeEndExpress()));
                            ticketSellTime.setPayCountdownMinute(kylinPerformanceMisVo.getPayCountdownMinute());
                            //修改 价格
                            ticketSellTime.setPrice(ticketItem.getPrice());
                            ticketSellTime.setPriceDiscountMember(null);
                            ticketsMapper.update(ticketSellTime, Wrappers.lambdaQuery(KylinTickets.class).eq(KylinTickets::getTicketsId, ticketItem.getTicketsId()));
                            //修改 mysql 购票限购
                            ticketStatusMapper.update(inventory, Wrappers.lambdaQuery(KylinTicketStatus.class).eq(KylinTicketStatus::getTicketId, ticketItem.getTicketsId()));
                        }
                    }
                    performanceVoTask.performanceVoStatus(performanceId);
                }
                return ResponseDto.success("操作完成");
            } else { //保存
                map.put("status", 0);
                map.put("auditStatus", -1);
                BasicDBObject object = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(map));
                mongoTemplate.getCollection(PerformancePartnerVo.class.getSimpleName()).updateMany(
                        Query.query(Criteria.where("performancesId").is(performanceId)).getQueryObject(),
                        object
                );
                return ResponseDto.success("保存成功");
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info(UserPathDto.setPartnerData("0", "updateStep2", step2Param, e));
            return ResponseDto.failure(ErrorMapping.get(20115));
        }
    }

    @Override
    public ResponseDto<PerformanceStep2Param> getStep2(String performancesId) {
        PerformancePartnerVo data = mongoTemplate.findOne(
                Query.query(Criteria.where("performancesId").is(performancesId)), PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName()
        );
        if (data == null) {
            return ResponseDto.failure(ErrorMapping.get(20104));
        }
        List<KylinTicketTimesPartnerVo> kylinTicketTimesPartnerVos = ticketTimesPartnerService.getTimesMongoList(performancesId);
        List<TicketTimesTicketCreatePartnerVo> ticketTimesTicketCreatePartnerVoList = new ArrayList<TicketTimesTicketCreatePartnerVo>();

        for (KylinTicketTimesPartnerVo ticketTimes : kylinTicketTimesPartnerVos) {
            TicketTimesTicketCreatePartnerVo ticketTimesTicketCreatePartnerVo = TicketTimesTicketCreatePartnerVo.getNew();
            BeanUtils.copyProperties(ticketTimes, ticketTimesTicketCreatePartnerVo);
            List<KylinTicketPartnerVo> kylinTicketPartnerVos = ticketsPartnerService.getTicketMongoList(ticketTimes.getTicketTimesId());
            ticketTimesTicketCreatePartnerVo.setTicket(kylinTicketPartnerVos);
            ticketTimesTicketCreatePartnerVoList.add(ticketTimesTicketCreatePartnerVo);
        }

        PerformanceStep2Param performanceStep2Param = PerformanceStep2Param.getNew();
        BeanUtils.copyProperties(data, performanceStep2Param);
        KylinPerformanceStatus performanceStatus = performanceStatusMapper.selectOne(Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performancesId));
        if (null != performanceStatus) {
            performanceStep2Param.setStatus(performanceStatus.getStatus());
        } else {
            performanceStep2Param.setStatus(-1);
        }

        performanceStep2Param.setTicketTimes(ticketTimesTicketCreatePartnerVoList);
        log.info(UserPathDto.setPartnerData("0", "getStep2", "performancesId=" + performancesId, performanceStep2Param));
        return ResponseDto.success(performanceStep2Param);
    }

    @Override
    public ResponseDto<String> onLinePerformance(String performancesId) {
        try {
            KylinPerformanceStatus performanceStatusData = performanceStatusMapper.selectOne(Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performancesId));
            if (!(performanceStatusData.getStatus() == 3 || performanceStatusData.getStatus() == 7)) {
                return ResponseDto.failure(ErrorMapping.get(20110));
            }
            // mysql
            LocalDateTime updatedAt = LocalDateTime.now();
            KylinPerformanceStatus performanceStatusUpdate = KylinPerformanceStatus.getNew();
            performanceStatusUpdate.setStatus(6);
            performanceStatusUpdate.setUpdatedAt(updatedAt);
            performanceStatusMapper.update(performanceStatusUpdate
                    , Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performancesId));

            //场次
            List<KylinTicketTimeRelation> ticketTimeRelation = ticketTimeRelationMapper.selectList(
                    Wrappers.lambdaQuery(KylinTicketTimeRelation.class).eq(KylinTicketTimeRelation::getPerformanceId, performancesId)
            );


            for (KylinTicketTimeRelation ticketTimeRelationItem : ticketTimeRelation) {
                KylinTicketTimes ticketTimes = ticketTimesMapper.selectOne(Wrappers.lambdaQuery(KylinTicketTimes.class).eq(KylinTicketTimes::getTicketTimesId, ticketTimeRelationItem.getTimesId()).eq(KylinTicketTimes::getStatus, 1));
                //票
                List<KylinTicketRelations> ticketRelations = ticketRelationsMapper.selectList(Wrappers.lambdaQuery(KylinTicketRelations.class).eq(KylinTicketRelations::getTimesId, ticketTimes.getTicketTimesId()));
                for (KylinTicketRelations ticketRelationsItem : ticketRelations) {
                    KylinTicketStatus ticketStatusUpdate = KylinTicketStatus.getNew();
                    ticketStatusUpdate.setStatus(9);
                    ticketStatusUpdate.setUpdatedAt(updatedAt);
                    ticketStatusMapper.update(ticketStatusUpdate
                            , Wrappers.lambdaQuery(KylinTicketStatus.class).eq(KylinTicketStatus::getTicketId, ticketRelationsItem.getTicketId()).in(KylinTicketStatus::getStatus, 3, 6, 8, 9, 10));

                    HashMap<String, Object> map = ObjectUtil.cloneHashMapStringAndObject();
                    map.put("status", 9);
                    map.put("updatedAt", updatedAt);
                    mongoTemplate.getCollection(KylinTicketPartnerVo.class.getSimpleName()).updateOne(
                            Query.query(Criteria.where("ticketsId").is(ticketRelationsItem.getTicketId()).and("status").in(3, 6, 8, 9, 10)).getQueryObject(),
                            ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(map))
                    );
                }
            }
//            判断状态
            performanceVoTask.performanceVoStatus(performancesId);
            log.info(UserPathDto.setPartnerData("0", "onLinePerformance", "performancesId=" + performancesId, "上线成功"));
            return ResponseDto.success("上线成功");
        } catch (Exception e) {
            log.info(UserPathDto.setPartnerData("0", "onLinePerformance", "performancesId=" + performancesId, e));
            return ResponseDto.failure(ErrorMapping.get(20108));
        }
    }

    @Override
    public ResponseDto<String> outLinePerformance(String performancesId) {
        try {
            KylinPerformanceStatus performanceStatusData = performanceStatusMapper.selectOne(Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performancesId));

            if (performanceStatusData.getStatus() >= 3 && performanceStatusData.getStatus() != 4 && performanceStatusData.getStatus() != 7) {//未提审||被拒绝   && performanceStatusData.getStatus() != 10
                LocalDateTime updatedAt = LocalDateTime.now();
                KylinPerformanceStatus performanceStatus = KylinPerformanceStatus.getNew();
                performanceStatus.setStatus(7);
                performanceStatus.setUpdatedAt(updatedAt);
                performanceStatusMapper.update(performanceStatus
                        , Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performancesId));

                performanceVoTask.performanceVoStatus(performancesId);
                log.info(UserPathDto.setPartnerData("0", "outLinePerformance", "performancesId=" + performancesId, "下线成功"));
                return ResponseDto.success("下线成功");
            } else {
                return ResponseDto.failure(ErrorMapping.get(20111));
            }
        } catch (Exception e) {
            log.info(UserPathDto.setPartnerData("0", "outLinePerformance", "outLinePerformance=" + performancesId, e));
            return ResponseDto.failure(ErrorMapping.get(20109));
        }
    }

    @Override
    public String copyPerformance(String performancesId) {
        try {
            PerformancePartnerVo performancePartnerVo = mongoTemplate.findOne(Query.query(Criteria.where("performancesId").is(performancesId)), PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName());
            //复制演出
            performancePartnerVo.setPerformancesId(IDGenerator.nextSnowId().toString());
            performancePartnerVo.setStatus(0);
            performancePartnerVo.setAuditStatus(-1);
            performancePartnerVo.setIsCreateSave(1);
            mongoTemplate.insert(performancePartnerVo, PerformancePartnerVo.class.getSimpleName());

            List<KylinTicketTimesPartnerVo> kylinTicketTimesPartnerVos = mongoTemplate.find(Query.query(Criteria.where("performancesId").is(performancesId)), KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
            for (KylinTicketTimesPartnerVo timeItem : kylinTicketTimesPartnerVos) {
                //复制场次
                String timesId = timeItem.getTicketTimesId();
                timeItem.setTicketTimesId(IDGenerator.nextSnowId());
                timeItem.setPerformancesId(performancePartnerVo.getPerformancesId());
                mongoTemplate.insert(timeItem, KylinTicketTimesPartnerVo.class.getSimpleName());

                List<KylinTicketPartnerVo> kylinTicketPartnerVos = mongoTemplate.find(Query.query(Criteria.where("timesId").is(timesId)), KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
                for (KylinTicketPartnerVo ticketItem : kylinTicketPartnerVos) {
                    //复制票
                    ticketItem.setStatus(0);
                    ticketItem.setTimesId(timeItem.getTicketTimesId());
                    ticketItem.setTicketsId(IDGenerator.nextSnowId().toString());
                    mongoTemplate.insert(ticketItem, KylinTicketPartnerVo.class.getSimpleName());
                }
            }
            log.info(UserPathDto.setPartnerData("0", "copyPerformance", "performancesId=" + performancesId, performancePartnerVo.getPerformancesId()));
            return performancePartnerVo.getPerformancesId();
        } catch (Exception e) {
            e.printStackTrace();
            log.info(UserPathDto.setPartnerData("0", "copyPerformance", "performancesId=" + performancesId, e));
            return null;
        }
    }

    @Override
    public ResponseDto<PageInfo<PerformancePartnerListDao>> getList(PerformancePartnerListParam performancePartnerListParam) {
        int status = performancePartnerListParam.getStatus();
        int page = performancePartnerListParam.getPage() - 1;
        int size = performancePartnerListParam.getSize();
        PageInfo<PerformancePartnerListDao> pageInfoTmp = null;
        if (status == 0) {//未发布演出
            // 排序 分页
            Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
            //条件
            Criteria criteria = Criteria.where("status").is(status).and("isCreateSave").is(1).and("merchantId").is(performancePartnerListParam.getMerchantId());
            if (!performancePartnerListParam.getTitle().isEmpty()) {
                criteria.and("title").regex(".*?\\" + performancePartnerListParam.getTitle());
            }
            Query query = Query.query(criteria);
            // 查询总数
            long count = mongoTemplate.count(query, PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName());
            List<PerformancePartnerVo> performancePartnerVo = mongoTemplate.find(query, PerformancePartnerVo.class, PerformancePartnerVo.class.getSimpleName());
            query.with(pageable);
            //处理Vo
            List<KylinPerformancePartnerListVo> voList = new ArrayList<>();
            for (PerformancePartnerVo item : performancePartnerVo) {
                KylinPerformancePartnerListVo voData = KylinPerformancePartnerListVo.getNew();
                voData.setStatus0Data(item);
                voList.add(voData);
            }
            pageInfoTmp = new PageInfo(voList);
            pageInfoTmp.setTotal(count);
        } else {//演出列表
            try {
                PageHelper.startPage(performancePartnerListParam.getPage(), performancePartnerListParam.getSize());
                List<PerformancePartnerListDao> voList = performancesMapper.partnerPerformanceList(BeanUtil.convertBeanToMap(performancePartnerListParam));
                for (int i = 0; i < voList.size(); i++) {
                    PerformancePartnerListDao vo = voList.get(i);
                    if (vo.getStatus() >= 6 && vo.getStatus() != 7) {
                        if (DateUtil.compareStrDay(vo.getTimeSell(), DateUtil.getNowTime()) > 0) {//未开始
                            vo.setStatus(9);
                        } else if (DateUtil.compareStrDay(vo.getTimeStop(), DateUtil.getNowTime()) < 0) {//已结束
                            vo.setStatus(10);
                        } else {
                            vo.setStatus(6);
                        }
                    }
                }
                pageInfoTmp = new PageInfo(voList);
            } catch (Exception e) {
                e.printStackTrace();
                return ResponseDto.failure(ErrorMapping.get(20104));
            }
        }
        return ResponseDto.success(pageInfoTmp);
    }

    @Override
    public ResponseDto<String> withdraw(String performancesId) {
        try {
            KylinPerformanceStatus performanceStatus = performanceStatusMapper.selectOne(Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performancesId));
            if (performanceStatus != null && performanceStatus.getAuditStatus() == 0) {
                KylinPerformanceStatus data1 = KylinPerformanceStatus.getNew();
                HashMap<String, Object> map = ObjectUtil.cloneHashMapStringAndObject();
                if (performanceStatus.getStatus() >= 3) {//通过审核
                    data1.setAuditStatus(1);
                    data1.setStatus(null);
                    map.put("auditStatus", 1);
                } else if (performanceStatus.getStatus() == 4 || performanceStatus.getStatus() == 1) {//未通过审核
                    data1.setAuditStatus(-1);
                    data1.setStatus(0);
                    map.put("auditStatus", -1);
                    map.put("status", 0);
                } else {
                    data1.setAuditStatus(2);
                    data1.setStatus(null);
                    map.put("auditStatus", 2);
                }
                performanceStatusMapper.update(data1, Wrappers.lambdaQuery(KylinPerformanceStatus.class).eq(KylinPerformanceStatus::getPerformanceId, performancesId));
                BasicDBObject object = ObjectUtil.cloneBasicDBObject().append("$set", mongoConverter.convertToMongoType(map));
                mongoTemplate.getCollection(PerformancePartnerVo.class.getSimpleName()).updateOne(
                        Query.query(Criteria.where("performancesId").is(performancesId)).getQueryObject(),
                        object
                );
                log.info(UserPathDto.setPartnerData("0", "withdraw", "performancesId=" + performancesId, "撤回成功"));
                return ResponseDto.success("撤回成功");
            } else {
                return ResponseDto.failure(ErrorMapping.get(20116));
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info(UserPathDto.setPartnerData("0", "withdraw", performancesId, e));
            return ResponseDto.failure(ErrorMapping.get(20117));
        }
    }

    @Override
    public List<PerformanceOrderStatisticalVo> getPerformanceOrderStatisticalList(String performancesId) {
        PerformanceOrderStatisticalDao countBean = PerformanceOrderStatisticalDao.getNew();
        countBean.setTitle("总计：");

        List<PerformanceOrderStatisticalVo> voList = new ArrayList<>();
        List<PerformanceOrderStatisticalDao> dtoList = performancesMapper.getPerformanceOrderStatisticalList(performancesId);
        dtoList.forEach(dto -> {
            PerformanceOrderStatisticalVo vo = PerformanceOrderStatisticalVo.getNew();
            BeanUtil.copy(dto, vo);
            voList.add(vo);

            countBean.setTotalGeneral(countBean.getTotalGeneral().add(dto.getTotalGeneral()));
            countBean.setSaleGeneral(countBean.getSaleGeneral().add(dto.getSaleGeneral()));
            countBean.setSurplusGeneral(countBean.getSurplusGeneral().add(dto.getSurplusGeneral()));
            countBean.setTotalSalePrice(countBean.getTotalSalePrice().add(dto.getTotalSalePrice()));
            countBean.setTotalExchange(countBean.getTotalExchange().add(dto.getTotalExchange()));
            countBean.setTotalRefundGeneral(countBean.getTotalRefundGeneral().add(dto.getTotalRefundGeneral()));
            countBean.setTotalRefundPrice(countBean.getTotalRefundPrice().add(dto.getTotalRefundPrice()));
            countBean.setTotalMemberNumber(countBean.getTotalMemberNumber().add(dto.getTotalMemberNumber()));
            countBean.setTotalPayingNumber(countBean.getTotalPayingNumber().add(dto.getTotalPayingNumber()));
            countBean.setTotalBuyUsers(dto.getTotalBuyUsers());
        });
        PerformanceOrderStatisticalVo vo = PerformanceOrderStatisticalVo.getNew();
        BeanUtil.copy(countBean, vo);
        voList.add(vo);
        return voList;
    }
}
