package com.jxy.marketall.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jxy.common.core.text.Convert;
import com.jxy.common.core.utils.DateUtils;
import com.jxy.common.core.utils.StringUtils;
import com.jxy.common.core.web.Result.AjaxResult;
import com.jxy.marketall.dto.*;
import com.jxy.marketall.entity.KeyValue;
import com.jxy.marketall.enums.NumberType;
import com.jxy.marketall.service.BTCMongoService;
import com.jxy.marketall.utils.EnumUtils;
import com.jxy.marketall.vo.QueryVo;
import com.jxy.marketall.vo.TopListWatchVo;
import com.jxy.marketall.vo.TopVo;
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.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Description TODO
 * @Date 2022/7/29 15:13
 * @Author 杜懿
 */
@Service
public class BTCMongoServiceImpl implements BTCMongoService {

    @Resource(name = "btcutxosMongoTemplate")
    private MongoTemplate btcMongoTemplate;

    @Override
    public AjaxResult getBuyData(QueryVo vo) {

        Query query = new Query();
        if(StringUtils.isNotNull(vo.getStart())){
            String start = vo.getStart();
            Date startDate = DateUtils.parseDate(start);
            long startTime = startDate.getTime()/1000;

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.DATE, 1);
            long endTime = calendar.getTime().getTime()/1000;

            query.addCriteria(new Criteria().andOperator(Criteria.where("unixdt").gte(startTime).lt(endTime))).limit(1);
        }else {
            query.with(Sort.by(Sort.Order.desc("unixdt"))).limit(1);
        }
        //BuyDto buyDto = btcMongoTemplate.findOne(query, BuyDto.class,"buy");
        JSONObject buyDto = btcMongoTemplate.findOne(query, JSONObject.class,"buy");

        Map<String,Object> map = new LinkedHashMap<>();
        Map<String,Object> sortMap = new HashMap<>();

        if(StringUtils.isNull(buyDto)){
                if(StringUtils.isNotNull(vo.getStart())){
                    map.put("date",vo.getStart());
                }else {
                    map.put("date",DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));
                }
                return AjaxResult.success(map);
        }

        Iterator<Map.Entry<String, Object>> iterator = buyDto.entrySet().iterator();
        Map.Entry<String, Object> entry;
        while (iterator.hasNext()){
            entry =iterator.next();
            if(entry.getKey().equals("_id")){
                map.put("id",Convert.toStr(entry.getValue()));
            }else if(entry.getKey().equals("unixdt")){
                map.put("date",unixStrToDateStr(Convert.toStr(entry.getValue())));
            }else {
                sortMap.put(entry.getKey(),Convert.toInt(entry.getValue()));
            }
        }
        List<KeyValue> list = sortMap.entrySet().stream().map(c -> new KeyValue(c.getKey(), Convert.toStr(c.getValue())))
                .collect(Collectors.toList());
        //排序 先去掉key中的buy 剩下的数字按按大小升序排序
        list.sort(new Comparator<KeyValue>() {
            @Override
            public int compare(KeyValue o1, KeyValue o2) {
                return Convert.toInt(o1.getKey().replace("buy",""))
                        .compareTo(Convert.toInt(o2.getKey().replace("buy","")));
            }
        });

        list.forEach(e -> map.put(e.getKey(),Convert.toInt(e.getValue())));

        System.out.println("map"+map);
        //if(StringUtils.isNull(buyDto)){
        //    buyDto = new BuyDto();
        //    if(StringUtils.isNotNull(vo.getStart())){
        //        buyDto.setDate(vo.getStart());
        //    }else {
        //        buyDto.setDate(DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));
        //    }
        //    return AjaxResult.success(buyDto);
        //}
        //
        //buyDto.setDate(unixStrToDateStr(buyDto.getDate()));
        //
        //return AjaxResult.success(buyDto);
        return AjaxResult.success(map);
    }

    @Override
    public AjaxResult getBuyAmountData(QueryVo vo) {

        Query query = new Query();

        if(StringUtils.isNotNull(vo.getStart())){
            String start = vo.getStart();
            Date startDate = DateUtils.parseDate(start);
            long startTime = startDate.getTime()/1000;

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.DATE, 1);

            long endTime = calendar.getTime().getTime()/1000;

            query.addCriteria(new Criteria().andOperator(Criteria.where("unixdt").gte(startTime).lt(endTime))).limit(1);
        }else {
            query.with(Sort.by(Sort.Order.desc("unixdt"))).limit(1);
        }

        //BuyAmountDto buyAmountDto = btcMongoTemplate.findOne(query, BuyAmountDto.class,"buy_amount");
        JSONObject buyAmountDto = btcMongoTemplate.findOne(query, JSONObject.class,"buy_amount");

        Map<String,Object> map = new LinkedHashMap<>();
        Map<String,Object> sortMap = new HashMap<>();

        if(StringUtils.isNull(buyAmountDto)){
            if(StringUtils.isNotNull(vo.getStart())){
                map.put("date",vo.getStart());
            }else {
                map.put("date",DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));
            }
            return AjaxResult.success(map);
        }

        Iterator<Map.Entry<String, Object>> iterator = buyAmountDto.entrySet().iterator();
        Map.Entry<String, Object> entry;
        while (iterator.hasNext()){
            entry =iterator.next();
            if(entry.getKey().equals("_id")){
                map.put("id",Convert.toStr(entry.getValue()));
            }else if(entry.getKey().equals("unixdt")){
                map.put("date",unixStrToDateStr(Convert.toStr(entry.getValue())));
            }else {
                sortMap.put(StringUtils.toCamelCase(entry.getKey()),Convert.toInt(entry.getValue()));
            }
        }
        List<KeyValue> list = sortMap.entrySet().stream().map(c -> new KeyValue(c.getKey(), Convert.toStr(c.getValue())))
                .collect(Collectors.toList());
        //排序 先去掉key中的buy 剩下的数字按按大小升序排序
        list.sort(new Comparator<KeyValue>() {
            @Override
            public int compare(KeyValue o1, KeyValue o2) {
                return Convert.toInt(o1.getKey().replace("buyAmount",""))
                        .compareTo(Convert.toInt(o2.getKey().replace("buyAmount","")));
            }
        });

        list.forEach(e -> map.put(e.getKey(),Convert.toInt(e.getValue())));

        //List<String> list = sortMap.entrySet().stream().sorted()
        //Collections.sort();

        //if(StringUtils.isNull(buyAmountDto)){
        //    buyAmountDto = new BuyAmountDto();
        //    if(StringUtils.isNotNull(vo.getStart())){
        //        buyAmountDto.setDate(vo.getStart());
        //    }else {
        //        buyAmountDto.setDate(DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));
        //    }
        //    return AjaxResult.success(buyAmountDto);
        //}

        //buyAmountDto.setDate(unixStrToDateStr(buyAmountDto.getDate()));

        //return AjaxResult.success(buyAmountDto);
        return AjaxResult.success(map);
    }

    @Override
    public AjaxResult getDiffData(QueryVo vo) {

        Query query = new Query();

        if(StringUtils.isNotNull(vo.getStart())){
            String start = vo.getStart();
            Date startDate = DateUtils.parseDate(start);
            long startTime = startDate.getTime()/1000;

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.DATE, 1);

            long endTime = calendar.getTime().getTime()/1000;

            query.addCriteria(new Criteria().andOperator(Criteria.where("unixdt").gte(startTime).lt(endTime))).limit(1);
        }else {
            query.with(Sort.by(Sort.Order.desc("unixdt"))).limit(1);
        }

        MongoDto mongoData = btcMongoTemplate.findOne(query, MongoDto.class, "diff");
        if(StringUtils.isNull(mongoData)){
            mongoData = new MongoDto();
            if(StringUtils.isNotNull(vo.getStart())){
                mongoData.setDate(vo.getStart());
            }else {
                mongoData.setDate(DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));
            }
            mongoData.setList(new ArrayList<>());
            return AjaxResult.success(mongoData);
        }
        mongoData.setDate(unixStrToDateStr(mongoData.getDate()));
        query.fields().exclude("_id","unixdt");
        JSONObject dataJSon = btcMongoTemplate.findOne(query, JSONObject.class, "diff");
        Set<String> keys = dataJSon.keySet();
        List<KeyValue> list = new ArrayList<>();
        for (String key: keys) {
            KeyValue keyValue = new KeyValue();
            keyValue.setValue(dataJSon.getString(key));
            keyValue.setKey(key);
            list.add(keyValue);
        }
        mongoData.setList(list);
        return AjaxResult.success(mongoData);

    }

    @Override
    public AjaxResult getDiffAmountData(QueryVo vo) {

        Query query = new Query();

        if(StringUtils.isNotNull(vo.getStart())){
            String start = vo.getStart();
            Date startDate = DateUtils.parseDate(start);
            long startTime = startDate.getTime()/1000;

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.DATE, 1);

            long endTime = calendar.getTime().getTime()/1000;

            query.addCriteria(new Criteria().andOperator(Criteria.where("unixdt").gte(startTime).lt(endTime))).limit(1);
        }else {
            query.with(Sort.by(Sort.Order.desc("unixdt"))).limit(1);
        }

        //DiffAmountDto diffAmountDto = btcMongoTemplate.findOne(query, DiffAmountDto.class, "diff_amount");
        //
        //diffAmountDto.setDate(unixStrToDateStr(diffAmountDto.getDate()));
        //return AjaxResult.success(diffAmountDto);

        MongoDto mongoData = btcMongoTemplate.findOne(query, MongoDto.class, "diff_amount");

        if(StringUtils.isNull(mongoData)){
            mongoData = new MongoDto();
            if(StringUtils.isNotNull(vo.getStart())){
                mongoData.setDate(vo.getStart());
            }else {
                mongoData.setDate(DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));
            }
            mongoData.setList(new ArrayList<>());
            return AjaxResult.success(mongoData);
        }

        mongoData.setDate(unixStrToDateStr(mongoData.getDate()));
        query.fields().exclude("_id","unixdt");
        JSONObject dataJSon = btcMongoTemplate.findOne(query, JSONObject.class, "diff_amount");
        Set<String> keys = dataJSon.keySet();
        List<KeyValue> list = new ArrayList<>();
        for (String key: keys) {
            KeyValue keyValue = new KeyValue();
            keyValue.setValue(dataJSon.getString(key));
            keyValue.setKey(key);
            list.add(keyValue);
        }
        mongoData.setList(list);
        return AjaxResult.success(mongoData);
    }

    @Override
    public AjaxResult getProfitData(QueryVo vo) {

        Query query = new Query();

        if(StringUtils.isNotNull(vo.getStart())){
            String start = vo.getStart();
            Date startDate = DateUtils.parseDate(start);
            long startTime = startDate.getTime()/1000;

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.DATE, 1);

            long endTime = calendar.getTime().getTime()/1000;

            query.addCriteria(new Criteria().andOperator(Criteria.where("unixdt").gte(startTime).lt(endTime))).limit(1);
        }else {
            query.with(Sort.by(Sort.Order.desc("unixdt"))).limit(1);
        }


        MongoDto mongoData = btcMongoTemplate.findOne(query, MongoDto.class, "profit");

        if(StringUtils.isNull(mongoData)){
            mongoData = new MongoDto();
            if(StringUtils.isNotNull(vo.getStart())){
                mongoData.setDate(vo.getStart());
            }else {
                mongoData.setDate(DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));
            }
            mongoData.setList(new ArrayList<>());
            return AjaxResult.success(mongoData);
        }

        mongoData.setDate(unixStrToDateStr(mongoData.getDate()));
        query.fields().exclude("_id","unixdt");
        JSONObject dataJSon = btcMongoTemplate.findOne(query, JSONObject.class, "profit");
        Set<String> keys = dataJSon.keySet();
        List<KeyValue> list = new ArrayList<>();
        for (String key: keys) {
            KeyValue keyValue = new KeyValue();
            keyValue.setValue(dataJSon.getString(key));
            String numStr = key.replace("profit","");
            Double numDouble = Convert.toDouble(numStr);
            key = Double.toString(numDouble/10);
            key = "profit"+key;
            keyValue.setKey(key);
            list.add(keyValue);
        }
        mongoData.setList(list);
        return AjaxResult.success(mongoData);
    }

    @Override
    public AjaxResult getProfitAmountData(QueryVo vo) {

        Query query = new Query();

        if(StringUtils.isNotNull(vo.getStart())){
            String start = vo.getStart();
            Date startDate = DateUtils.parseDate(start);
            long startTime = startDate.getTime()/1000;

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.DATE, 1);

            long endTime = calendar.getTime().getTime()/1000;

            query.addCriteria(new Criteria().andOperator(Criteria.where("unixdt").gte(startTime).lt(endTime))).limit(1);
        }else {
            query.with(Sort.by(Sort.Order.desc("unixdt"))).limit(1);
        }

        MongoDto mongoData = btcMongoTemplate.findOne(query, MongoDto.class, "profit_amount");

        if(StringUtils.isNull(mongoData)){
            mongoData = new MongoDto();
            if(StringUtils.isNotNull(vo.getStart())){
                mongoData.setDate(vo.getStart());
            }else {
                mongoData.setDate(DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));
            }
            mongoData.setList(new ArrayList<>());
            return AjaxResult.success(mongoData);
        }

        mongoData.setDate(unixStrToDateStr(mongoData.getDate()));
        query.fields().exclude("_id","unixdt");
        JSONObject dataJSon = btcMongoTemplate.findOne(query, JSONObject.class, "profit_amount");
        Set<String> keys = dataJSon.keySet();
        List<KeyValue> list = new ArrayList<>();
        for (String key: keys) {
            KeyValue keyValue = new KeyValue();
            keyValue.setValue(dataJSon.getString(key));
            String numStr = key.replace("profit_amount","");
            Double numDouble = Convert.toDouble(numStr);
            key = Double.toString(numDouble/10);
            key = "profit_amount"+key;
            keyValue.setKey(key);
            list.add(keyValue);
        }
        mongoData.setList(list);
        return AjaxResult.success(mongoData);
    }

    @Override
    public AjaxResult getTopList(TopVo topVo) {
        LocalDate localDate = LocalDate.now();
        String topliststr = "toplist"+localDate.format(DateTimeFormatter.ofPattern("dd + yyyy")).replace("+",localDate.getMonth().getDisplayName(TextStyle.SHORT, Locale.ENGLISH));

        /** 判断topliststr对应集合是否存在 */
        boolean flag = btcMongoTemplate.collectionExists(topliststr);
        int times = 0;
        while (!flag){
            //减一天再查
            localDate = localDate.minusDays(1);
            topliststr = "toplist"+localDate.format(DateTimeFormatter.ofPattern("dd + yyyy")).replace("+",localDate.getMonth().getDisplayName(TextStyle.SHORT, Locale.ENGLISH));
            System.out.println("查询集合："+topliststr);
            flag = btcMongoTemplate.collectionExists(topliststr);
            times++;
            if(times > 10){
                break;
            }
        }

        /** 构建查询条件 */
        Criteria criteria;
        if(StringUtils.isNotNull(topVo.getTotal())){
            topVo.setTotal(topVo.getTotal().replaceAll(",",""));
        }
        Double total = Convert.toDouble(topVo.getTotal());
        double value = 100.0;
        if(StringUtils.isNotNull(total)){
            /** 设置判断范围value  默认值100 */
            if(total > value){
                value = total;
            }
            criteria = Criteria.where("value").gte(value);
        }else {
            if(StringUtils.isNotNull(topVo.getTotal())){
                if(topVo.getTotal().length() >= 64){
                    //txid
                    System.out.println("txid"+ topVo.getTotal());
                    criteria = Criteria.where("txid").is(topVo.getTotal());
                }else {
                    //addr
                    System.out.println("addr"+topVo.getTotal());
                    criteria = Criteria.where("addr").is(topVo.getTotal());
                }
            }else {
                criteria = Criteria.where("value").gte(value);;
            }
        }


        /** 构建分页条件 */
        int pageIndex = 0;
        if(topVo.getPage() > 0){
            pageIndex = topVo.getPage() - 1;
        }
        int pageSize = topVo.getLimit();
        int totalPage = 0;

        /** 统计去重后的总个数 */
        Aggregation countAgg = Aggregation.newAggregation(
                Aggregation.match(criteria),
                //按"txid",字段去重统计
                Aggregation.group("txid"),
                Aggregation.count().as("countNum")
        );
        AggregationResults<DataCountDto> countAggResult = btcMongoTemplate.aggregate(countAgg, topliststr, DataCountDto.class);
        List<DataCountDto> countList = countAggResult.getMappedResults();
        if(countList.size()<=0){
            //return AjaxResult.error("该条件下未查询到数据，请检查参数是否正确！");
            TopListDto topListDto = new TopListDto();
            topListDto.setDate(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            topListDto.setCount(0);
            /** totalPage用于计算时是按0开始算 返回给前端的是按1开始算 所以要+1 */
            topListDto.setTotalPage(0);
            List<TopDto> newList = new ArrayList<>();
            topListDto.setList(newList);
            return AjaxResult.success("该条件下未查询到数据",topListDto);
        }
        Long count = countList.get(0).getCountNum();
        System.out.println(count);

        totalPage = (int) (count/pageSize);
        if(count % pageSize != 0){
            totalPage++;
        }
        if(pageIndex>totalPage){
            //查询的起始页数大于总页数 且集合存在（countList.size>0说明集合存在）则把查询起始页数改为最大页数
            pageIndex = totalPage - 1;
        }

        /** 去重查询数据 */
        Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("txid")
                        .first("addr").as("addr")
                        .first("txid").as("txid")
                        .first("value").as("value"),
                Aggregation.sort(Sort.by(Sort.Order.desc("value"))),
                Aggregation.project("addr","txid","value"),
                //分页
                Aggregation.skip(pageIndex*pageSize),
                Aggregation.limit(pageSize)
        );
        AggregationResults<TopDto> aggregate = btcMongoTemplate.aggregate(agg, topliststr, TopDto.class);
        List<TopDto> list = aggregate.getMappedResults();

        if(list.size()<=0){
            //return AjaxResult.error("该条件下未查询到数据，请检查参数是否正确！");
            //return AjaxResult.error("该条件下未查询到数据，请检查参数是否正确！");
            TopListDto topListDto = new TopListDto();
            topListDto.setDate(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            topListDto.setCount(0);
            /** totalPage用于计算时是按0开始算 返回给前端的是按1开始算 所以要+1 */
            topListDto.setTotalPage(0);
            List<TopDto> newList = new ArrayList<>();
            topListDto.setList(newList);
            return AjaxResult.success("该条件下未查询到数据",topListDto);
        }

        //todo 遍历list为tag标签赋值
        TopListDto topListDto = new TopListDto();
        topListDto.setDate(localDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        topListDto.setCount(count);
        /** totalPage用于计算时是按0开始算 返回给前端的是按1开始算 所以要+1 */
        topListDto.setTotalPage(totalPage);
        topListDto.setList(list);

        //Query query = new Query(criteria);
        //long count = btcMongoTemplate.count(query, topliststr);
        //System.out.println("未去重前数据总条数"+count);

        return AjaxResult.success(topListDto);
    }

    @Override
    public AjaxResult getDayBalanceData(QueryVo queryVo, String value,String pre) {
        /** 构建查询的集合 */
        String str = EnumUtils.getNumberTypeStr(NumberType.class, value);
        String collectionName = pre+str+"_days";

        //todo 构建查询条件 日期 默认一周
        Query query = new Query();
        if(StringUtils.isNotNull(queryVo.getStart())){
            String start = queryVo.getStart();
            Date startDate = DateUtils.parseDate(start);
            long startTime = startDate.getTime()/1000;

            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            calendar.add(Calendar.DATE, 1);

            long endTime = calendar.getTime().getTime()/1000;

            query.addCriteria(new Criteria().andOperator(Criteria.where("unixdt").gte(startTime).lt(endTime))).limit(1);
        }else {
            query.with(Sort.by(Sort.Order.desc("unixdt"))).limit(1);
        }

        List<DayBalanceDto> list = new ArrayList<>();
        DayBalanceDto dto = btcMongoTemplate.findOne(query, DayBalanceDto.class, collectionName);

        if (StringUtils.isNull(dto)){
            return AjaxResult.success(list);
        }

        dto.setDateTime(unixStrToDateStr(dto.getDateTime(),DateUtils.YYYY_MM_DD_HH_MM_SS));

        list.add(dto);
        return AjaxResult.success(list);
    }

    @Override
    public AjaxResult getTopListWatch(TopListWatchVo vo) {

        Criteria criteria = new Criteria();
        long startL = 0L;
        long endL = 0L;
        if(StringUtils.isNotEmpty(vo.getAddress())){
            /** 传入了地址则一律按地址查询 */
            criteria = Criteria.where("addr").is(vo.getAddress());
        }
        else if(StringUtils.isNotNull(vo.getValue())){
            /** 查询大于所传的value的数据 */
            criteria = Criteria.where("out_value").gte(vo.getValue());
        }
        else if(StringUtils.isNotEmpty(vo.getEnd()) || StringUtils.isNotEmpty(vo.getStart())){
            if(StringUtils.isEmpty(vo.getStart())){
                /** 说明只传了结束时间   */
                LocalDate endLD = LocalDate.parse(vo.getEnd());
                LocalDateTime endLDT = endLD.atTime(23, 59, 0);
                endL = endLDT.atZone(ZoneOffset.systemDefault()).toEpochSecond();
               criteria = Criteria.where("out_time").lt(endL);
            }else if(StringUtils.isEmpty(vo.getEnd())) {
                LocalDate startLD = LocalDate.parse(vo.getStart());
                LocalDateTime startLDT = startLD.atTime(23, 59, 0);
                startL = startLDT.atZone(ZoneOffset.systemDefault()).toEpochSecond();
                criteria = Criteria.where("out_time").gte(startL);
            }else{
                /** 两个都不为空 */
                LocalDate endLD = LocalDate.parse(vo.getEnd());
                LocalDateTime endLDT = endLD.atTime(23, 59, 0);
                endL = endLDT.atZone(ZoneOffset.systemDefault()).toEpochSecond();

                LocalDate startLD = LocalDate.parse(vo.getStart());;
                LocalDateTime startLDT = startLD.atTime(23, 59, 0);
                startL = startLDT.atZone(ZoneOffset.systemDefault()).toEpochSecond();
                criteria.andOperator(Criteria.where("out_time").lt(endL),Criteria.where("out_time").gte(startL));
            }
        }

        /** 构建分页条件 */
        int pageIndex = 0;
        if(vo.getPage() > 0){
            pageIndex = vo.getPage() - 1;
        }
        int pageSize = 50;
        int totalPage = 0;

        /** 统计去重后的总个数 */
        Aggregation countAgg = Aggregation.newAggregation(
                Aggregation.match(criteria),
                //按"txid",字段去重统计
                Aggregation.group("txid"),
                Aggregation.count().as("countNum")
        );
        AggregationResults<DataCountDto> countAggResult = btcMongoTemplate.aggregate(countAgg, "toplist_watch", DataCountDto.class);
        List<DataCountDto> countList = countAggResult.getMappedResults();
        if(countList.size() <= 0){
            return AjaxResult.error("该条件下未查询到数据，请检查参数是否正确！");
        }
        Long count = countList.get(0).getCountNum();

        totalPage = (int) (count/pageSize);
        if(count % pageSize != 0){
            totalPage++;
        }

        if(pageIndex>totalPage){
            //查询的起始页数大于总页数 且集合存在（countList.size>0说明集合存在）则把查询起始页数改为最大页数
            pageIndex = totalPage - 1;
        }

        Aggregation agg = Aggregation.newAggregation(
                Aggregation.match(criteria),
                Aggregation.group("txid")
                        .first("_id").as("id")
                        .first("addr").as("addr")
                        .first("out_height").as("out_height")
                        .first("out_time").as("out_time")
                        .first("out_txid").as("out_txid")
                        .first("out_value").as("out_value"),
                Aggregation.sort(Sort.by(Sort.Order.asc("out_time"))),
                Aggregation.project("id","addr","out_height","out_time","out_txid","out_value"),

                //分页
                Aggregation.skip(pageIndex*pageSize),
                Aggregation.limit(pageSize)
        );
        AggregationResults<TopListWatchDataDto> aggregate = btcMongoTemplate.aggregate(agg, "toplist_watch", TopListWatchDataDto.class);
        List<TopListWatchDataDto> list = aggregate.getMappedResults();

        if(list.size() <= 0){
            return AjaxResult.error("该条件下未查询到数据，请检查参数是否正确！");
        }

        for(TopListWatchDataDto dto:list) {
            dto.setDate(unixStrToDateStr(dto.getDate(),DateUtils.YYYY_MM_DD_HH_MM_SS));
        }
        TopListWatchDto topListWatchDto = new TopListWatchDto();
        topListWatchDto.setCount(count);
        topListWatchDto.setTotalPage(totalPage);
        topListWatchDto.setList(list);
        return AjaxResult.success(topListWatchDto);
    }

    public String unixStrToDateStr(String date,String sdf){
        if(sdf == null){
            sdf = "yyyy-MM-dd";
        }
        Long dateLong = Convert.toLong(date);
        dateLong *= 1000;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(sdf);
        Date newDate = new Date(dateLong);

        //服务器上需要+8小时
        Calendar ca = new GregorianCalendar();
        ca.setTime(newDate);
        ca.add(ca.HOUR,+8);

        String dareString = simpleDateFormat.format(ca.getTime());
        return dareString;
    }


    public String unixStrToDateStr(String date){

        return unixStrToDateStr(date,null);
    }

}
