package com.jxy.marketall.task;

import com.jxy.common.core.text.DoubleCalculate;
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.common.redis.service.RedisService;
import com.jxy.marketall.dto.*;
import com.jxy.marketall.entity.BiAn;
import com.jxy.marketall.entity.Utxos;
import com.jxy.marketall.mapper.*;
import com.jxy.marketall.vo.BiAnVo;
import com.jxy.marketall.vo.QueryVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.*;


/**
 * @Description TODO
 * @Date 2022/7/26 17:03
 * @Author 杜懿
 */
@Configuration
@EnableScheduling
public class BTCNDAQTask {


    @Autowired
    private BiAnMapper2 biAnMapper;

    @Autowired
    private NDAQMapper ndaqMapper;


    @Autowired
    private RedisService redisService;

    @Scheduled(cron = "0 24 * * * ?")
    //@Scheduled(cron = "0 0/5 * * * ?")
    public void utxos2ndListToRedis(){

        QueryVo vo =new QueryVo();

        //构造BTCprice查询条件
        BiAnVo biAnVo = new BiAnVo();
        biAnVo.setSymbol("1dBTCUSDT");

        //根据查询BTC priceK线 获取时间线
        List<BiAn> biAnList = biAnMapper.selectLongTimeDataByCondition(biAnVo);
        System.out.println("btc价格K线"+biAnList);

        if(biAnList.size() >0){
            Calendar cal = new GregorianCalendar();
            cal.setTime(biAnList.get(biAnList.size()-1).getOpenTime());
            cal.add(cal.DATE,1);
            vo.setEnd(DateUtils.dateTime(cal.getTime()));
            vo.setStart(DateUtils.dateTime(biAnList.get(0).getOpenTime()));

            //返回降序排序结果
            List<NDAQOHLCDto> ohlcList = ndaqMapper.getOHLCList(vo);
            if(ohlcList.size() >0){
                //整合数据
                List<NBohlcDto> nbohlcList = new ArrayList<>();
                //第一步 根据时间线构造返回结果list 并填充btc币价相关数据
                for(int i = 0; i < biAnList.size(); i++){
                    NBohlcDto dto = new NBohlcDto();
                    dto.setBtcOpenPrice(biAnList.get(i).getOpenPrice());
                    dto.setBtcHighPrice(biAnList.get(i).getHighPrice());
                    dto.setBtcLowPrice(biAnList.get(i).getLowPrice());
                    dto.setBtcClosePrice(biAnList.get(i).getClosePrice());
                    dto.setVolume(biAnList.get(i).getVolume());
                    dto.setDate(biAnList.get(i).getOpenTime());
                    nbohlcList.add(dto);
                }

                //第二步 把纳斯达克数据赋值到返回队列nbohlcList
                nbohlcList.stream().forEach(n -> ohlcList.stream().anyMatch(o -> {
                    if(DateUtils.isSameDay(n.getDate(),o.getDate())){
                        n.setNdaqOpenPrice(o.getOpenPrice());
                        n.setNdaqHighPrice(o.getHighestPrice());
                        n.setNdaqLowPrice(o.getLowestPrice());
                        n.setNdaqClosePrice(o.getClosePrice());
                    }
                    return false;
                }));

                //第三步 根据纳斯达克K线数据ohlcList 构造缺失日期数据
                List<NDAQOHLCDto> addList = new ArrayList<>();
                //遍历查询到的纳斯达克数据(降序) 构造缺失日期数据 注意
                for(int i = 0 ; i < ohlcList.size() - 1; i++){
                    NDAQOHLCDto preDto = ohlcList.get(i);
                    NDAQOHLCDto nextDto = ohlcList.get(i+1);
                    Date preDate = DateUtils.parseDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, preDto.getDate()));
                    Date nextDate = DateUtils.parseDate(DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, nextDto.getDate()));
                    Long diff = DateUtils.getDateDiff(preDate, nextDate);

                    if(diff > 1){
                        NDAQOHLCDto dto = new NDAQOHLCDto();
                        BeanUtils.copyProperties(preDto,dto);

                        double opDiff = DoubleCalculate.divide(DoubleCalculate.subtract(preDto.getOpenPrice(), nextDto.getOpenPrice()), diff, 2);
                        double hpDiff = DoubleCalculate.divide(DoubleCalculate.subtract(preDto.getHighestPrice(), nextDto.getHighestPrice()), diff, 2);
                        double lpDiff = DoubleCalculate.divide(DoubleCalculate.subtract(preDto.getLowestPrice(), nextDto.getLowestPrice()), diff, 2);
                        double cpDiff = DoubleCalculate.divide(DoubleCalculate.subtract(preDto.getClosePrice(), nextDto.getClosePrice()), diff, 2);

                        for (int k = 1 ; k < diff ;k++){

                            dto.setOpenPrice(DoubleCalculate.subtract(dto.getOpenPrice(),opDiff));
                            dto.setHighestPrice(DoubleCalculate.subtract(dto.getHighestPrice(),hpDiff));
                            dto.setLowestPrice(DoubleCalculate.subtract(dto.getLowestPrice(),lpDiff));
                            dto.setClosePrice(DoubleCalculate.subtract(dto.getClosePrice(),cpDiff));

                            Calendar ca = new GregorianCalendar();
                            ca.setTime(dto.getDate());
                            ca.add(ca.DATE,-1);
                            dto.setDate(ca.getTime());

                            NDAQOHLCDto addDto = new NDAQOHLCDto();
                            BeanUtils.copyProperties(dto,addDto);

                            addList.add(addDto);
                        }
                    }
                }

                //第四步 把缺失日期数据赋值到返回队列nbohlcList
                for (int i = 0 ; i < addList.size() ; i++){
                    NDAQOHLCDto enrty = addList.get(i);
                    NBohlcDto dto = nbohlcList.stream().filter(n -> DateUtils.isSameDay(enrty.getDate(), n.getDate())).findAny().orElse(null);
                    if(StringUtils.isNotNull(dto)){
                        nbohlcList.get(nbohlcList.indexOf(dto)).setNdaqOpenPrice(enrty.getOpenPrice());
                        nbohlcList.get(nbohlcList.indexOf(dto)).setNdaqHighPrice(enrty.getHighestPrice());
                        nbohlcList.get(nbohlcList.indexOf(dto)).setNdaqLowPrice(enrty.getLowestPrice());
                        nbohlcList.get(nbohlcList.indexOf(dto)).setNdaqClosePrice(enrty.getClosePrice());
                    }
                }

                //特殊情况处理： 周一数据没之前 第三步会失效导致周六周日数据仍为0 应该改为周五数据
                for(int i = nbohlcList.size() - 20 ; i < nbohlcList.size() ; i++  ){
                    NBohlcDto entry = nbohlcList.get(i);
                    if(entry.getNdaqOpenPrice() == 0){
                        nbohlcList.get(i).setNdaqOpenPrice(nbohlcList.get(i-1).getNdaqOpenPrice());
                        nbohlcList.get(i).setNdaqHighPrice(nbohlcList.get(i-1).getNdaqHighPrice());
                        nbohlcList.get(i).setNdaqLowPrice(nbohlcList.get(i-1).getNdaqLowPrice());
                        nbohlcList.get(i).setNdaqClosePrice(nbohlcList.get(i-1).getNdaqClosePrice());
                    }
                }
                if(nbohlcList.size()>0){
                    //存入redis 先删除原有数据再重新插入数据
                    redisService.deleteObject("NBPriceByBTCTimeList");
                    redisService.setCacheList("NBPriceByBTCTimeList",nbohlcList);
                }
            }else {
                System.out.println("该时间段内没有查询到币价数据，没有与之匹配的纳斯达克数据返回！");
            }
        }else {
            System.out.println("数据库没有查询到BTCUSDT按天的数据");
        }



    }



}
