package com.liang.common.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.exceptions.ValidateException;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 说明：常用工具
 */
@Slf4j
public class Tools {


    private static Random rand;  // SecureRandom is preferred to Random

    static {
        try {
            rand = SecureRandom.getInstanceStrong();
        } catch (NoSuchAlgorithmException e) {
            log.error("init error", e);
        }

    }


    private Tools() {
    }

    /**
     * 随机生成六位数验证码
     *
     * @return
     */
    public static int getRandomNum() {
//        Random r = new Random();

        return rand.nextInt(900000);//(Math.random()*(999999-100000)+100000)
    }

    /**
     * 随机生成四位数验证码
     *
     * @return
     */
    public static int getRandomNum4() {
//        Random r = new Random();
        return rand.nextInt(9000) + 1000;
    }


    /**
     * 随机生成四位数验证码
     *
     * @return
     */
    public static int getRandomNumLen(int bound) {
//        Random r = new Random();
        return rand.nextInt(bound);
    }

    public static Random getRandom() {
        return rand;
    }

    /**
     * 往文件里的内容
     *
     * @param fileP   文件路径
     * @param content 写入的内容
     */
    public static void writeFile(String fileP, String content) throws IOException {
        String filePath = (Thread.currentThread().getContextClassLoader().getResource("")) + "../../";    //项目路径
        filePath = filePath.replace("file:/", "");
        filePath = filePath.replace("%20", " ");
        filePath = filePath.trim() + fileP.trim();
        if (filePath.indexOf(":") != 1) {
            filePath = File.separator + filePath;
        }
        try (OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(filePath), "utf-8");
             BufferedWriter writer = new BufferedWriter(write);) {
            writer.write(content);
        } catch (IOException e) {
            throw e;
        }
    }

    public static String getString(Map map, String key) {
        if (map == null || key == null) {
            return "";
        }
        Object v = map.get(key);
        return v == null ? "" : v.toString();
    }

    /**
     * 检测字符串是否不为空(null,"","null")
     *
     * @param s
     * @return 不为空则返回true，否则返回false
     */
    public static boolean notEmpty(String s) {
        return !isEmpty(s);
    }


    /**
     * 集合是否为非空
     *
     * @param collection 集合
     * @return 是否为非空
     */
    public static boolean notEmpty(Collection<?> collection) {
        return !isEmpty(collection);
    }


    /**
     * 检测字符串是否不为空(null,"")
     *
     * @param obj
     * @return 不为空则返回true，否则返回false
     */
    public static boolean notEmpty(Object obj) {
        return !isEmpty(obj);
    }


    /**
     * 数组是否为非空
     *
     * @param <T>   数组元素类型
     * @param array 数组
     * @return 是否为非空
     */
    public static <T> boolean notEmpty(T[] array) {
        return !isEmpty(array);
    }

    /**
     * 检测字符串是否为空(null,"","null")
     *
     * @param s
     * @return 为空则返回true，不否则返回false
     */
    public static boolean isEmpty(String s) {
        return s == null || "".equals(s) || "null".equals(s);
    }


    /**
     * 集合是否为空
     *
     * @param collection 集合
     * @return 是否为空
     */
    public static boolean isEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }

    /**
     * 检测字符串是否为空(null,"","null")
     *
     * @param obj
     * @return 为空则返回true，不否则返回false
     */
    public static boolean isEmpty(Object obj) {
        if (obj instanceof String) {
            return isEmpty((String) obj);//TODO
        } else {
            return null == obj;
        }
    }

    /**
     * 数组是否为空
     *
     * @param <T>   数组元素类型
     * @param array 数组
     * @return 是否为空
     */
    public static <T> boolean isEmpty(T[] array) {
        return array == null || array.length == 0;
    }

    /**
     * 字符串转换为字符串数组
     *
     * @param str        字符串
     * @param splitRegex 分隔符
     * @return
     */
    public static String[] str2StrArray(String str, String splitRegex) {
        if (isEmpty(str)) {
            return null;
        }
        return str.split(splitRegex);
    }

    /**
     * 用默认的分隔符(,)将字符串转换为字符串数组
     *
     * @param str 字符串
     * @return
     */
    public static String[] str2StrArray(String str) {
        return str2StrArray(str, ",\\s*");
    }

    /**
     * 按照yyyy-MM-dd HH:mm:ss的格式，日期转字符串
     *
     * @param date
     * @return yyyy-MM-dd HH:mm:ss
     */
    public static String date2Str(Date date) {
        return date2Str(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 按照yyyy-MM-dd HH:mm:ss的格式，字符串转日期
     *
     * @param date
     * @return
     */
    public static Date str2Date(String date) {
        if (notEmpty(date)) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                return sdf.parse(date);
            } catch (ParseException e) {
                log.error("", e);
            }
            return new Date();
        } else {
            return null;
        }
    }

    /**
     * 按照参数format的格式，日期转字符串
     *
     * @param date
     * @param format
     * @return
     */
    public static String date2Str(Date date, String format) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            return sdf.format(date);
        } else {
            return "";
        }
    }

    /**
     * 把时间根据时、分、秒转换为时间段
     *
     * @param StrDate
     */
    public static String getTimes(String StrDate) {
        String resultTimes = "";

        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        java.util.Date now;

        try {
            now = new Date();
            java.util.Date date = df.parse(StrDate);
            long times = now.getTime() - date.getTime();
            long day = times / (24 * 60 * 60 * 1000);
            long hour = (times / (60 * 60 * 1000) - day * 24);
            long min = ((times / (60 * 1000)) - day * 24 * 60 - hour * 60);
            long sec = (times / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);

            StringBuffer sb = new StringBuffer();
            //sb.append("发表于：");
            if (hour > 0) {
                sb.append(hour + "小时前");
            } else if (min > 0) {
                sb.append(min + "分钟前");
            } else {
                sb.append(sec + "秒前");
            }

            resultTimes = sb.toString();
        } catch (ParseException e) {
            log.error("", e);
        }

        return resultTimes;
    }


    /**
     * 读取txt里的全部内容
     *
     * @param fileP    文件路径
     * @param encoding 编码
     * @return
     */
    public static String readTxtFileAll(String fileP, String encoding) throws IOException {
        StringBuffer fileContent = new StringBuffer();
        try {
            String filePath = String.valueOf(Thread.currentThread().getContextClassLoader().getResource("")) + "../../";    //项目路径
            filePath = filePath.replaceAll("file:/", "");
            filePath = filePath.replaceAll("%20", " ");
            filePath = filePath.trim() + fileP.trim();
            if (filePath.indexOf(":") != 1) {
                filePath = File.separator + filePath;
            }
            File file = new File(filePath);
            if (file.isFile() && file.exists()) {        // 判断文件是否存在
                try (InputStreamReader read = new InputStreamReader(
                        new FileInputStream(file), encoding);    // 考虑到编码格式
                     BufferedReader bufferedReader = new BufferedReader(read);) {
                    String lineTxt;
                    while ((lineTxt = bufferedReader.readLine()) != null) {
                        fileContent.append(lineTxt);
                        fileContent.append("\n");
                    }
                }
            } else {
                throw new FileNotFoundException("找不到指定的文件,查看此路径是否正确:" + filePath);
            }
        } catch (IOException e) {
            throw new IOException("读取文件内容出错" + e.getMessage());
        }
        return fileContent.toString();
    }


    public static boolean isEmail(String email) {
        return Validator.isMatchRegex("^[A-Za-z0-9+_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+$", email);
    }

    public static boolean isMobile(String phone) {
        return Validator.isMobile(phone);
    }


    /**
     * 获取周末  月从0开始
     *
     * @param year
     * @param mouth
     * @return
     */
    public static Set<String> getMonthWekDay(int year, int mouth) {
        Set<String> dateList = new HashSet<>();
        SimpleDateFormat simdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = new GregorianCalendar(year, mouth, 1);
        Calendar endCalendar = new GregorianCalendar(year, mouth, 1);
        endCalendar.add(Calendar.MONTH, 1);
        while (true) {
            int weekday = calendar.get(Calendar.DAY_OF_WEEK);
            if (weekday == 1 || weekday == 7) {
                dateList.add(simdf.format(calendar.getTime()));
            }
            calendar.add(Calendar.DATE, 1);
            if (calendar.getTimeInMillis() >= endCalendar.getTimeInMillis()) {
                break;
            }
        }
        return dateList;
    }


    /**
     * @param obj 实体
     * @return 全部不为空并且全部不为null, 则返回true;否则返回false
     */
    public static boolean allNotEmpty(Object... obj) {
        for (Object o : obj) {
            if (Tools.isEmpty(o)) {
                return false;
            }
        }
        return true;
    }
}
