package com.jxy.marketall.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
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.service.BorderMongoService;
import com.jxy.marketall.vo.BorderVo;
import com.mongodb.MongoTimeoutException;
import org.bson.json.JsonObject;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
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.io.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
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 BorderMongoServiceImpl implements BorderMongoService {

    @Resource(name = "borderMongoTemplate")
    private MongoTemplate borderMT;


    @Override
    public AjaxResult getBuyPowerList(BorderVo vo) {

        if(StringUtils.isNull(vo.getCoin())){
            return AjaxResult.error("必传参数缺失");
        }

        /** 构建查询的集合 */
        String collectionName = vo.getCoin()+"USDT_bids";
        try {
            if(!borderMT.collectionExists(collectionName)){
                return AjaxResult.error("币种传参有误请检查传参");
            }
        }catch (MongoTimeoutException e){
            return AjaxResult.error("后台数据连接超时，请联系管理员");
        }


        BuyPowerDto dto = getList(collectionName);

        return AjaxResult.success(dto);

    }

    @Override
    public AjaxResult getSellPowerList(BorderVo vo) {
        if(StringUtils.isNull(vo.getCoin())){
            return AjaxResult.error("必传参数缺失");
        }
        /** 构建查询的集合 */
        String collectionName = vo.getCoin()+"USDT_asks";


        if(!borderMT.collectionExists(collectionName)){
            return AjaxResult.error("币种传参有误请检查传参");
        }

        BuyPowerDto dto = getList(collectionName);

        return AjaxResult.success(dto);
    }



    public BuyPowerDto getList(String collectionName){

        //设置查询时间范围为昨天和今天
        Date now = new Date();
        LocalDate localDate=now.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        long endTime = localDate.plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()/1000;
        long startTime = localDate.plusDays(-1).atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()/1000;
        Query query = new Query();

        Criteria criteria = new Criteria();
        criteria.andOperator(Criteria.where("unixdt").gte(startTime).lt(endTime));

        query.addCriteria(criteria).with(Sort.by(Sort.Order.asc("unixdt")));
        query.fields().exclude("_id");

        List<JSONObject> jsonList = borderMT.find(query, JSONObject.class, collectionName);

        BuyPowerDto dto = new BuyPowerDto();
        dto.setMaxPrice(0);

        List<JSONObject> newJsonList = new ArrayList<>();
        JSONArray jsonArray = JSONArray.parseArray(JSONObject.toJSONString(jsonList));
        List<JSONObject> tempList = jsonArray.toJavaList(JSONObject.class);
        newJsonList.addAll(tempList);
        newJsonList.stream().forEach(e ->{
            e.remove("unixdt");
            for (String key: e.keySet()) {
                Integer price = Convert.toInt(key);
                if(price > dto.getMaxPrice()){
                    dto.setMaxPrice(price);
                }
                if(dto.getMinPrice() == 0){
                    dto.setMinPrice(price);
                }
                if(price < dto.getMinPrice()){
                    dto.setMinPrice(price);
                }
            }
        });

        //(max-min)/1000 * 100 +100;
        dto.setInterval((dto.getMaxPrice() - dto.getMinPrice())/1000 * 100 +100);
        //根据间隔去生产时间展示的最大值最小值
        dto.setMinPrice(Math.floorDiv(dto.getMinPrice(),dto.getInterval()) * dto.getInterval());
        dto.setMaxPrice(Math.floorDiv(dto.getMaxPrice(),dto.getInterval()) * dto.getInterval());

        int size = (dto.getMaxPrice()-dto.getMinPrice())/dto.getInterval();

        List<BuyPowerMongoDto> list = new ArrayList<>();
        jsonList.stream().forEach(e ->{
            BuyPowerMongoDto mongoDto = new BuyPowerMongoDto();

            mongoDto.setDate(new Date(Convert.toLong(Convert.toStr(e.get("unixdt"))+"000")));
            e.remove("unixdt");

            Map<Integer, BigDecimal> map = new HashMap<>();
            for(int i=0 ; i <= size;i++){
                map.put(dto.getMinPrice()+(i*dto.getInterval()),BigDecimal.valueOf(0.0));
            }

            for (String key: e.keySet()) {
                Integer price = Convert.toInt(key)/dto.getInterval()*dto.getInterval();
                map.replace(price,map.get(price).add(e.getBigDecimal(key)).setScale(5,BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
            }
            List<BorderDto> borderList = map.entrySet().stream().map(kv -> new BorderDto(kv.getKey(),kv.getValue())).collect(Collectors.toList());
            mongoDto.setValue(borderList);
            list.add(mongoDto);
        });
        dto.setList(list);
        return dto;
    }

}
