package com.jxy.marketall.task;

import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.C;
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.redis.service.RedisService;
import com.jxy.marketall.dto.*;
import com.jxy.marketall.enums.ETHV2RedisName;
import com.jxy.marketall.mapper.ETHV2Mapper;
import com.jxy.marketall.vo.QueryVo;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.aggregation.ComparisonOperators;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * @Description TODO
 * @Date 2022/7/7 18:03
 * @Author 杜懿
 */
@Configuration
@EnableScheduling
public class ETHV2Task {

    @Autowired
    private ETHV2Mapper ethv2Mapper;

    @Autowired
    private RedisService redisService;

    /**币天销毁量 Coin Days Destroyed所有数据 */
    @Scheduled(cron = "30 0 0/1 * * ?")
    public void CddDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_CDD);
    }

    /** eth 币价Price */
    @Scheduled(cron = "0 11 0/1 * * ?")
    //@Scheduled(cron = "0 0/2 * * * ?")
    public void ETHPriceToRedis(){

        QueryVo vo = new QueryVo();
        //vo.setStart("2010-08-19");
        List<PriceDataDto> list = ethv2Mapper.getPriceList(vo);

        if(list.size() > 0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject("ethPriceList");
            redisService.setCacheList("ethPriceList",list);
        }
    }

    /**已花费输出休眠平均天数 Average Coin Dormancy所有数据 */
    @Scheduled(cron = "30 0 0/1 * * ?")
    public void dormancyDataToRedis(){

        dataToDB(ETHV2RedisName.ETH_DORMANCY);

    }

    /**已花费输出平均寿命 Average Spent Output Lifespan所有数据 */
    @Scheduled(cron = "30 0 0/1 * * ?")
    public void asolDataToRedis(){

        dataToDB(ETHV2RedisName.ETH_ASOL);

    }

    /**币天销毁量分布  Distribution of Coin Days Destroyed    1-730所有数据 */
    @Scheduled(cron = "30 0 0/1 * * ?")
    public void CDDWaveDataToRedis(){

        List<ETHCoinDaysDescDto> list = ethv2Mapper.getCDD();

        if(list.size()>0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(ETHV2RedisName.ETH_CDDWAVE.getKey());
            redisService.setCacheList(ETHV2RedisName.ETH_CDDWAVE.getKey(),list);
        }

    }

    /**按余额分段的地址数分布 wave Distribution of Address 所有数据 */
    @Scheduled(cron = "40 0 0/1 * * ?")
    public void AddressBalanceToRedis(){

        List<ETHAddressBalanceDto> list = ethv2Mapper.getAddressBalance();

        if(list.size()>0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(ETHV2RedisName.ETH_ADDRESS_BALANCE.getKey());
            redisService.setCacheList(ETHV2RedisName.ETH_ADDRESS_BALANCE.getKey(),list);
        }

    }

    /**持有者地址的供应分布 Distribution of Address Supply 所有数据 */
    @Scheduled(cron = "40 0 0/1 * * ?")
    public void BalanceToRedis(){

        List<ETHAddressBalanceDto> list = ethv2Mapper.getAddressSupply();

        if(list.size()>0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(ETHV2RedisName.ETH_BALANCE.getKey());
            redisService.setCacheList(ETHV2RedisName.ETH_BALANCE.getKey(),list);
        }

    }

    /**通货膨胀率 Inflation Rate所有数据 */
    //inflaction rate=SUM365(Daily Coin Issuance)/Circulating Supply
    @Scheduled(cron = "10 1 0/1 * * ?")
    //@Scheduled(cron = "0/10 * * * * ?")
    public void InflationRateDataToRedis(){
        //获取年总发行量
        Map<Integer, YearMaDto> map = ethv2Mapper.getYearIssuance();
        //List<DateBigDecimalDto> issuanceList = ethv2Mapper.getListByTableAndField(ETHV2RedisName.ETH_ISSUANCE.getTable(), ETHV2RedisName.ETH_ISSUANCE.getFiled());

        //Map<Date,BigDecimal> map = new HashMap<>();
        //for(int i=issuanceList.size() - 1  ; i >=364 ; i--){
        //    List<DateBigDecimalDto> list = issuanceList.stream().skip(i-364).limit(365).collect(Collectors.toList());
        //    BigDecimal total = list.stream().map(DateBigDecimalDto::getValue).reduce(BigDecimal.ZERO, BigDecimal::add);
        //    map.put(list.get(list.size()-1).getDate(),total);
        //}


        List<DateBigDecimalDto> csupplyList = ethv2Mapper.getListByTableAndField(ETHV2RedisName.ETH_CSUPPLY.getTable(), ETHV2RedisName.ETH_CSUPPLY.getFiled());

        csupplyList.stream().forEach(e ->{

            if(BigDecimal.ZERO.compareTo(e.getValue()) == 0){

            }else {
                //BigDecimal issuance = map.get(e.getDate());
                BigDecimal issuance = map.get(Convert.toInt(DateUtils.parseDateToStr(DateUtils.YYYY, e.getDate()))).getValue();
                if(StringUtils.isNull(issuance)){
                    issuance = BigDecimal.ZERO;
                }
                e.setValue(issuance.divide(e.getValue(), 8,BigDecimal.ROUND_HALF_UP).stripTrailingZeros());
            }
        });

        if(csupplyList.size()>0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(ETHV2RedisName.ETH_INFLATION_RATE.getKey());
            redisService.setCacheList(ETHV2RedisName.ETH_INFLATION_RATE.getKey(),csupplyList);
        }

    }

    /**新币发行量 issuance所有数据 */
    @Scheduled(cron = "10 1 0/1 * * ?")
    public void IssuanceDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_ISSUANCE);
    }

    /**已花费输出盈利比 Spent Output Profit Ratio所有数据 */
    @Scheduled(cron = "10 1 0/1 * * ?")
    public void soprDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_SOPR);

    }


    /**市值/交易价值比 Network Value to Transactions Ratio所有数据 */
    @Scheduled(cron = "10 1 0/1 * * ?")
    public void NVTRatioDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_NVT_RATIO);
    }

    /**流通速度 Velocity所有数据 */
    @Scheduled(cron = "10 1 0/1 * * ?")
    public void VelocityDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_VELOCITY);
    }


    /**活跃度 liveliness所有数据 */
    @Scheduled(cron = "20 1 0/1 * * ?")
    public void LivelinessDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_LIVELINESS);
    }

    /**交易费率乘数 Fee Ratio Multiple (FRM)所有数据 */
    @Scheduled(cron = "20 1 0/1 * * ?")
    public void FRMDataToRedis(){
        List<DateBigDecimalDto> list = ethv2Mapper.getListByTableAndField(ETHV2RedisName.ETH_FRM.getTable(), ETHV2RedisName.ETH_FRM.getFiled());
        Date start = DateUtils.parseDate("2017-05-18");
        list = list.stream().filter(dto -> (dto.getDate().after(start) || dto.getDate().equals(start))).collect(Collectors.toList());
        if(list.size()>0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(ETHV2RedisName.ETH_FRM.getKey());
            redisService.setCacheList(ETHV2RedisName.ETH_FRM.getKey(),list);
        }
    }

    /**未实现的净收益损失比 Net Unrealized Profit/Loss所有数据 */
    @Scheduled(cron = "20 1 0/1 * * ?")
    public void NUPLDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_NUPL);
    }

    /**流通市值 Market Cap所有数据 */
    @Scheduled(cron = "20 1 0/1 * * ?")
    public void MarketcapDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_MARKETCAP);
    }

    /**已实现流通市值 Realized Cap所有数据 */
    @Scheduled(cron = "20 1 0/1 * * ?")
    public void RealizedCapDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_REALIZED_CAP);
    }

    /**已实现价格 Realized Price所有数据 */
    @Scheduled(cron = "20 1 0/1 * * ?")
    public void RealizedPriceDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_REALIZED_RRICE);
    }

    /**流通市值-已实现流通市值比 Market Value to Realized Value Ratio所有数据 */
    @Scheduled(cron = "30 1 0/1 * * ?")
    public void mvrvRatioDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_MVRV_RATIO);
    }



    /**燃烧量 Burned Supply所有数据 */
    @Scheduled(cron = "30 1 0/1 * * ?")
    public void BurnedSupplyDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_BURNED_SUPPLY);
    }

    /**发行量 Minted Supply所有数据 */
    @Scheduled(cron = "30 1 0/1 * * ?")
    public void MintedSupplyDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_MINTED_SUPPLY);
    }

    /**盈利地址百分比 Percent of Addresses in Profit所有数据 */
    @Scheduled(cron = "30 1 0/1 * * ?")
    public void AddressProfitRatioDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_ADDRESS_PROFIT_RATIO);

    }

    /**盈利地址数 Number of Addresses in Profit所有数据 */
    @Scheduled(cron = "30 1 0/1 * * ?")
    public void AddressProfitDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_ADDRESS_PROFIT);
    }

    /**亏损地址数 Number of Addresses in Loss所有数据 */
    @Scheduled(cron = "40 1 0/1 * * ?")
    public void AddressLossDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_ADDRESS_LOSS);
    }

    /**盈利百分比 Percent Supply in Profit所有数据 */
    @Scheduled(cron = "40 1 0/1 * * ?")
    public void SupplyProfitRaitoDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_SUPPLY_PROFIT_RATIO);
    }

    /**盈利供应量 Total Supply in Profit 所有数据 */
    @Scheduled(cron = "40 1 0/1 * * ?")
    public void SupplyProfitDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_SUPPLY_PROFIT);
    }

    /**盈利亏损量 Total Supply in Loss 所有数据 */
    @Scheduled(cron = "40 1 0/1 * * ?")
    public void SupplyLossDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_SUPPLY_LOSS);
    }

    /**未实现的净收益量 Relative Unrealized Profit所有数据 */
    @Scheduled(cron = "40 1 0/1 * * ?")
    public void RelativeUnrealizedProfitDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_RELATIVE_UNREALIZED_PROFIT);
    }

    /**未实现的净亏损量 Relative Unrealized Loss所有数据 */
    @Scheduled(cron = "40 1 0/1 * * ?")
    public void RelativeUnrealizedLossDataToRedis() {
        dataToDB(ETHV2RedisName.ETH_RELATIVE_UNREALIZED_LOSS);
    }

    /**长持者未实现的净收益量 Long Term Holder NUPL所有数据 */
    @Scheduled(cron = "40 1 0/1 * * ?")
    public void LTHNUPLDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_LTH_NUPL);
    }


    /**短持者未实现的净亏损量 Short Term Holder NUPL所有数据 */
    @Scheduled(cron = "40 1 0/1 * * ?")
    public void STHNUPLDataToRedis(){
        dataToDB(ETHV2RedisName.ETH_STH_NUPL);
    }

    public  void  dataToDB(ETHV2RedisName redisName){

        List<DateBigDecimalDto> list = ethv2Mapper.getListByTableAndField(redisName.getTable(), redisName.getFiled());
        if(list.size()>0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(redisName.getKey());
            redisService.setCacheList(redisName.getKey(),list);
        }
    }

}
