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

import com.liquidnet.common.cache.redis.util.RedisUtil;
import com.liquidnet.service.kylin.constant.KylinRedisConst;
import com.liquidnet.service.kylin.dto.vo.PerformanceVo;
import com.liquidnet.service.kylin.entity.KylinPerformances;
import com.liquidnet.service.kylin.mapper.KylinPerformancesMapper;
import com.liquidnet.service.kylin.service.IKylinPerformancesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.bson.Document;
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.query.BasicQuery;
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;
import java.util.regex.Pattern;

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

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    RedisUtil redisUtil;

    public HashMap<String, Object> localList(
            String timeStart, int days, String title, String cityName, int type,
            Integer isDiscount, Integer isAdvance, Integer isExclusive,
            int page, int size,
            String orderBy, String sort
    ) {
        HashMap<String, Object> info = new HashMap<>();

        // 排序 分页
        Sort sortName = null; // 默认开票越早的在上面
        if (sort.equals("DESC")) {
            if (!orderBy.isEmpty()) {
                sortName = Sort.by(Sort.Direction.DESC, orderBy);
            }
        } else if (sort.equals("ASC")) {
            if (!orderBy.isEmpty()) {
                sortName = Sort.by(Sort.Direction.ASC, orderBy);
            }
        } else {
            sortName = Sort.by(Sort.Direction.ASC, "timeStart");
        }

        Pageable pageable = PageRequest.of(page - 1, size, sortName);

        //条件
        Document queryObject = new Document();

        if (!title.isEmpty()) {
            queryObject.put("title", Pattern.compile(title, Pattern.CASE_INSENSITIVE));
        }
        if (type > 0) {
            queryObject.put("type", type);
        }
        if (isExclusive != null) {
            queryObject.put("isExclusive", isExclusive);
        }
        if (isDiscount != null) {
            queryObject.put("isDiscount", isDiscount);
        }
        if (isAdvance != null) {
            queryObject.put("isAdvance", isAdvance);
        }

        Query query = new BasicQuery(queryObject);
        if (!timeStart.isEmpty()) {
            String timeStartEnd = timeStart + " 23:59:59";
            query.addCriteria(Criteria.where("timeStart").gte(timeStart).lte(timeStartEnd));
        }
        if (days > 0) {
            LocalDateTime nowTime = LocalDateTime.now();
            String nowTimeStr = nowTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            LocalDateTime OtherTime = nowTime.plusDays(days);
            String OtherTimeStr = OtherTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            query.addCriteria(Criteria.where("timeStart").gte(nowTimeStr).lte(OtherTimeStr));
        }

        // 固定查询条件
        LocalDateTime nowTime = LocalDateTime.now();
        String nowTimeStr = nowTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        query.addCriteria(Criteria.where("timeEnd").gte(nowTimeStr));
        query.addCriteria(Criteria.where("statusSell").is(1));

        // 要查询的字段
        /*Document fieldsObject = new Document();
        Query query = new BasicQuery(queryObject, fieldsObject);
        fieldsObject.put("performancesId", true);*/

        // 查询总数
        long count = mongoTemplate.count(query, PerformanceVo.class, PerformanceVo.class.getSimpleName());

        query.with(pageable);

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

        // 组合数据
        info.put("total", count);
        info.put("list", list);

        return info;
    }

    public HashMap<String, Object> noticeList() {
        // 固定条件
        Query query = new Query();
        LocalDateTime nowTime = LocalDateTime.now();
        String nowTimeStr = nowTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        query.addCriteria(Criteria.where("timeEnd").gte(nowTimeStr));
        query.addCriteria(Criteria.where("statusSell").is(1));

        // 今天的
        LocalDateTime toDayTime = LocalDateTime.now();
        String toDayTimeStr = toDayTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDateTime toDayEndTime = toDayTime.plusDays(1);
        String toDayEndTimeStr = toDayEndTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        query.addCriteria(Criteria.where("timeStart").gte(toDayTimeStr).lt(toDayEndTimeStr));
        List<PerformanceVo> toDayList = mongoTemplate.find(query, PerformanceVo.class, PerformanceVo.class.getSimpleName());

        // 三天的
        Query queryT = new Query();
        LocalDateTime nowTimeT = LocalDateTime.now();
        String nowTimeStrT = nowTimeT.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        queryT.addCriteria(Criteria.where("timeEnd").gte(nowTimeStrT));
        queryT.addCriteria(Criteria.where("statusSell").is(1));

        LocalDateTime threeDaysLater = toDayTime.plusDays(3);
        String threeDaysLaterStr = threeDaysLater.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        queryT.addCriteria(Criteria.where("timeStart").gte(toDayEndTimeStr).lt(threeDaysLaterStr));
        List<PerformanceVo> threeDaysList = mongoTemplate.find(queryT, PerformanceVo.class, PerformanceVo.class.getSimpleName());

        HashMap<String, Object> info = new HashMap<>();
        info.put("toDayList", toDayList);
        info.put("threeDaysList", threeDaysList);
        return info;
    }

    public List<PerformanceVo> recommendList() {
        // 固定条件
        Query query = new Query();
        LocalDateTime nowTime = LocalDateTime.now();
        String nowTimeStr = nowTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        query.addCriteria(Criteria.where("timeEnd").gte(nowTimeStr));
        query.addCriteria(Criteria.where("statusSell").is(1));
        // 推荐
        query.addCriteria(Criteria.where("isRecommend").is(1));
        List<PerformanceVo> recommendList = mongoTemplate.find(query, PerformanceVo.class, PerformanceVo.class.getSimpleName());

        return recommendList;
    }

    public HashMap<String, Object> detail(String performancesId) {
        HashMap<String, Object> info = new HashMap<>();

        PerformanceVo performancesInfo = (PerformanceVo) redisUtil.hget(KylinRedisConst.PERFORMANCES, performancesId);
        String roadShowId = "";
        if (null == performancesInfo) {
            performancesInfo = mongoTemplate.findOne(
                    Query.query(Criteria.where("performancesId").is(performancesId)),
                    PerformanceVo.class,
                    PerformanceVo.class.getSimpleName()
            );
            roadShowId = performancesInfo.getRoadShowId();

            redisUtil.hset(KylinRedisConst.PERFORMANCES, performancesId, performancesInfo);
        } else {
            roadShowId = performancesInfo.getRoadShowId();
        }

        List roadList = new ArrayList();
        if (Integer.parseInt(roadShowId) > 0) {
            roadList = redisUtil.lGet(KylinRedisConst.PERFORMANCES_ROADSHOW.concat(roadShowId), 0, -1);
            if (roadList.isEmpty()) {
                roadList = mongoTemplate.find(
                        Query.query(Criteria.where("roadShowId").is(roadShowId)),
                        PerformanceVo.class,
                        PerformanceVo.class.getSimpleName()
                );
                for(Object pinfo : roadList) {
                    redisUtil.lSet(KylinRedisConst.PERFORMANCES_ROADSHOW.concat(roadShowId), pinfo);
                }
            }
        }

        info.put("performancesInfo", performancesInfo);
        info.put("roadList", roadList);

        return info;
    }

}
