package com.xiaomai.utils;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class CommUtil {
    public static Date now = new Date();

    public static String getCurrentTime() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.toString();
    }

    public static String getTimeStamp() {
        Long ct = System.currentTimeMillis();
        return ct.toString();
    }

    /**
     * 获取配置文件指出参数信息
     *
     * @return 返回一个文件对象
     */
    public static Properties getconfig() {
        Properties prop = null;

        try {
//          数据流的形式读取配置文件
            prop = new Properties();
            FileInputStream fis = new FileInputStream(System.getProperty("user.dir") +
                    "/src/main/resources/config.properties");
            prop.load(fis);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return prop;

    }

    //把JavaBean转化为map
    public static Map<String, String> bean2map(Object bean) {
        Map<String, String> map = new HashMap<>();
        //获取JavaBean的描述器
        try {
            BeanInfo b = Introspector.getBeanInfo(bean.getClass(), Object.class);
            //获取属性描述器
            PropertyDescriptor[] pds = b.getPropertyDescriptors();
            for (PropertyDescriptor pd : pds) {
                String propertyName = pd.getName();
                Method m = pd.getReadMethod();
                Object properValue = m.invoke(bean);
                if (null != properValue) {
                    map.put(propertyName, properValue.toString());
                }
            }
        } catch (Exception e) {
            return null;
        } finally {
            return map;
        }

    }

    /**
     * 在当前时间上增加days天，days – 可以为负
     *
     * @param days
     * @return
     */
    public static Date addDay(int days) {
        return new LocalDate().plusDays(days).toDate();
    }

    public static String getFormatTimeStr(Date date, String format) {
        assert date != null;
        try {
            return new SimpleDateFormat(format).format(date);
        } catch (Exception ignored) {
            return "";
        }
    }

    /**
     * 获取日期的时间戳格式
     *
     * @param time    制定日期时间,根据pattern格式传值
     * @param pattern 时间格式 比如1>yyyy-MM-dd HH:mm:ss 2>yyyy-MM-dd 3>yyyy-MM-dd HH:mm
     * @return
     */
    public static String getStringTimestamp(String time, String pattern) {
        Date date = null;
        try {
            date = getFormattedDate(time, pattern);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date.getTime() + "";

    }

    /**
     * 将指定格式的日期时间字符串，转换为Date
     * 若 指定格式 与 日期时间字符串 不一致时，会抛出转换异常
     *
     * @param dateStr 日期时间字符串
     * @param format  指定格式
     * @return
     * @throws ParseException
     */
    public static Date getFormattedDate(String dateStr, String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(dateStr);
    }


    /**
     * 获取当前时间+n天的日期时间戳，一般是开始日期的时间戳 00：00：00
     *
     * @return
     */
    public static String oneKeyGetAddDay(int day) {
        Date getAddDayData = addDay(day);//获取本周的第一天
        String getAddDayDataString = getFormatTimeStr(getAddDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getAddDayDataString, "yyyy-MM-dd HH:mm:ss");
    }


    public static Date getStartOfDateWeek(Date date) {
        return new DateTime(date).withDayOfWeek(1).withTimeAtStartOfDay().toDate();
    }

    /**
     * 获取本周第一天
     *
     * @return
     */
    public static String oneKeyGetWeekStartDay() {
        Date getWeekStartDayData = getStartOfDateWeek(now);//获取本周的第一天
        String getWeekStartDay = getFormatTimeStr(getWeekStartDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getWeekStartDay, "yyyy-MM-dd HH:mm:ss");
    }

    public static Date getEndOfDateWeek(Date date) {
        return new DateTime(date).withDayOfWeek(7).withTime(23, 59, 59, 0).toDate();
    }

    /**
     * 获取本周最后一天
     *
     * @return
     */
    public static String oneKeyGetWeekEndDay() {
        Date getWeekEndDayData = getEndOfDateWeek(now);//获取本周的最后一天
        String getWeekEndDay = getFormatTimeStr(getWeekEndDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getWeekEndDay, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取下周第一天
     * @return
     */
    public static String oneKeyGetNextWeekStartDay() {
        Date getWeekStartDayData = getStartOfDateWeek(now);//获取本周的第一天
        Date getNextWeekStartDayData=addNDays(getWeekStartDayData,7);
        String getNextWeekStartDay = getFormatTimeStr(getNextWeekStartDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNextWeekStartDay, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取下周最后一天
     * @return
     */
    public static String oneKeyGetNextWeekEndDay() {
        Date getWeekEndDayData = getEndOfDateWeek(now);//获取本周的最后一天
        Date getNextWeekEndDayData =addNDays(getWeekEndDayData,7);
        String getNextWeekEndDay = getFormatTimeStr(getNextWeekEndDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNextWeekEndDay, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取下周某一天（结束日期）
     * @param n ，n=7是下周最后一天周日，n=6下周周六，n=5下周周五，n=4下周周四
     * @return
     */
    public static String oneKeyGetNextWeekEndXDay(int n) {
        Date getWeekEndDayData = getEndOfDateWeek(now);//获取本周的最后一天
        Date getNextWeekEndDayData =addNDays(getWeekEndDayData,n);
        String getNextWeekEndDay = getFormatTimeStr(getNextWeekEndDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNextWeekEndDay, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取下周某一天（开始时间）
     * @param n 以7为基数（7是周一），+1（8）是周二，+2（9）是周三，10是周四
     * @return
     */
    public static String oneKeyGetNextWeekXDay(int n) {
        Date getWeekStartDayData = getStartOfDateWeek(now);//获取本周的第一天
        Date getNextWeekStartDayData=addNDays(getWeekStartDayData,n);
        String getNextWeekStartDay = getFormatTimeStr(getNextWeekStartDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNextWeekStartDay, "yyyy-MM-dd HH:mm:ss");
    }



    /**
     * 获取下下周的某一天的开始时间
     * @param n，7是下下周一，8是下下周2
     * @return
     */
    public static String oneKeyGetNextNextWeekXStartDay(int n){
        Date getWeekStartDayData = getStartOfDateWeek(now);//获取本周的第一天
        Date getNextWeekStartDayData=addNDays(getWeekStartDayData,7);//下周第一天
        Date getNextNextWeekStartDayData=addNDays(getNextWeekStartDayData,n);
        String getNextNextWeekXStartDay = getFormatTimeStr(getNextNextWeekStartDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNextNextWeekXStartDay, "yyyy-MM-dd HH:mm:ss");

    }

    public static Date getEndOfDay(Date date) {
        assert date != null;
        return new DateTime(date).withTime(23, 59, 59, 999).toDate();
    }

    /**
     * 设定时间+N天
     *
     * @param date 设置的时间  Date now=new Date();
     * @param n    天
     * @return
     */
    public static Date addNDays(Date date, int n) {
        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.add(Calendar.DAY_OF_MONTH, n);
        return now.getTime();

    }

    /**
     * 当前时间+n天结束日期时间戳 23：59：59
     * @param n
     * @return
     */
    public static String getNDayEndTimeTamp(int n){
        Date now = new Date();
        Date totalDate = addNDays(now, n);
        String getNDayEndTime = getFormatTimeStr(getEndOfDay(totalDate), "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNDayEndTime, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取当前时间整点时间戳
     */
    public static Long getWholeHourTimestamp(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MINUTE, 60);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Long wholeHourTimestamp = calendar.getTimeInMillis();
        System.out.println("整点时间戳: " + wholeHourTimestamp);
        return wholeHourTimestamp;
    }

    /**
     *获取指定时间的整点
     * @param n 整数
     * @param time 整点时间 比如13：00
     * @return
     */
    public static String getWholeHourTimeStamp(int n,String time){
        Date getWeekStartDayData = CommUtil.getStartOfDateWeek(now);
        Date getNextWeekXDayData = CommUtil.addNDays(getWeekStartDayData, n);
        String getNextWeekXDayDataS = new SimpleDateFormat("yyyy-MM-dd").format(getNextWeekXDayData.getTime());
        return CommUtil.getStringTimestampByStrTime(getNextWeekXDayDataS + " " + time);

    }



    public static String getStringTimestampByStrTime(String time) {
        String timestamp = null;
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        java.util.Date date = null;
        try {
            date = df.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        long timestamp1 = cal.getTimeInMillis();
        timestamp = Long.toString(timestamp1);
        return timestamp;

    }

    //@Test
    public void test() {
        //当天时间戳格式：2024-6-12 00：00：00点
        System.out.println("当前时间时间戳" + oneKeyGetAddDay(0));
        System.out.println("****" +getNDayEndTimeTamp(0));

    }

    /**
     * 获取指定周的某一天的开始时间00，比如下周的第一天，下周的第二天
     * @param day ，0就是周的第一天，1是周二，2是周三，3是周四，4是周五，5是周六，6是周日
     * @param week 周为单位，1是当前周加1周即为下周，2就是下下周，0就是代表本周
     * @return
     */

    public static String  getXStartOfDateNextXWeek(int day,int week) {
        Date getNextXWeekStartDayData= new DateTime(now).withDayOfWeek(1).plusWeeks(week).withTimeAtStartOfDay().toDate();
        Date getNextXWeekStartXDayData=addNDays(getNextXWeekStartDayData,day);
        String getNextXWeekStartXDayDataS = getFormatTimeStr(getNextXWeekStartXDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNextXWeekStartXDayDataS, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 获取指定周的某一天的结束时间23：59，比如下周的最后一天天，下下周的第二天
     * @param day 0表示某周的最后一天，-1表示某周的周六,-2周五，-3周四，-4周三，-5周二，-6周一
     * @param week 周为单位，1是当前周加1周即为下周，2就是下下周，0就是代表本周
     * @return
     */
    public static String  getXEndOfDateNextXWeek(int day,int week) {
        Date getNextXWeekEndDayData= new DateTime(now).withDayOfWeek(7).plusWeeks(2).withTime(23, 59, 59, 0).toDate();
        Date getNextXWeekEndXDayData=addNDays(getNextXWeekEndDayData,day);
        String getNextXWeekEndXDayDataS = getFormatTimeStr(getNextXWeekEndXDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNextXWeekEndXDayDataS, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 晚于当前时间 多少分钟
     * @param minutes 分钟
     * @return
     */
    public static String getTodayGoalTime(int minutes){
        Date getNextXWeekStartDayData= new DateTime(now).plusMinutes(minutes).toDate();
        String getNextXWeekStartXDayDataS = getFormatTimeStr(getNextXWeekStartDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        return getStringTimestamp(getNextXWeekStartXDayDataS, "yyyy-MM-dd HH:mm:ss");
    }


    public static void main(String[] args) {
     /*   getWholeHourTimestamp();
        Date getWeekStartDayData = getStartOfDateWeek(now);//获取本周的第一天
        Date getNextWeekXDayData=addNDays(getWeekStartDayData,9);
        String getNextWeekXDayDataS = new SimpleDateFormat("yyyy-MM-dd").format(getNextWeekXDayData.getTime());
        String startStamp = getStringTimestampByStrTime(getNextWeekXDayDataS + " " + "14:00");
        System.out.println("********"+startStamp);

        long currentTimestamp = System.currentTimeMillis();
        // 在当前时间的基础上，加上2秒（2000毫秒）
        long futureTimestamp = currentTimestamp + 2000;

        // 输出未来时间戳
        System.out.println("当前时间戳: " + currentTimestamp);
        System.out.println("未来2秒后的时间戳: " + futureTimestamp);


        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println("当前时间: " + now);

        // 延后2秒
        LocalDateTime future = now.plusSeconds(2);
        System.out.println("未来2秒时间: " + future);

        System.out.println("%%%%%"+getXEndOfDateNextXWeek(-1,2));*/

        Date getNextXWeekStartDayData= new DateTime(now).plusMinutes(30).toDate();
        String getNextXWeekStartXDayDataS = getFormatTimeStr(getNextXWeekStartDayData, "yyyy-MM-dd HH:mm:ss");//时间格式转化为string
        System.out.println( "((((((("+getStringTimestamp(getNextXWeekStartXDayDataS, "yyyy-MM-dd HH:mm:ss"));







    }


}
