package com.ruoyi.web.runner;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateRange;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileReader;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.ruoyi.framework.datasource.DynamicDataSource;
import com.ruoyi.quartz.glue.GlueFactory;
import com.ruoyi.quartz.handler.IJobHandler;
import com.ruoyi.quartz.handler.impl.MyJobHandler;
import com.ruoyi.ucp.entity.*;
import com.ruoyi.ucp.feign.AdapterApi;
import com.ruoyi.ucp.service.*;
import com.ruoyi.ucp.util.CalcCache;
import com.ruoyi.web.controller.JavaFunctionJobHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Component
public class LoadDataSourceRunner implements CommandLineRunner {
    @Resource
    private DynamicDataSource dynamicDataSource;
    @Resource
    private IUcpDataSourceService ucpDataSourceService;

    //@Resource
    //private ScriptEngine engine;
    @Resource
    private AdapterApi adapter;
    @Resource
    private IPointInfoService pointService;
    @Resource
    private IStationInfoDayService stationInfoDayService;
    @Resource
    private IStationInfoHourService stationInfoHourService;
    @Resource
    private IMethodService methodService;
    @Resource
    private ILineInfoDayService lineInfoDayService;
    @Resource
    private IFormulaService formulaService;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Value("${ruoyi.profile}")
    private String path;
//    @Value("${power_curve_month}")
//    private String powerCurveMonth;
//    @Resource
//    private JavaFunctionJobHandler task;

    @Override
    public void run(String... args) {
        List<UcpDataSource> list = ucpDataSourceService.list();
        List<DruidDataSource> dataSources = BeanUtil.copyToList(list, DruidDataSource.class);
        dynamicDataSource.createDataSource(dataSources);

        //engine.put("adapter", adapter);
        //engine.put("pointService", pointService);
        //engine.put("stationInfoDayService", stationInfoDayService);
        //engine.put("stationInfoHourService", stationInfoHourService);
        //engine.put("lineInfoDayService", lineInfoDayService);

        List<Method> methods = methodService.list();
        List<Formula> formulas = formulaService.list();
        //        String functionCode = GlueFactory.getFunctionTemplate();
        String jarPath = path + "FunctionTemplate.java";
        String functionCode = FileReader.create(new File(jarPath)).readString();
        //        String functionCode = ResourceUtil.readUtf8Str("FunctionTemplate.java");
        try {
            for (Method method : methods) {
                //engine.eval(method.getMethodExpression());
                functionCode = functionCode
                        .replace("//此处加公式", method.getMethodExpression() + "\n//此处加公式");
            }
            for (Formula formula : formulas) {
                functionCode = functionCode.replace("//此处加公式", formula.getFormulaExpression() + "\n//此处加公式");
            }
            IJobHandler jobHandler = GlueFactory.getInstance().loadNewInstance(functionCode);
            MyJobHandler.jobHandler = jobHandler;
        } catch (Exception e) {
            e.printStackTrace();
        }

        LettuceConnectionFactory factory = (LettuceConnectionFactory) stringRedisTemplate.getConnectionFactory();
        int database = factory.getDatabase();
        factory.setDatabase(9);
        stringRedisTemplate.setConnectionFactory(factory);
        factory.afterPropertiesSet();
        factory.resetConnection();
        /*Set<String> keys = redisTemplate.keys("monthCurve_*");
        for (String key : keys) {
            //redis缓存中获取到字符串
            JSONArray o = (JSONArray) redisTemplate.opsForValue().get(key);
            //字符串类型转换为list月拟合曲线集合
            List<ProEconWtCurveFittingMonth> powerList = JSON.parseObject(o.toJSONString(), new TypeReference<List<ProEconWtCurveFittingMonth>>() {}.getType());

//            List<ProEconWtCurveFittingMonth> powerList = JSONObject.parseObject((String) o, new TypeReference<List<ProEconWtCurveFittingMonth>>() {});
            Map<Double, Double> collect = powerList.stream().collect(Collectors.toMap(ProEconWtCurveFittingMonth::getSpeed, ProEconWtCurveFittingMonth::getActualPower,(v1,v2)->v1));
            CalcCache.wtMcfMap.put(powerList.get(0).getWindturbineId(), collect);
        }*/
        PointInfo pi = new PointInfo();
        pi.setUniformCode("MX000");
        pi.setInstitutionType("state");
        List<PointInfo> trubineModel = pointService.getByEntity(pi);
        pi.setUniformCode("AI422");
        List<PointInfo> trubineModel1 = pointService.getByEntity(pi);
        trubineModel.addAll(trubineModel1);

        String zllgl = stringRedisTemplate.opsForValue().get("ZLLGL");
        //字符串类型转换为list月拟合曲线集合
        Map<String, Map<Double, ProBasicModelPowerRd>> bzgl = JSON.parseObject(zllgl, new TypeReference<Map<String, Map<Double, ProBasicModelPowerRd>>>() {
        }.getType());
        bzgl.forEach((modeId, map) -> {
            ConcurrentHashMap<Double, Double> mdd = new ConcurrentHashMap<>();
            map.forEach((speed, mprd) -> {
                mdd.put(speed, mprd.getEnsurePower());
            });
            CalcCache.bzgl.put(modeId, mdd);
        });
        for (PointInfo info : trubineModel) {
            Map<Double, ProBasicModelPowerRd> rdMap = bzgl.get(info.getSpare());
            ConcurrentHashMap<Double, Double> mdd = new ConcurrentHashMap<>();
            rdMap.forEach((fs, rd) -> {
                mdd.put(fs, rd.getTheoryPower());
            });
            CalcCache.llgl.put(info.getTurbineId(), mdd);
        }

        factory.setDatabase(database);
        factory.afterPropertiesSet();
        factory.resetConnection();

        String powerCurveMonth = "glqxnh:" + DateUtil.date().getMonth() + ":";
        Set<String> keys = stringRedisTemplate.keys(powerCurveMonth + "*");
        CalcCache.keys = keys.stream().collect(Collectors.joining(","));
        for (String key : keys) {
            String yc = stringRedisTemplate.opsForValue().get(key);
            ConcurrentHashMap<Double, Double> wtyc = JSON.parseObject(yc, new TypeReference<ConcurrentHashMap<Double, Double>>() {
            }.getType());
            CalcCache.fitcoef.put(key.replaceFirst(powerCurveMonth, ""), wtyc);
            if (wtyc.size() == 2500) {
                CalcCache.already.add(key.replaceFirst(powerCurveMonth, ""));
            }
        }

        String swdlTime = stringRedisTemplate.opsForValue().get("swdlTime");
        if (swdlTime != null)
            CalcCache.swdlTime = JSON.parseObject(swdlTime, new TypeReference<Map<String, Long>>() {
            });


//        DateTime start = DateUtil.parse("2024-03-25");
//        DateTime end = DateUtil.parse("2024-06-25");
//        task.calcGlqxnh(start,end);
//        System.out.println("选否");
    }
}
