package com.dky.tool;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.dky.modelI.DntdModelI;
import com.dky.stirtpar.StirparModelCalculate;
import com.dky.utils.ConfigReader;
import com.dky.utils.entity.SysDeviceHeatScene;
import com.dky.utils.enums.Code;
import com.dky.utils.result.ResponseUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class ModelTool {

    public List<SysDeviceHeatScene> specList;

    // 私有化构造方法,避免外部实例化
    private ModelTool() {
    }

    public ModelTool(List<SysDeviceHeatScene> specList) {
        this.specList = specList;
    }

    // 创建工具类的静态工厂方法
    public static ModelTool create(JSONObject list) {
        List<SysDeviceHeatScene> specList = new ArrayList<>();
        JSONArray specArray = list.getJSONArray("devSpecList");
        for (int i = 0; i < specArray.size(); i++) {
            SysDeviceHeatScene devSpec = specArray.getJSONObject(i).toBean(SysDeviceHeatScene.class);
            specList.add(devSpec);
        }
        return new ModelTool(specList);
    }


    public JSONObject exeModel2Report(JSONObject jsonObject, String key,List<Map> mapList) {
        JSONObject jsonObjectResult = new JSONObject();
        // 判断CpuId是否包含本机地址
        Boolean isAuthorization = Boolean.FALSE;
        // 参数合法性检查
        if (key == null || key.isEmpty()) {
            System.err.println("解密密钥不能为空");
            return ResponseUtil.createResponse(Code.KEY_CONTEXT_ERROR.getCode(), Code.KEY_CONTEXT_ERROR.getDesc(), null);
        }
        //这里会去查询两张表,分别是mysql中的information_schema库的tables和statistics表中的设备数据表元信息,其中有用的只是tables中的create_time字段,其余字段没有任何意义,只是为了防止破解
        if (mapList.size() != 2){
            System.err.println("未获取到验证信息");
            return ResponseUtil.createResponse(Code.KEY_CONTEXT_ERROR.getCode(), Code.KEY_CONTEXT_ERROR.getDesc(), null);
        }
        try {
            // 根据给定的类名初始化类  加密不需要反实例化new
            Class<?> sm4UtilsClass = Class.forName("com.dky.security.SM4Utils");
            // 实例化类
            Object obj = sm4UtilsClass.getDeclaredConstructor().newInstance();
            // 获取方法并调用
            Method decryptMethod = sm4UtilsClass.getMethod("sm2DecryptBase64", String.class);
            String invoke = (String) decryptMethod.invoke(obj, key);
            Map<String, String> map = new HashMap<>();
            String[] keyValuePairs = invoke.split("&");
            for (String keyValuePair : keyValuePairs) {
                String[] keyValue = keyValuePair.split("=");
                String key1 = keyValue[0];
                String value = keyValue[1];
                map.put(key1, value);
            }

            //获取table表的JSONObject
            Map table = mapList.get(0);
            //获取statistics表的JSONObject
            Map statistics = mapList.get(1);
            if(statistics == null) {
                System.err.println("未获取到验证信息");
                return ResponseUtil.createResponse(Code.KEY_UNAUTHORIZED.getCode(), Code.KEY_UNAUTHORIZED.getDesc(), null);
            }
            if(map.get("expireTime") == null){
                return ResponseUtil.createResponse(Code.KEY_CONTEXT_ERROR.getCode(), Code.KEY_CONTEXT_ERROR.getDesc(), null);
            }
            if(map.get("companyname") == null){
                return ResponseUtil.createResponse(Code.KEY_CONTEXT_ERROR.getCode(), Code.KEY_CONTEXT_ERROR.getDesc(), null);
            }
            // 定义日期时间格式并转化日期数据
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //创建表日期
            Date createTimeDate = null;
            try{
                //处理查询出的类型是String
                String createTimeDateStr = (String) table.get("CREATE_TIME");
                createTimeDate = formatter.parse(createTimeDateStr);
            } catch (ParseException e){
                try{
                    // 假设 table.get("CREATE_TIME") 返回的是 LocalDateTime 对象
                    LocalDateTime createTimeDateTime = (LocalDateTime) table.get("CREATE_TIME");
                    // 将 LocalDateTime 转换为字符串
                    createTimeDate = formatter.parse(createTimeDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                } catch (NullPointerException e2){
                    try{
                        // 假设 table.get("CREATE_TIME") 返回的是 LocalDateTime 对象
                        LocalDateTime createTimeDateTime = (LocalDateTime) table.get("create_time");
                        // 将 LocalDateTime 转换为字符串
                        createTimeDate = formatter.parse(createTimeDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    } catch (NullPointerException e1){
                        e1.printStackTrace();
                        return ResponseUtil.createResponse(Code.KEY_UNAUTHORIZED.getCode(), Code.KEY_UNAUTHORIZED.getDesc(), null);
                    }
                }
            }
            //key中验证日期
            Date startTimeDate  = formatter.parse(map.get("cpuIds"));
            //表创建时间早于key中时间,直接放行
            if (createTimeDate.before(startTimeDate)){
                isAuthorization = Boolean.TRUE;
            }
            //表创建时间早于key10天内的时间,直接放行
            if (createTimeDate.before(new Date(startTimeDate.getTime() + 1000 * 60 * 60 * 24 * 10))){
                isAuthorization = Boolean.TRUE;
            }
            if (isAuthorization) {
                // 判断模型使用权限
                // 根据给定的类名初始化类  加密不需要反实例化new
                Class<?> buildHeatingScene = Class.forName("com.dky" + "." + ConfigReader.getProperty(jsonObject.getStr("type")));
                // 实例化这个类
                DntdModelI buildHeatingSceneModel = (DntdModelI) buildHeatingScene.newInstance();
                // 调用指定方法
                jsonObjectResult = buildHeatingSceneModel.createReport(jsonObject, this.specList);
            } else {
                jsonObjectResult = ResponseUtil.createResponse(Code.KEY_UNAUTHORIZED.getCode(), Code.KEY_UNAUTHORIZED.getDesc(), null);
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException |
                 NoSuchMethodException | SecurityException e) {
            // 异常处理
            System.err.println("反射调用过程中发生异常: " + e.getMessage());
        } catch (InvocationTargetException e) {
            jsonObjectResult = ResponseUtil.createResponse(Code.KEY_CONTEXT_ERROR.getCode(), Code.KEY_CONTEXT_ERROR.getDesc(), null);
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return jsonObjectResult;
    }

    public static void main(String[] args) throws Exception {
        String key = "BLR6nEyco9XOz/AAPNyQiVV9ZAaW8uzIlPCPAelM2/l1G/xHFQPpoU6da86xwtXPym6gHx5TRKVUyUpGOUfIqDTf/acmql7/xM6RZUlNizb93z8o5+f3HL4c5/J/R2+6/V0c0oLkh/j/uks6QnyI5UHN+WFPpRVliv3H+Dd+97/jodlcYCafeKMdknClJlaVpUZBnsjDw+Am2+gl1h43wGkmHqS5jGD9z1wkr/VjsjE7oLyS";
        // 根据给定的类名初始化类  加密不需要反实例化new
        Class<?> sm4UtilsClass = Class.forName("com.dky.security.SM4Utils");
        // 实例化类
        Object obj = sm4UtilsClass.getDeclaredConstructor().newInstance();
        // 获取方法并调用
        Method decryptMethod = sm4UtilsClass.getMethod("sm2DecryptBase64", String.class);
        String invoke = (String) decryptMethod.invoke(obj, key);
        System.out.println(invoke);
    }

    public static JSONObject getEnergyUseInfos(JSONObject jsonObject) {
        // 调用指定方法
        return StirparModelCalculate.createReport(jsonObject);
    }
}