package com.jxy.marketall.task;

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.entity.Utxos;
import com.jxy.marketall.enums.ETHV2RedisName;
import com.jxy.marketall.enums.GDPType;
import com.jxy.marketall.enums.MacroeconomicsRedisName;
import com.jxy.marketall.mapper.MacroEconomyMapper;
import com.jxy.marketall.mapper.Utxos2ndMapper;
import com.jxy.marketall.mapper.UtxosMapper;
import com.jxy.marketall.vo.QueryVo;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
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 sun.nio.ch.Net;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Description 宏观经济相关接口
 * @Date 2022/7/26 17:03
 * @Author 杜懿
 */
@Configuration
@EnableScheduling
public class MacroeconomicsTask {

    @Autowired
    private MacroEconomyMapper macroEconomyMapper;

    @Autowired
    private RedisService redisService;



    @Scheduled(cron = "0 24 0/4 * * ?")
    //@Scheduled(cron = "0 0/1 * * * ?")
    public void AdjustedMoneyStockMeasuresData(){
        List<AdjustedMoneyStockMeasuresDto> list = macroEconomyMapper.getAdjustedMoneyStockMeasuresList();

        if(list.size() > 0){
            redisService.deleteObject(MacroeconomicsRedisName.MONEY_STOCK_MEASURES_ADJUSTED.getKey());
            redisService.setCacheList(MacroeconomicsRedisName.MONEY_STOCK_MEASURES_ADJUSTED.getKey(),list);
        }
    }

    @Scheduled(cron = "0 24 0/4 * * ?")
    public void NotAdjustedMoneyStockMeasuresData(){
        List<NotAdjustedMoneyStockMeasuresDto> list = macroEconomyMapper.getNotAdjustedMoneyStockMeasuresList();

        if(list.size() > 0){
            redisService.deleteObject(MacroeconomicsRedisName.MONEY_STOCK_MEASURES_NOT_ADJUSTED.getKey());
            redisService.setCacheList(MacroeconomicsRedisName.MONEY_STOCK_MEASURES_NOT_ADJUSTED.getKey(),list);
        }
    }

    @Scheduled(cron = "0 23 0/4 * * ?")
    public void PSIData(){

        List<DateStringDto> tempList1 = macroEconomyMapper.getPSIList();
        List<DateStringDto> tempList2 = tempList1.stream().filter(e -> (!"NULL".equals(StringUtils.clean(e.getValue())) && StringUtils.isNotNull(StringUtils.clean(e.getValue())))).collect(Collectors.toList());
        List<DateBigDecimalDto> list = tempList2.stream().map(e ->{
            DateBigDecimalDto dto = new DateBigDecimalDto();
            dto.setDate(e.getDate());
            dto.setValue(Convert.toBigDecimal(StringUtils.clean(e.getValue())));
            return dto;
        }).collect(Collectors.toList());

        if(list.size() > 0){

            redisService.deleteObject(MacroeconomicsRedisName.LOAN_PSI.getKey());
            redisService.setCacheList(MacroeconomicsRedisName.LOAN_PSI.getKey(),list);
        }
    }

    @Scheduled(cron = "0 23 0/4 * * ?")
    public void GDPPrivateInvestoData(){
        List<DateStringDto> tempList1 = macroEconomyMapper.getGDPPrivateInvestorList();
        List<DateStringDto> tempList2 = tempList1.stream().filter(e -> (!"NULL".equals(StringUtils.clean(e.getValue())) && StringUtils.isNotNull(StringUtils.clean(e.getValue())))).collect(Collectors.toList());
        List<DateBigDecimalDto> list = tempList2.stream().map(e ->{
            DateBigDecimalDto dto = new DateBigDecimalDto();
            dto.setDate(e.getDate());
            dto.setValue(Convert.toBigDecimal(StringUtils.clean(e.getValue())));
            return dto;
        }).collect(Collectors.toList());


        if(list.size() > 0){
            redisService.deleteObject(MacroeconomicsRedisName.LOAN_FDHBPI_GDP.getKey());
            redisService.setCacheList(MacroeconomicsRedisName.LOAN_FDHBPI_GDP.getKey(),list);
        }
    }

    @Scheduled(cron = "0 23 0/1 * * ?")
    //@Scheduled(cron = "0 0/1 * * * ?")
    public void WeekebData(){

        List<DateStringDto> templist = macroEconomyMapper.getWEIList();

        List<DateBigDecimalDto> list = templist.stream().map(e ->{
            DateBigDecimalDto dto = new DateBigDecimalDto();
            Calendar ca = new GregorianCalendar();
            ca.setTime(e.getDate());
            ca.add(ca.HOUR,+8);
            dto.setDate(ca.getTime());
            dto.setValue(Convert.toBigDecimal(StringUtils.clean(e.getValue())));
            return dto;
        }).collect(Collectors.toList());

        if(list.size() > 0){
            redisService.deleteObject(MacroeconomicsRedisName.WEI.getKey());
            redisService.setCacheList(MacroeconomicsRedisName.WEI.getKey(),list);
        }
    }

    //@Scheduled(cron = "0 24 0/4 * * ?")
    @Scheduled(cron = "10 1 0 * * ?")
    public void NewGDP(){

        Calendar ca = Calendar.getInstance();
        int year = ca.get(Calendar.YEAR) - 2 ;
        String times = ""+year+"Q1";

        List<GDPDto> list = macroEconomyMapper.getGDPTable(times);

        list.stream().forEach(e -> {
            BigDecimal pceg = Convert.toBigDecimal(e.getPcedg().replaceAll(",","")).add(Convert.toBigDecimal(e.getPcend().replaceAll(",","")));
            DecimalFormat df = new DecimalFormat("#,###");
            e.setPceg(df.format(pceg.doubleValue()));
        });

        GDPTableDto gtDto = new GDPTableDto();
        //构造头部
        List<GDPTableHeadDto> gthList = new ArrayList<>();
        for(int i=0;i<3;i++){
            //循环三次 构造最近3年的数据
            GDPTableHeadDto gtHDto = new GDPTableHeadDto();
            gtHDto.setYear(year);
            List<GDPTableHeadEntityDto> headList = new ArrayList<>();
            if(i<2){
                //前两年数据肯定为4个季度额度数据 即数据条数必定为4
                for (int j=1;j<=4;j++){
                    GDPTableHeadEntityDto heDto = new GDPTableHeadEntityDto();
                    heDto.setProp(""+year+"Q"+j);
                    heDto.setName("Q"+j);
                    headList.add(heDto);
                }
                gtHDto.setHead(headList);
            }else {
                for (int j=1;j<=(list.size() - 8);j++){
                    GDPTableHeadEntityDto heDto = new GDPTableHeadEntityDto();
                    heDto.setProp(""+year+"Q"+j);
                    heDto.setName("Q"+j);
                    headList.add(heDto);
                }
                gtHDto.setHead(headList);
            }
            gthList.add(gtHDto);
            year++;
        }
        gtDto.setHead(gthList);
        //构造数据
        List<Map<String,String>> bodyList = new ArrayList<>();
        Map<String,String> pce = new HashMap<>();
        Map<String,String> pceg = new HashMap<>();
        Map<String,String> pcedg = new HashMap<>();
        Map<String,String> pcend = new HashMap<>();
        Map<String,String> pces = new HashMap<>();
        Map<String,String> gpdi = new HashMap<>();
        Map<String,String> fpi = new HashMap<>();
        Map<String,String> cbi = new HashMap<>();
        Map<String,String> netexp = new HashMap<>();
        Map<String,String> impgs = new HashMap<>();
        Map<String,String> expgs = new HashMap<>();

        pce.put("name","Personal consumption expenditures");
        pceg.put("name","Goods");
        pcedg.put("name","Durable goods");
        pcend.put("name","Nondurable goods");
        pces.put("name","Services");
        gpdi.put("name","Gross private domestic investment");
        fpi.put("name","Fixed investment");
        cbi.put("name","Change in private inventories");
        netexp.put("name","Net exports of goods and services");
        impgs.put("name","Imports");
        expgs.put("name","Exports");
        list.stream().forEach(e -> {
            pce.put(e.getDate(),e.getPce());
            pceg.put(e.getDate(),e.getPceg());
            pcedg.put(e.getDate(),e.getPcedg());
            pcend.put(e.getDate(),e.getPcend());
            pces.put(e.getDate(),e.getPces());
            gpdi.put(e.getDate(),e.getGpdi());
            fpi.put(e.getDate(),e.getFpi());
            cbi.put(e.getDate(),e.getCbi());
            netexp.put(e.getDate(),e.getNetexp());
            impgs.put(e.getDate(),e.getImpgs());
            expgs.put(e.getDate(),e.getExpgs());
        });
        bodyList.add(pce);
        bodyList.add(pceg);
        bodyList.add(pcedg);
        bodyList.add(pcend);
        bodyList.add(pces);
        bodyList.add(gpdi);
        bodyList.add(fpi);
        bodyList.add(cbi);
        bodyList.add(netexp);
        bodyList.add(impgs);
        bodyList.add(expgs);

        gtDto.setList(bodyList);

        redisService.deleteObject(MacroeconomicsRedisName.GDP_NEW.getKey());
        redisService.setCacheObject(MacroeconomicsRedisName.GDP_NEW.getKey(),gtDto);
    }

    //@Scheduled(cron = "0 0/3 * * * ?")
    @Scheduled(cron = "10 1 0 * * ?")
    public void GDPList(){

        GDPType[] values = GDPType.values();
        for(int i=0;i<values.length;i++){
            dataToDB(values[i]);
        }

    }

    public  void  dataToDB(GDPType gdpType){

        List<DateStrBigDecimalDto> list = new ArrayList<>();

        if(GDPType.PCEG.equals(gdpType)){
            //pceg 是table中PCEDG和PCEND的值相加计算 所以要单独处理
            List<DateStrStringDto> dgStrList = macroEconomyMapper.getGDPByTableAndField(GDPType.PCEDG.getTable(), GDPType.PCEDG.getFiled());
            List<DateStrStringDto> ndStrList = macroEconomyMapper.getGDPByTableAndField(GDPType.PCEND.getTable(), GDPType.PCEND.getFiled());

            List<DateStrBigDecimalDto> dgBDList = listChange(dgStrList);

            List<DateStrBigDecimalDto> ndBDList = listChange(ndStrList);

            list = dgBDList.stream().map(dg ->{
                ndBDList.stream().filter(nd -> dg.getDate().equals(nd.getDate())).forEach(nd ->{
                    dg.setDate(nd.getDate());
                    dg.setValue(dg.getValue().add(nd.getValue()));
                });
                return dg;
            }).collect(Collectors.toList());
        }else {
            //其余field直接从数据库取值 然后进行字段类型转换处理
            List<DateStrStringDto> tempList1 = macroEconomyMapper.getGDPByTableAndField(gdpType.getTable(), gdpType.getFiled());
            list = listChange(tempList1);
        }
        if(list.size()>0){
            //存入redis 先删除原有数据再重新插入数据
            redisService.deleteObject(gdpType.getKey());
            redisService.setCacheList(gdpType.getKey(),list);
        }
    }


    /**
     * list对象转换
     * 数据库取出时对象为DateStrStringDto,经此方法转换后list对象变为DateStrBigDecimalDto
     */
    public List<DateStrBigDecimalDto> listChange(List<DateStrStringDto> strList) {
        if(StringUtils.isNull(strList)){
            return new ArrayList<>();
        }

        List<DateStrStringDto> tempList = strList.stream().filter(e -> (!"NULL".equals(StringUtils.clean(e.getValue())) && StringUtils.isNotNull(StringUtils.clean(e.getValue())))).collect(Collectors.toList());

        List<DateStrBigDecimalDto> list = tempList.stream().map(e -> {
            DateStrBigDecimalDto dto = new DateStrBigDecimalDto();
            dto.setDate(e.getDate());
            dto.setValue(Convert.toBigDecimal(StringUtils.clean(e.getValue().replaceAll(",", ""))));
            return dto;
        }).collect(Collectors.toList());

        return list;
    }

}
