package com.liquidnet.service.kylin.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.liquidnet.commons.lang.CommonConst;
import com.liquidnet.commons.lang.util.*;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.base.UserPathDto;
import com.liquidnet.service.base.constant.MQConst;
import com.liquidnet.service.goblin.dto.vo.SmileUserVO;
import com.liquidnet.service.kylin.constant.KylinPerformanceStatusEnum;
import com.liquidnet.service.kylin.constant.KylinTableStatusConst;
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.KylinCandyVo;
import com.liquidnet.service.kylin.dto.vo.mongo.KylinPerformanceVo;
import com.liquidnet.service.kylin.dto.vo.partner.KylinTicketExpressModuleVo;
import com.liquidnet.service.kylin.dto.vo.partner.KylinTicketPartnerVo;
import com.liquidnet.service.kylin.dto.vo.partner.KylinTicketTimesPartnerVo;
import com.liquidnet.service.kylin.dto.vo.returns.PayDetailVo;
import com.liquidnet.service.kylin.service.IKylinPerformancesService;
import com.liquidnet.service.kylin.utils.DataUtils;
import com.liquidnet.service.kylin.utils.ObjectUtil;
import com.liquidnet.service.kylin.utils.QueueUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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.query.BasicQuery;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端 演出 服务实现类
 * </p>
 *
 * @author jiangxiulong
 * @since 2021-05-11
 */
@Service
@Slf4j
public class KylinPerformancesServiceImpl implements IKylinPerformancesService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private DataUtils dataUtils;
    @Autowired
    private QueueUtils queueUtils;

    @Value("${liquidnet.service.smile.url}")
    private String smileUrl;

    public HashMap<String, Object> localList(
            int days, String cityName, Integer adCode, int type,
            Integer isDiscount, Integer isAdvance, Integer isExclusive,
            String orderBy, String sort
    ) {
        List<KylinPerformanceVo> performancesList = dataUtils.getPerformancesListOfcityNameOradCode(cityName, adCode);

        // 是否启用推荐
        Integer isRecommend = 1;

        // 判断搜索 处理新数据
        List<KylinPerformanceVo> performancesListNew = ObjectUtil.getKylinPerformanceVoArrayList();
        List<String> performancesIds = CollectionUtil.arrayListString();
        for (KylinPerformanceVo info : performancesList) {
            boolean isShow = true;
            if (type > 0) {
                isRecommend = 0;
                if (info.getType() != type) {
                    isShow = false;
                }
            }
            if (null != isExclusive || null != isDiscount || null != isAdvance) {
                isRecommend = 0;
                if (info.getIsExclusive() != isExclusive && info.getIsDiscount() != isDiscount && info.getIsAdvance() != isAdvance) {
                    isShow = false;
                }
            }
            if (days > 0) {
                isRecommend = 0;

                HashMap toDayTime = DateUtil.oneDayStartEnd();
                String nowTimeTStr = (String) toDayTime.get("startStr");

                String timeStart = info.getTimeStart();

                // 今天的0点到几天后的0点
                Calendar cal = Calendar.getInstance();
                cal.setTime((Date) toDayTime.get("start"));
                Date beforeDayEnd = DateUtil.getBeforeDayBegin(cal, days);
                String daysLaterStr = DateUtil.SDF_YMD_HMS.format(beforeDayEnd);
                if (-1 == DateUtil.compareStrDay(timeStart, nowTimeTStr) || -1 == DateUtil.compareStrDay(daysLaterStr, timeStart)) {
                    isShow = false;
                }
            }
            if (isShow) {
                performancesIds.add(info.getPerformancesId());
                performancesListNew.add(info);
            }
        }


        // 推荐
        int is_native = 1;
        int recommend = performancesListNew.size();
        if (recommend <= 2 && 1 == isRecommend) {
            List<KylinPerformanceVo> performancesListRecommend = dataUtils.getPerformancesListIsSystemRecommend();

            if (!CollectionUtils.isEmpty(performancesListRecommend)) {
                is_native = 0;
                if (recommend > 0) {// 去重
                    List<KylinPerformanceVo> collect = performancesListRecommend.stream().filter(r -> !performancesIds.contains(r.getPerformancesId())).collect(Collectors.toList());
                    performancesListNew.addAll(collect);
                } else {
                    performancesListNew.addAll(performancesListRecommend);
                }
            }
        }
        performancesListNew = checkAppStatus(performancesListNew);

        // 组合数据
        HashMap<String, Object> info = CollectionUtil.mapStringObject();
        info.put("is_native", is_native); // 本地演出少是否推荐了其他演出 0有推荐 1没有
        info.put("recommend", recommend); // 从第几个开始是其他推荐演出 后台设置的那个推荐
        info.put("total", 0);
        info.put("list", performancesListNew);

        log.info(UserPathDto.setData("本地演出列表", "cityName=" + cityName + " type=" + type + " isDiscount=" + isDiscount + " isAdvance =" + isAdvance + " isExclusive=" + isExclusive + " days=" + days, info));
        return info;
    }

    public HashMap<String, Object> noticeList(Integer type) {
        /*if (-1 != DateUtil.compareStrDay(timeStart, toDayEndTimeStr) && -1 == DateUtil.compareStrDay(timeStart, threeDaysLaterStr)) {
            threeDaysList.add(info);
        }*/
        HashMap<String, Object> performancesListNotice = dataUtils.getPerformancesListNotice();
        List<KylinPerformanceVo> toDayList = (List<KylinPerformanceVo>) performancesListNotice.get("toDayList");
        List<KylinPerformanceVo> threeDaysList = (List<KylinPerformanceVo>) performancesListNotice.get("threeDaysList");

        toDayList = checkAppStatus(toDayList);
        threeDaysList = checkAppStatus(threeDaysList);
        if (null != type && type > 0) {
            toDayList = mergeRoadList(toDayList);
            threeDaysList = mergeRoadList(threeDaysList);
        }

        HashMap<String, Object> newList = CollectionUtil.mapStringObject();
        newList.put("toDayList", toDayList);
        newList.put("threeDaysList", threeDaysList);
        return newList;
    }

    private List<KylinPerformanceVo> mergeRoadList(List<KylinPerformanceVo> performanceList) {
        List<String> roadIdList = new ArrayList<>();
        List<KylinPerformanceVo> newList = ObjectUtil.getKylinPerformanceVoArrayList();
        for (KylinPerformanceVo info : performanceList) {
            String roadShowId = info.getRoadShowId();
            if (null != roadShowId && !roadShowId.isEmpty() && !roadShowId.equals("0")) {
                if (!roadIdList.contains(info.getRoadShowId())) {
                    newList.add(info);
                    roadIdList.add(roadShowId);
                }
            } else if (roadShowId.equals("0")) {
                newList.add(info);
            }
        }
        return newList;
    }

    public List<KylinPerformanceVo> recommendList() {
        List<KylinPerformanceVo> performancesListRecommend = dataUtils.getPerformancesListIsRecommend();
        performancesListRecommend = checkAppStatus(performancesListRecommend);
        return performancesListRecommend;
    }

    public List<KylinPerformanceVo> exclusiveList() {
        List<KylinPerformanceVo> performancesListExclusive = dataUtils.getPerformancesListIsExclusive();
        performancesListExclusive = checkAppStatus(performancesListExclusive);
        return performancesListExclusive;
    }

    public KylinPerformanceVo detail(String performancesId, double latitudeFrom, double longitudeFrom, String agentId) {
        KylinPerformanceVo performancesInfo = dataUtils.getPerformanceVo(performancesId);
        if (null == performancesInfo) {
            return null;
        }

        if (StringUtil.isNotEmpty(agentId)) {
            try {
                MultiValueMap<String, String> params = new LinkedMultiValueMap();
                params.add("userId", agentId);
                MultiValueMap<String, String> headers = CollectionUtil.linkedMultiValueMapStringString();
                headers.add("Accept", "application/json;charset=UTF-8");
                String returnData = HttpUtil.post(smileUrl + "/smile/frontNoLogin/getUserById", params, headers);
                ResponseDto<SmileUserVO> responseDto = JsonUtils.fromJson(returnData, new TypeReference<ResponseDto<SmileUserVO>>() {
                });
                String agentName = responseDto.getData().getName();
                performancesInfo.setAgentName(agentName);
            } catch (Exception e) {
                log.error("演出详情 获取小家伙名称异常 eMsg:{}", e.getMessage());
                performancesInfo.setAgentName("");
            }
        }

        try {
            performancesInfo = checkAppStatusInfo(performancesInfo);
            performancesInfo.setMessage(KylinPerformanceStatusEnum.getName(performancesInfo.getAppStatus()));
        } catch (Exception e) {
            log.error(" ERROR PERFORMANCE DETAILS PERFORMANCE_ID : " + performancesId);
        }

        // 处理距离
        if (longitudeFrom != CommonConst.DFT_DOUBLE_VAL) {
            try {
                String diffDistance = DistanceUtil.getDistance(longitudeFrom, latitudeFrom, Double.parseDouble(performancesInfo.getLongitude()), Double.parseDouble(performancesInfo.getLatitude()));
                performancesInfo.setDiffDistance(diffDistance);
            } catch (Exception e) {
                log.error("演出详情 经纬度处理距离异常 e:{}", e);
            }
        }

        log.info(UserPathDto.setData("演出详情", "performancesId=" + performancesId + " latitudeFrom=" + latitudeFrom + " longitudeFrom=" + longitudeFrom, performancesInfo));
        return performancesInfo;
    }

    public List<KylinPerformanceVo> roadList(String roadShowId) {
        List<KylinPerformanceVo> performancesList = dataUtils.getRoadList(roadShowId);
        performancesList = checkAppStatusRoad(performancesList);
        return performancesList;
    }

    public HashMap<String, Object> ticketTimesPartner(String performancesId, Integer isAgent) {
        KylinPerformanceVo vo = dataUtils.getPerformanceVo(performancesId);
        if (null == vo) {
            return null;
        }
        vo = checkAppStatusInfo(vo);
        queueUtils.pushPvUv(CurrentUtil.getCurrentUid(), KylinTableStatusConst.PvUv.TK_TICKET.getKey(), performancesId, null, null, CurrentUtil.getCliIpAddr());
        List<KylinTicketTimesVo> ticketTimesList = vo.getTicketTimeList();
        if (null != ticketTimesList) {

            for (int i = 0; i < ticketTimesList.size(); i++) {
                KylinTicketTimesVo partner = ticketTimesList.get(i);
                List<KylinTicketVo> ticketList = partner.getTicketList();
                List<KylinTicketVo> ticketListNew = ObjectUtil.getKylinTicketVoArrayList();
                for (KylinTicketVo ticket : ticketList) {
                    int status = checkTicketStatus(ticket);
                    ticket.setStatus(status);

                    int statusExchange = checkTicketStatusExchange(ticket);
                    ticket.setStatusExchange(statusExchange);

                    // 会员状态
                    Integer isMemberStatus = getIsMemberStatus(ticket);
                    ticket.setIsMemberStatus(isMemberStatus);
                    if (null == isAgent || 0 == isAgent) {
                        ticketListNew.add(ticket);
                    } else if (1 >= isAgent) {
                        if (1 == ticket.getIsAgent()) {
                            ticketListNew.add(ticket);
                        }
                    }
                }
                partner.setTicketList(ticketListNew);
                if (ticketListNew.size() == 0) {
                    ticketTimesList.remove(i);
                    i--;
                }
            }
        }

        KylinPerformanceVo performancesInfo = dataUtils.getPerformanceVo(performancesId);
        HashMap<String, Object> info = CollectionUtil.mapStringObject();
        info.put("city_name", performancesInfo.getCityName());
        info.put("field_name", performancesInfo.getFieldName());
        info.put("title", performancesInfo.getTitle());
        info.put("appStatus", performancesInfo.getAppStatus());

        HashMap<String, Object> result = CollectionUtil.mapStringObject();
        result.put("performancesInfo", info);
        result.put("ticketTimesList", ticketTimesList);

        return result;
    }

    public List<KylinPerformanceVo> performanceList(String... performancesIds) {
        List<KylinPerformanceVo> performanceList = ObjectUtil.getKylinPerformanceVoArrayList();
        for (String id : performancesIds) {
            KylinPerformanceVo info = dataUtils.getPerformanceVo(id);
            performanceList.add(info);
        }
        performanceList = checkAppStatus(performanceList);
        return performanceList;
    }

    public List performanceCalendar(String yearMonth, String cityName, Integer adCode) {
        List<KylinPerformanceVo> performancesList = dataUtils.getPerformancesListOfcityNameOradCode(cityName, adCode);

        // 获取此月开始结束时间
        String[] split = yearMonth.split("-");
        String monthStart = "";
        if (split.length > 2) {
            monthStart = DateUtil.getMonthFirst(split[0].concat("-").concat(split[1]));
        } else {
            monthStart = DateUtil.getMonthFirst(yearMonth);
        }
        String monthEnd = "";
        monthEnd = DateUtil.getMonthLast(monthStart);

        List date = new ArrayList();
        for (KylinPerformanceVo info : performancesList) {
            String timeStart = info.getTimeStart();
            if (-1 != DateUtil.compareStrDay(timeStart, monthStart) && 1 != DateUtil.compareStrDay(timeStart, monthEnd)) {
                String[] timeStartArr = timeStart.split(" ");
                date.add(timeStartArr[0]);
            }
        }
        //  去重
        List newList = (List) date.stream().distinct().collect(Collectors.toList());

        return newList;
    }

    public List calendarPerformances(String yearMonthDay, String cityName, Integer adCode) {
        List<KylinPerformanceVo> performancesList = dataUtils.getPerformancesListOfcityNameOradCode(cityName, adCode);

        String yearMonthDayStart = yearMonthDay.concat(" 00:00:00");
        String yearMonthDayEnd = yearMonthDay.concat(" 23:59:59");

        List<KylinPerformanceVo> performancesListNew = ObjectUtil.getKylinPerformanceVoArrayList();
        for (KylinPerformanceVo info : performancesList) {
            String timeStart = info.getTimeStart();
            if (-1 != DateUtil.compareStrDay(timeStart, yearMonthDayStart) && 1 != DateUtil.compareStrDay(timeStart, yearMonthDayEnd)) {
                performancesListNew.add(info);
            }
        }

        performancesListNew = checkAppStatus(performancesListNew);

        return performancesListNew;
    }

    public HashMap performancesSearch(String title, int page, int size) {
        Document queryObject = new Document();
        queryObject.put("title", Pattern.compile(title, Pattern.CASE_INSENSITIVE));
        Query query = new BasicQuery(queryObject);
        /*String nowTimeStr = DateUtil.getNowTime();
        query.addCriteria(Criteria.where("timeEnd").gte(nowTimeStr));*/
        query.addCriteria(Criteria.where("appStatus").in(6, 8, 9, 10));
        query.addCriteria(Criteria.where("isShow").is(1));

        long count = mongoTemplate.count(query, KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());

        query.fields().exclude("details");
        query.fields().exclude("noticeImage");
        query.fields().exclude("ticketTimeList");

        Sort sortName = Sort.by(Sort.Direction.DESC, "timeStart");
        Pageable pageable = PageRequest.of(page - 1, size, sortName);
        query.with(pageable);

        List<KylinPerformanceVo> list = mongoTemplate.find(query, KylinPerformanceVo.class, KylinPerformanceVo.class.getSimpleName());

        // 这里不需要剔除一些数据 所以不能调用公共方法 可优化
        if (!CollectionUtils.isEmpty(list)) {
            String nowTimeStr = DateUtil.getNowTime();
            for (KylinPerformanceVo info : list) {
                // 当前时间大于停售时间 小于结束时间 是 停售
                String stopSellTime = info.getStopSellTime();
                String timeEnd = info.getTimeEnd();
                Integer isEnd = DateUtil.compareStrDay(nowTimeStr, timeEnd);
                if (1 == DateUtil.compareStrDay(nowTimeStr, stopSellTime) && -1 == DateUtil.compareStrDay(nowTimeStr, timeEnd)) {
                    info.setAppStatus(11);
                }

                // 票状态 3预览 6票可购买 8售罄 9未开始 10结束 11停售
                if (3 != info.getAppStatus() && info.getAppStatus() != 8 && info.getAppStatus() != 11 && 7 != info.getAppStatus() && 1 != isEnd) { // 个别状态无需再判断
                    String sellTime = info.getSellTime();
                    if (1 == DateUtil.compareStrDay(sellTime, nowTimeStr)) {// 未开始
                        info.setAppStatus(9);
                        int isMemberStatus = getPerformanceIsMemberStatus(info);
                        if (1 == isMemberStatus) {
                            info.setAppStatus(6);
                        }
                    } else { // 已开始
                        info.setAppStatus(6);
                        if (1 == DateUtil.compareStrDay(nowTimeStr, timeEnd)) { // 演出已结束
                            info.setAppStatus(10);
                        }
                    }
                }
            }
        }

        HashMap<String, Object> info = CollectionUtil.mapStringObject();
        info.put("total", count);
        info.put("list", list);

        log.info(UserPathDto.setData("演出搜索", "title=" + title + " page=" + page + " size=" + size, info));
        return info;
    }

    public PayDetailVo payDetail(String performancesId, String ticketsId) {
        KylinTicketVo ticketVo = null;
        KylinPerformanceVo performancesInfo = dataUtils.getPerformanceVo(performancesId);
        if (null == performancesInfo) {
            return null;
        }
        performancesInfo = checkAppStatusInfo(performancesInfo);
        queueUtils.pushPvUv(CurrentUtil.getCurrentUid(), KylinTableStatusConst.PvUv.TK_ORDER.getKey(), performancesId, null, null, CurrentUtil.getCliIpAddr());
        for (int i = 0; i < performancesInfo.getTicketTimeList().size(); i++) {
            for (int x = 0; x < performancesInfo.getTicketTimeList().get(i).getTicketList().size(); x++) {
                KylinTicketVo ticketItem = performancesInfo.getTicketTimeList().get(i).getTicketList().get(x);
                if (ticketItem.getTicketsId().equals(ticketsId)) {
                    int status = checkTicketStatus(ticketItem);
                    ticketItem.setStatus(status);
                    int statusExchange = checkTicketStatusExchange(ticketItem);
                    ticketItem.setStatusExchange(statusExchange);
                    ticketVo = ticketItem;
                    Integer isMemberStatus = getIsMemberStatus(ticketItem);
                    ticketItem.setIsMemberStatus(isMemberStatus);
                }
            }
        }

        performancesInfo.setMessage(KylinPerformanceStatusEnum.getName(performancesInfo.getAppStatus()));

        PayDetailVo payDetailVo = new PayDetailVo();
        if (ticketVo.getIsExpress() == 1) {
            KylinTicketExpressModuleVo expressModuleVo = dataUtils.getTEMVo(ticketsId);
            payDetailVo.setExpressModuleList(expressModuleVo == null ? null : expressModuleVo.getProduceCodeList());
        } else {
            payDetailVo.setExpressModuleList(null);
        }
        payDetailVo.setPerformanceInfo(performancesInfo);
        payDetailVo.setTicketInfo(ticketVo);

        log.info(UserPathDto.setData("预支付演出票种详情", "performancesId=" + performancesId + " ticketsId=" + ticketsId, payDetailVo));
        return payDetailVo;
    }

    public List<KylinPerformanceVo> checkAppStatus(List<KylinPerformanceVo> list) {
        List<KylinPerformanceVo> newList = ObjectUtil.getKylinPerformanceVoArrayList();
        if (!CollectionUtils.isEmpty(list)) {
            String nowTimeStr = DateUtil.getNowTime();
            for (KylinPerformanceVo info : list) {
                // 当前时间大于停售时间 小于结束时间 是 停售
                String stopSellTime = info.getStopSellTime();
                String timeEnd = info.getTimeEnd();
                Integer isEnd = DateUtil.compareStrDay(nowTimeStr, timeEnd);
                if (1 == DateUtil.compareStrDay(nowTimeStr, stopSellTime) && -1 == DateUtil.compareStrDay(nowTimeStr, timeEnd) && 7 != info.getAppStatus()) {
                    info.setAppStatus(11);
                }

                // 票状态 6票可购买 8售罄 9未开始 10结束 11停售
                if (3 != info.getAppStatus() && 7 != info.getAppStatus() && 1 != isEnd) { // 演出已结束、未上线 不展示
                    String sellTime = info.getSellTime();
                    if (1 == DateUtil.compareStrDay(sellTime, nowTimeStr)) {// 未开始
                        info.setAppStatus(9);
                        int isMemberStatus = getPerformanceIsMemberStatus(info);
                        if (1 == isMemberStatus) {
                            info.setAppStatus(6);
                        }
                    } else { // 已开始
                        info.setAppStatus(6);
                        if (1 == DateUtil.compareStrDay(nowTimeStr, timeEnd)) { // 演出已结束
                            info.setAppStatus(10);
                        }
                    }
                    newList.add(info);
                }
            }
        }
        return newList;
    }

    public List<KylinPerformanceVo> checkAppStatusRoad(List<KylinPerformanceVo> list) {
        List<KylinPerformanceVo> newList = ObjectUtil.getKylinPerformanceVoArrayList();
        if (!CollectionUtils.isEmpty(list)) {
            String nowTimeStr = DateUtil.getNowTime();
            for (KylinPerformanceVo info : list) {
                // 当前时间大于停售时间 小于结束时间 是 停售
                String stopSellTime = info.getStopSellTime();
                String timeEnd = info.getTimeEnd();
                Integer isEnd = DateUtil.compareStrDay(nowTimeStr, timeEnd);
                if (1 == DateUtil.compareStrDay(nowTimeStr, stopSellTime) && -1 == DateUtil.compareStrDay(nowTimeStr, timeEnd) && 7 != info.getAppStatus()) {
                    info.setAppStatus(11);
                }

                // 票状态 6票可购买 8售罄 9未开始 10结束 11停售
//                if (3 != info.getAppStatus() && 7 != info.getAppStatus() && 1 != isEnd) { // 演出已结束、未上线 不展示
                if (3 != info.getAppStatus() && 7 != info.getAppStatus()) { // 演出已结束、未上线 不展示
                    String sellTime = info.getSellTime();
                    if (1 == DateUtil.compareStrDay(sellTime, nowTimeStr)) {// 未开始
                        info.setAppStatus(9);
                        int isMemberStatus = getPerformanceIsMemberStatus(info);
                        if (1 == isMemberStatus) {
                            info.setAppStatus(6);
                        }
                    } else { // 已开始
                        info.setAppStatus(6);
                        if (1 == DateUtil.compareStrDay(nowTimeStr, timeEnd)) { // 演出已结束
                            info.setAppStatus(10);
                        }
                    }
                    newList.add(info);
                }
            }
        }
        return newList;
    }

    public KylinPerformanceVo checkAppStatusInfo(KylinPerformanceVo info) {
        if (null != info) {
            if (info.getAppStatus() == 0 || info.getAppStatus() == 1) {
                info.setAppStatus(3);
            }
            List<KylinTicketTimesVo> ticketTimeList = info.getTicketTimeList();
            List<KylinTicketTimesVo> ticketTimeListNew = ObjectUtil.getKylinTicketTimesVoArrayList();
            for (KylinTicketTimesVo ticketTime : ticketTimeList) {
                List<KylinTicketVo> ticketList = ticketTime.getTicketList();
                List<KylinTicketVo> ticketListNew = ObjectUtil.getKylinTicketVoArrayList();
                for (KylinTicketVo ticket : ticketList) {
                    int status = checkTicketStatus(ticket);
                    ticket.setStatus(status);
                    // 会员状态
                    Integer isMemberStatus = getIsMemberStatus(ticket);
                    ticket.setIsMemberStatus(isMemberStatus);
                    if (ticket.getStatus() != 7) {
                        ticketListNew.add(ticket);
                    }
                }
                if (!CollectionUtils.isEmpty(ticketListNew)) {
                    ticketTime.setTicketList(ticketListNew);
                    ticketTimeListNew.add(ticketTime);
                }
            }
            info.setTicketTimeList(ticketTimeListNew);

            if (CollectionUtils.isEmpty(ticketTimeListNew) && 7 != info.getAppStatus()) { //列表的时候无需判断 因为列表不展示状态标签
                info.setAppStatus(11); // 所有票种下架 演出停售
            }
            // 当前时间大于停售时间 小于结束时间 是 停售
            String nowTimeStr = DateUtil.getNowTime();
            String stopSellTime = info.getStopSellTime();
            String timeEnd = info.getTimeEnd();
            if (1 == DateUtil.compareStrDay(nowTimeStr, stopSellTime) && -1 == DateUtil.compareStrDay(nowTimeStr, timeEnd) && 7 != info.getAppStatus()) {
                info.setAppStatus(11);
            }

            // 票状态 6票可购买 8售罄 9未开始 10结束 11停售
            if (3 != info.getAppStatus() && info.getAppStatus() != 8 && info.getAppStatus() != 11 && 7 != info.getAppStatus()) { // 个别状态无需再判断
                String sellTime = info.getSellTime();
                if (1 == DateUtil.compareStrDay(sellTime, nowTimeStr)) {// 未开始
                    info.setAppStatus(9);
                    int isMemberStatus = getPerformanceIsMemberStatus(info);
                    if (1 == isMemberStatus) {
                        info.setAppStatus(6);
                    }
                } else { // 已开始
                    info.setAppStatus(6);
                    if (1 == DateUtil.compareStrDay(nowTimeStr, timeEnd)) { // 演出已结束
                        info.setAppStatus(10);
                    }
                }
            }
        }
        return info;
    }

    public int checkTicketStatus(KylinTicketVo ticketItem) {
        // 3审核通过;4审核未通过;6在售;7停售;8售罄;9未开始;10已结束
        int getStatus = ticketItem.getStatus();
        int status = getStatus;

        if (getStatus == 8) {
            getStatus = 6;
        }
        boolean isSellOut = dataUtils.ticketIsSoldOut(ticketItem.getTicketsId());
        if (isSellOut && getStatus != 7) {
            status = 8;
            getStatus = 8;
        }
        if (null != ticketItem) {
            // 判断售罄
            if (6 == getStatus || 9 == getStatus || 10 == getStatus) {
                String timeStart = ticketItem.getTimeStart();
                String timeEnd = ticketItem.getTimeEnd();
                String nowTime = DateUtil.getNowTime();

                if (1 == DateUtil.compareStrDay(timeStart, nowTime)) {// 未开始
                    status = 9;
                } else { // 已开始
                    status = 6;
                    if (1 == DateUtil.compareStrDay(nowTime, timeEnd)) { // 已结束
                        status = 10;
                    }
                }
            }
        }
        return status;
    }

    public int checkTicketStatusExchange(KylinTicketVo ticketItem) {
        int statusExchange;
        int surplusExchange = dataUtils.getSurplusExchange(ticketItem.getTicketsId());

        String timeStart = ticketItem.getTimeStart();
        String timeEnd = ticketItem.getTimeEnd();
        String nowTime = DateUtil.getNowTime();

        if (1 == DateUtil.compareStrDay(timeStart, nowTime)) {// 未开始
            statusExchange = 7;
        } else { // 已开始
            statusExchange = surplusExchange > 0 ? 6 : 7;
            if (1 == DateUtil.compareStrDay(nowTime, timeEnd)) { // 已结束
                statusExchange = 7;
            }
        }
        return statusExchange;
    }

    public Integer getIsMemberStatus(KylinTicketVo ticket) {// 会员状态
        Integer isMemberStatus = 0;
        if (null != ticket) {
            if (1 == ticket.getIsMember()) { // 有会员
                String memberTimeStart = ticket.getMemberTimeStart();
                String nowTime = DateUtil.getNowTime();
                if (1 == DateUtil.compareStrDay(memberTimeStart, nowTime)) { // 还没到会员购买时间
                    isMemberStatus = 0;
                } else { // 可以购买
                    isMemberStatus = 1;
                }
            } else {
                isMemberStatus = 0;
            }
        }
        return isMemberStatus;
    }

    public Integer getPerformanceIsMemberStatus(KylinPerformanceVo info) {// 会员状态
        Integer isMemberStatus = 0;
        if (null != info) {
            if (1 == info.getIsMember()) { // 有会员
                String memberTimeStart = info.getSellMemberTime();
                String nowTime = DateUtil.getNowTime();
                if (1 == DateUtil.compareStrDay(memberTimeStart, nowTime)) { // 还没到会员购买时间
                    isMemberStatus = 0;
                } else { // 可以购买
                    isMemberStatus = 1;
                }
            } else {
                isMemberStatus = 0;
            }
        }
        return isMemberStatus;
    }

    /**
     * 获取我的已购票演出列表
     *
     * @return
     */
    public List<KylinPerformanceVo> myPerformancesList() {
        String userId = CurrentUtil.getCurrentUid();
        List<KylinPerformanceVo> performanceVoList = dataUtils.myPerformancesList(userId);
        return performanceVoList;
    }

    @Override
    public ResponseDto<String> getPerformanceIdByInfo(Integer useScope, String busiId) {
        if (useScope.equals(91)) {//场次
            List<KylinTicketTimesPartnerVo> voTimes = mongoTemplate.find(Query.query(Criteria.where("ticketTimesId").is(busiId)),
                    KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
            if (voTimes.size() <= 0) {
                return ResponseDto.failure();
            } else {
                return ResponseDto.success(voTimes.get(0).getPerformancesId());
            }
        } else if (useScope.equals(92)) {//票
            List<KylinTicketPartnerVo> voTickets = mongoTemplate.find(Query.query(Criteria.where("ticketsId").is(busiId)),
                    KylinTicketPartnerVo.class, KylinTicketPartnerVo.class.getSimpleName());
            if (voTickets.size() <= 0) {
                return ResponseDto.failure();
            } else {
                List<KylinTicketTimesPartnerVo> voTimes = mongoTemplate.find(Query.query(Criteria.where("ticketTimesId").is(voTickets.get(0).getTimesId())),
                        KylinTicketTimesPartnerVo.class, KylinTicketTimesPartnerVo.class.getSimpleName());
                if (voTimes.size() <= 0) {
                    return ResponseDto.failure();
                } else {
                    return ResponseDto.success(voTimes.get(0).getPerformancesId());
                }
            }
        } else {
            return ResponseDto.failure();
        }
    }

    @Override
    public ResponseDto<String> subscribe(String performancesId, Integer sourceType) {
        try {
            Map claims = CurrentUtil.getTokenClaims();
            String uid = StringUtils.defaultString(((String) claims.get(CurrentUtil.TOKEN_SUB)), "");
            String nickname = StringUtils.defaultString(((String) claims.get(CurrentUtil.TOKEN_NICKNAME)), "");
            String mobile = StringUtils.defaultString(((String) claims.get(CurrentUtil.TOKEN_MOBILE)), "");
            queueUtils.sendMsgByRedis(
                    MQConst.KylinQueue.SQL_PERFORMANCE_LACK.getKey(),
                    SqlMapping.get(
                            "kylin_perform_sub.insert",
                            new Object[]{
                                    IDGenerator.nextSnowId(), performancesId, uid, nickname, mobile, sourceType
                            }
                    ));
            dataUtils.setSubscribe(uid, performancesId);
            return ResponseDto.success("预约成功");
        } catch (Exception e) {
            log.error("演出预约 [performancesId:{}, uid:{}, e:{}]", performancesId, CurrentUtil.getCurrentUid(), e);
            return ResponseDto.success("预约失败");
        }
    }

    @Override
    public ResponseDto<Integer> isSubscribe(String performancesId) {
        String uid = CurrentUtil.getCurrentUid();
        Integer subscribe = dataUtils.getSubscribe(uid, performancesId);
        return ResponseDto.success(subscribe);
    }

    @Override
    public ResponseDto<List<KylinCandyVo>> kylinCandy(List<String> data, String roadShowId) {
        List<KylinCandyVo> voList = ObjectUtil.kylinCandyVos();
        for (String couponId : data) {
            List<String> roadShowIds = dataUtils.getCouponRoad(couponId);
            if (roadShowIds.size() == 0 || roadShowIds.contains(roadShowId)) {
                KylinCandyVo vo = KylinCandyVo.getNew();
                vo.setCouponId(couponId);
                vo.setRoadShowId(roadShowIds.contains(roadShowId) ? roadShowId : "");
                voList.add(vo);
            }
        }

        return ResponseDto.success(voList);
    }
}
