package com.bonus.common.biz.config;

import lombok.extern.slf4j.Slf4j;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;

/**
 * @Author ma_sh
 * @create 2024/10/22 14:36
 */
@Slf4j
public class DateTimeHelper {

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

    /**
     * 获取当前时间的年份
     *
     * @return
     */
    public static String getNowYear() {
        return format(new Date(), "yyyy");
    }

    public static String getNowMonthAndDay() {
        return format(new Date(), "MM-dd");
    }

    public static String getYear(Date d) {
        int year = d.getYear() + 1900;
        return year + "";
    }



    /**
     * 格式化 时间
     *
     * @param format
     * @return
     */
    public static String format(Date d, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        return df.format(d);
    }

    public static String format(String str, String format, String disFormat) {
        Date d = parse(str, format);
        return format(d, disFormat);
    }

    /**
     * 格式化 时间
     *
     * @param format
     * @return
     */
    public static String format(Date d, DateFormat format) {
        return format.format(d);
    }

    /**
     * 格式化 时间
     *
     * @param format
     * @return Date
     * @throws ParseException
     */
    public static Date parse(String dateStr, String format) {
        SimpleDateFormat df = new SimpleDateFormat(format);
        try {
            return df.parse(dateStr);
        } catch (ParseException e) {
            return new Date();
        }
    }

    public static Date parse(String dateStr, String format, Date d) {
        try {
            SimpleDateFormat df = new SimpleDateFormat(format);
            return df.parse(dateStr);
        } catch (Exception e) {
            return d;
        }
    }

    /**
     * 解析时间
     *
     * @return Date
     * @throws ParseException
     */
    public static Date parse(String dateStr, DateFormat format) throws ParseException {
        return format.parse(dateStr);
    }

    public static Date parseDate(String dateStr) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.parse(dateStr);
    }

    /**
     * 获取当前时间的年月
     *
     * @return
     */
    public static String getPrevMonth() {
        return minusMonth(new Date(), 1);
    }

    /**
     * 获取当前时间的上个年月
     *
     * @return
     */
    public static String getNowMonth() {
        return format(new Date(), "yyyy-MM");
    }

    /**
     * 获取当前时间的上个年月格式化
     *
     * @return
     */
    public static String getNowMonthFomart() {
        return format(new Date(), "yyyyMM");
    }

    /**
     * 获取当前时间的前一天
     *
     * @return
     */
    public static String getPreDate(String dateStr) {
        Date date = parse(dateStr, "yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DAY_OF_MONTH, -1);
        return format(c.getTime(), "yyyy-MM-dd");
    }

    /**
     * 获取当前时间的上一个月
     *
     * @return
     */
    public static String getPreMonthDate() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月
        date = calendar.getTime();
        return format(date, "yyyy-MM-dd");
    }

    public static String getPreMonth() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月
        date = calendar.getTime();
        return format(date, "yyyy-MM");
    }

    /**
     * 获取当前时间的前两个月
     *
     * @return
     */
    public static String getTwoMonthDate() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 2); // 设置为前两个月
        date = calendar.getTime();
        return format(date, "yyyy-MM-dd");
    }

    /**
     * 获取当前时间的上一年
     *
     * @return
     */
    public static String getPreYearDate() {
        Date date = new Date();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date); // 设置为当前时间
        calendar.set(Calendar.YEAR, calendar.get(Calendar.YEAR) - 1); // 设置为上一年
        date = calendar.getTime();
        return format(date, "yyyy-MM-dd");
    }

    /**
     * 获取当前时间的年月日
     *
     * @return
     */
    public static String getNowDate() {
        return format(new Date(), "yyyy-MM-dd");
    }

    public static String getNowDateFomart() {
        return format(new Date(), "yyyyMMdd");
    }

    /**
     * 明年的昨天
     *
     * @param dateStr
     * @return
     */
    public static String getNextYearDate(String dateStr) {
        Date date = parse(dateStr, "yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, 1);
        c.add(Calendar.DAY_OF_MONTH, -1);
        return format(c.getTime(), "yyyy-MM-dd");
    }

    /**
     * 获取前年
     *
     * @param dateStr
     * @return
     */
    public static String getBeforeYearDate(String dateStr) {
        Date date = parse(dateStr, "yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, -1);
//		c.add(Calendar.DAY_OF_MONTH, 1);
        return format(c.getTime(), "yyyy-MM-dd");
    }

    /**
     * 获取明天时间的年月日
     *
     * @return
     */
    public static String getTomorrowDate(String nowDate) {
        Date date = parse(nowDate, "yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.DATE, 1);
        return format(c.getTime(), "yyyy-MM-dd");
    }

    /**
     * 获取当前时间
     *
     * @return
     */
    public static String getNowTime() {
        return format(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    public static String getNowTimeFomart() {
        return format(new Date(), "yyyyMMddHHmmss");
    }

    public static String getNextYear() {
        return format(new Date(), "yyyy-MM-dd HH:mm:ss");
    }

    /**
     *
     * @return
     */
    public static String minusMonth(Date date, int c) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
        try {
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            cal.add(Calendar.MONTH, -c);
            return format(cal.getTime(), df);
        } catch (Exception e) {
            return format(date, df);
        }
    }

    /**
     *
     * @param month
     * @return
     */
    public static String minusMonth(String month, int c) {
        try {
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM");
            Date date = parse(month, df);

            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            cal.add(Calendar.MONTH, -c);

            return format(cal.getTime(), df);
        } catch (Exception e) {
            return month;
        }
    }

    /**
     *
     * @return
     */
    public static Date minus(Date d, int type, int c) {
        try {
            Calendar cal = Calendar.getInstance();
            cal.setTime(d);
            cal.add(type, -c);
            return cal.getTime();
        } catch (Exception e) {
            return new Date();
        }
    }

    /**
     * 得到前一个月
     *
     * @param month
     * @return
     */
    public static String prevMonth(String month) {
        return minusMonth(month, 1);
    }

    /**
     * 得到前一个月
     *
     * @param month
     * @return
     */
    public static String prevMonth(String month, int c) {
        return minusMonth(month, c);
    }

    public static float duration(String startTime, String stopTime) {
        Date sd = DateTimeHelper.parse(startTime, "yyyy-MM-dd HH:mm");
        long sl = sd.getTime();

        Date ed = DateTimeHelper.parse(stopTime, "yyyy-MM-dd HH:mm");
        long el = ed.getTime();

        float l = el - sl;
        if (l <= 0) {
            l = 0;
        }
        l = l / (1000 * 60);
        return l;
    }

    public static String getStartYearMonthBySeason(String year, int season) {
        switch (season) {
            case 1:
                return getYearMonth(year, "01");
            case 2:
                return getYearMonth(year, "04");
            case 3:
                return getYearMonth(year, "07");
            case 4:
                return getYearMonth(year, "10");
            default:
                return getYearMonth(year, "01");
        }
    }

    private static String getYearMonth(String year, String month) {
        return year + "-" + month;
    }

    public static String getEndYearMonthBySeason(String year, int season) {
        switch (season) {
            case 1:
                return getYearMonth(year, "03");
            case 2:
                return getYearMonth(year, "06");
            case 3:
                return getYearMonth(year, "09");
            case 4:
                return getYearMonth(year, "12");
            default:
                return getYearMonth(year, "03");
        }
    }

    public static String getAddNumDay(String giveTime, int addDay) {
        String time = giveTime;
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance();
        try {
            date = sdf.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, +addDay);// +1今天的时间加一天
        date = calendar.getTime();
        time = sdf.format(date);
        return time;
    }

    /**
     * date2比date1多的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDays(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);
        int day1 = cal1.get(Calendar.DAY_OF_YEAR);
        int day2 = cal2.get(Calendar.DAY_OF_YEAR);

        int year1 = cal1.get(Calendar.YEAR);
        int year2 = cal2.get(Calendar.YEAR);
        if (year1 != year2) // 同一年
        {
            int timeDistance = 0;
            for (int i = year1; i < year2; i++) {
                if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) // 闰年
                {
                    timeDistance += 366;
                } else // 不是闰年
                {
                    timeDistance += 365;
                }
            }

            return timeDistance + (day2 - day1);
        } else // 不同年
        {
//			System.out.println("判断day2 - day1 : " + (day2 - day1));
            return day2 - day1;
        }
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        int days = (int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24));
        return days;
    }

    public static int calcDate(String dateStr, String dateStr2) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = format.parse(dateStr);
            Date date2 = format.parse(dateStr2);
            return DateTimeHelper.differentDays(date, date2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    // 判断时间date1是否在时间date2之前
    // 时间格式 2005-4-21
    public static boolean isDateBefore(String date1, String date2) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date bt = sdf.parse(date1);
            Date et = sdf.parse(date2);
            if (bt.before(et)) {
                return true;
            } else {
                return false;
            }

        } catch (ParseException e) {
            System.out.print("[SYS] " + e.getMessage());
            return false;
        }
    }

    public static boolean isFirstDay() {
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        return c.get(Calendar.DAY_OF_MONTH) == 1;
    }

    public static String getFirstDay() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        // 获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, 0);
        c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        String first = format.format(c.getTime());
        return first;
    }


    public static String getLastDay() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        // 获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        String last = format.format(ca.getTime());
        return last;
    }

    public static String getPreFirstDay() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        // 获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -1);
        c.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天
        String first = format.format(c.getTime());
        return first;
    }

    public static String getPreLastDay() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        // 获取当前月最后一天
        Calendar c = Calendar.getInstance();
        c.add(Calendar.MONTH, -1);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        String last = format.format(c.getTime());
        return last;
    }

    // 计算两个日期相差年数
    public static int yearDateDiff(String startDate, String endDate) {
        int year = 0;
        try {

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Calendar bef = Calendar.getInstance();
            Calendar aft = Calendar.getInstance();
            bef.setTime(sdf.parse(startDate));

            aft.setTime(sdf.parse(endDate));
            year = aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR);

        } catch (ParseException e) {
            e.printStackTrace();
        }
        return year;
    }

    public static boolean isInXMinutes(String createTime, int x) {
        try {
            Date date = FULL_SDF.parse(createTime);
            Date now = new Date();
            long diff = now.getTime() - date.getTime();
            return diff <= x * 60 * 1000;
        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean isMonthStartAndEnd(String startDateStr, String endDateStr) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date startDate = sdf.parse(startDateStr);
            Date endDate = sdf.parse(endDateStr);
            Calendar startCal = Calendar.getInstance();
            startCal.setTime(startDate);
            Calendar endCal = Calendar.getInstance();
            endCal.setTime(endDate);
            Calendar today = Calendar.getInstance();
            today.setTime(new Date());
            if (startCal.get(Calendar.DAY_OF_MONTH) == 1
                    && endCal.get(Calendar.DAY_OF_MONTH) == endCal.getActualMaximum(Calendar.DAY_OF_MONTH)
                    && startCal.get(Calendar.YEAR) == endCal.get(Calendar.YEAR)
                    && startCal.get(Calendar.MONTH) == endCal.get(Calendar.MONTH) && startCal.before(today)
                    && endCal.before(today)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 判断当前时间是否为当月的最后一天
     *
     * @return
     */
    public static boolean isLastDayOfMonth() {
        String day = getLastDay();
        String currentDay = getNowDate();
        if (day.equals(currentDay)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 格式化 时间
     * @param
     * @return
     */
    public static String currentDateTime() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return df.format(new Date());
    }


    /**
     * 性能分析总结方法
     * 根据监控数据生成性能分析报告
     */
    public static void logPerformanceAnalysis(String methodName, long totalTime, Map<String, Long> stepTimes) {
        log.info("=== {} 性能分析报告 ===", methodName);
        log.info("总耗时: {}ms", totalTime);

        // 找出最耗时的步骤
        String slowestStep = stepTimes.entrySet().stream()
                .max(Map.Entry.comparingByValue())
                .map(Map.Entry::getKey)
                .orElse("未知");

        Long slowestTime = stepTimes.get(slowestStep);
        log.info("最耗时步骤: {} ({}ms, 占比: {}%)",
                slowestStep, slowestTime, (slowestTime * 100.0 / totalTime));

        // 详细步骤耗时
        stepTimes.forEach((step, time) ->
                log.info("  {} : {}ms ({}%)", step, time, (time * 100.0 / totalTime)));

        // 性能建议
        if (totalTime > 1000) {
            log.warn("警告: {}方法执行超过1秒，建议优化", methodName);
        }
        if (slowestTime > totalTime * 0.7) {
            log.warn("警告: {}步骤耗时过长，建议重点优化", slowestStep);
        }
        log.info("=== 性能分析报告结束 ===");
    }


}

