package com.njcn.common.utils;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;

import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import static java.lang.Integer.parseInt;


/**
 * @author hongawen
 * @version 1.0.0
 * @date 2021年04月12日 14:21
 */
public class PubUtils {

    private final static ObjectMapper MAPPER = new ObjectMapper();

    private static final String DATE_TIME = "yyyy-MM-dd HH:mm:ss";

    private static final String DATE = "yyyy-MM-dd";

    private static final String TIME = "HH:mm:ss";


    /**
     * 生成随机码，包含字母。--> 大写
     *
     * @param length 随机码长度
     */
    public static String randomCode(int length) {
        return RandomUtil.randomString(length).toUpperCase(Locale.ENGLISH);
    }


    /****
     * ***** ***** 验证IP是否属于某个IP段 ipSection IP段（以'-'分隔） ip 所验证的IP号码 ***** *****
     **/
    public static boolean ipExistsInRange(String ip, String ipSection) {
        ipSection = ipSection.trim();
        ip = ip.trim();
        int idx = ipSection.indexOf('-');
        String beginIp = ipSection.substring(0, idx);
        String endIp = ipSection.substring(idx + 1);
        return getIp2long(beginIp) <= getIp2long(ip) && getIp2long(ip) <= getIp2long(endIp);
    }

    private static long getIp2long(String ip) {
        ip = ip.trim();
        String[] ips = ip.split("\\.");
        long ip2long = 0L;
        for (int i = 0; i < 4; ++i) {
            ip2long = ip2long << 8 | parseInt(ips[i]);
        }
        return ip2long;
    }

    /**
     * 获取当前时间
     *
     * @author cdf
     * @date 2021/7/26
     */
    public static String getNow() {
        DateFormat bf = new SimpleDateFormat("yyyyMMddHHmmss");
        return bf.format(new Date());
    }

    /**
     * 获取当前web的IP
     */
    public static String getLocalIp() {
        String host;
        try {
            host = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
            host = "127.0.0.1";
        }
        return host;
    }

    /**
     * 将JSON转为实体对象
     *
     * @param jsonStr    json
     * @param targetType 对象类型
     * @param <T>        对象
     */
    public static <T> T json2obj(String jsonStr, Type targetType) {
        try {
            JavaType javaType = TypeFactory.defaultInstance().constructType(targetType);
            MAPPER.registerModule(new JavaTimeModule());
            MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
            return MAPPER.readValue(jsonStr, javaType);
        } catch (IOException e) {
            throw new IllegalArgumentException("将JSON转换为对象时发生错误:" + jsonStr, e);
        }
    }

    /**
     * 判断一个数字是否在区间内
     *
     * @param current 待判断数字
     * @param min     最小值
     * @param max     最大值
     */
    public static boolean rangeInDefined(int current, int min, int max) {
        return Math.max(min, current) == Math.min(current, max);
    }

    /**
     * 将起始日期字符串 yyyy-MM-dd  转为 yyyy-MM-dd HH:mm:ss的LocalDateTime
     */
    public static LocalDateTime beginTimeToLocalDateTime(String beginTime){
        beginTime = beginTime + StrUtil.SPACE + "00:00:00";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME);
        return  LocalDateTime.parse(beginTime, dateTimeFormatter);
    }

    /**
     * 将截止日期字符串 yyyy-MM-dd  转为 yyyy-MM-dd HH:mm:ss的LocalDateTime
     */
    public static LocalDateTime endTimeToLocalDateTime(String endTime){
        endTime = endTime + StrUtil.SPACE + "23:59:59";
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME);
        return  LocalDateTime.parse(endTime, dateTimeFormatter);
    }

    /**
     * 将字符串日期转为LocalDate日期（只用于日期转换）
     */
    public static LocalDate localDateFormat(String time){
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE);
        return LocalDate.parse(time,dateTimeFormatter);
    }

    public static LocalDateTime localDateTimeFormat(String time){
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATE_TIME);
        return LocalDateTime.parse(time,dateTimeFormatter);
    }

    /**
     * 用于获取对象中，前缀一样，后缀为2~50的属性值
     * @param object 待操作对象
     * @param methodPrefix 方法前缀
     * @param number 方法后缀
     * @return 对象属性值
     */
    public static Float getValueByMethod(Object object, String methodPrefix, Integer number) {
        try {
            Method method = object.getClass().getMethod(methodPrefix + number);
            return (Float) method.invoke(object);
        } catch (Exception e) {
            throw new BusinessException(CommonResponseEnum.REFLECT_METHOD_EXCEPTION);
        }
    }

    public static List<String> getStartTimeEndTime(String beginDate, String endDate) throws Exception {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(beginDate));
        List<String> startTimeEndTime = null;
        for (long d = cal.getTimeInMillis(); d <= sdf.parse(endDate).getTime(); d = getDplaus(cal)) {
            startTimeEndTime.add(sdf.format(d));
        }
        return startTimeEndTime;
    }

    public static long getDplaus(Calendar c) {
        c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) + 1);
        return c.getTimeInMillis();
    }

    public static String comFlag(Integer comFlag) {
        switch (comFlag) {
            case 0:
                return "中断";
            case 1:
                return "正常";
            default:
                return "";
        }
    }

    public static String runFlag(Integer runFlag) {
        switch (runFlag) {
            case 0:
                return "投运";
            case 1:
                return "热备用";
            case 2:
                return "停运";
            default:
                return "";
        }
    }

    public static String ptType(Integer ptType) {
        switch (ptType) {
            case 0:
                return "星型接线";
            case 1:
                return "三角型接线";
            case 2:
                return "开口三角型接线";
            default:
                return "";
        }
    }
}
