package com.util;

import com.business.domain.ImputationData;
import com.business.service.ImputationDataService;
import com.sooka.common.utils.DateUtils;
import com.sooka.common.utils.StringUtils;
import com.sooka.system.service.ITULogService;
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.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author limeng
 * @date 2022年10月11日 8:50
 */
@Configuration
@EnableScheduling
public class StaticScheduleTask {

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private ITULogService logService;

    @Autowired
    private ImputationDataService imputationDataService;

    /**添加定时任务 每天凌晨1点**/
    //@Scheduled(cron = "0 0 1 * * ?")
    private void configureTasks() {
        for(int i=0;i<getYears().length;i++){
            Map map = logService.selectImputationLog(getYears()[i]);
            try {
                ImputationData imputationData = new ImputationData();
                imputationData.setYear(getYears()[i]);
                ImputationData imd = imputationDataService.selectImputationData(imputationData);
                ImputationData id = (ImputationData) mapToBean(map,new ImputationData().getClass());
                if(imd == null){
                    imputationDataService.insertImputationData(id);
                }
                imputationDataService.updateImputationData(id);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**获取当前年和前四年的年份**/
    private String[] getYears() {
        String[] arr = new String[5];
        for(int i=0;i<arr.length;i++){
            arr[i] = getYears(i-4);
        }
        return arr;
    }

    /**
     * @Description 获取年份
     * @param num 负数为之前年,0为当前年,正数为之后年
     * @Throws
     * @Return java.lang.String
     * @Date 2022-10-12 10:28:15
     * @Author
     **/
    public static String getYears(int num) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.YEAR, num);
        Date y = c.getTime();
        return format.format(y);
    }

    /**比较两个日期大小**/
    private boolean daysBefore(String time) {
        Calendar calendar = null;
        try {
            calendar = getCalendar(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar now = Calendar.getInstance();
        return calendar.before(now);
    }

    /**将String时间转换为Calendar**/
    private static Calendar getCalendar(String time) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(simpleDateFormat.parse(time));
        return calendar;
    }

    /**
     * 利用反射将map集合封装成bean对象
     *
     * @param map
     * @param clazz
     * @return
     */
    public static <T> T mapToBean(Map<String, Object> map, Class<?> clazz) throws Exception {
        Object obj = clazz.newInstance();
        if (map != null && !map.isEmpty() && map.size() > 0) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                // 属性名
                String propertyName = entry.getKey();
                // 属性值
                Object value = entry.getValue();
                String setMethodName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
                //获取和map的key匹配的属性名称
                Field field = getClassField(clazz, propertyName);
                if (field == null){
                    continue;
                }
                Class<?> fieldTypeClass = field.getType();
                value = convertValType(value, fieldTypeClass);
                try {
                    clazz.getMethod(setMethodName, field.getType()).invoke(obj, value);
                } catch (NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
        }
        return (T) obj;
    }

    /**
     * 根据给定对象类匹配对象中的特定字段
     * @param clazz
     * @param fieldName
     * @return
     */
    private static Field getClassField(Class<?> clazz, String fieldName) {
        if (Object.class.getName().equals(clazz.getName())) {
            return null;
        }
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            if (field.getName().equals(fieldName)) {
                return field;
            }
        }
        //如果该类还有父类，将父类对象中的字段也取出
        Class<?> superClass = clazz.getSuperclass();
        //递归获取
        if (superClass != null) {
            return getClassField(superClass, fieldName);
        }
        return null;
    }

    /**
     * 将map的value值转为实体类中字段类型匹配的方法
     * @param value
     * @param fieldTypeClass
     * @return
     */
    private static Object convertValType(Object value, Class<?> fieldTypeClass) {
        Object retVal = null;
        if (Long.class.getName().equals(fieldTypeClass.getName())
                || long.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Long.parseLong(value.toString());
        } else if (Integer.class.getName().equals(fieldTypeClass.getName())
                || int.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Integer.parseInt(value.toString());
        } else if (Float.class.getName().equals(fieldTypeClass.getName())
                || float.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Float.parseFloat(value.toString());
        } else if (Double.class.getName().equals(fieldTypeClass.getName())
                || double.class.getName().equals(fieldTypeClass.getName())) {
            retVal = Double.parseDouble(value.toString());;
        } else {
            retVal = value.toString();
        }
        return retVal;
    }




}
