package com.utic.center.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class TimeUtils {
    public static final int TYPE_CURR_05MIN = 0;
    public static final int TYPE_PRCS_05MIN = 1;
    public static final int TYPE_PRCS_15MIN = 2;
    public static final int TYPE_PRCS_HOUR = 3;
    public static final int TYPE_PRCS_DAY = 4;
    public static final int TYPE_PRCS_MONTH = 5;
    public static final int TYPE_PRCS_YEAR = 6;

    private TimeUtils() {}

    public static void sleep(long delay) {
        try {
            TimeUnit.MILLISECONDS.sleep(delay);
        } catch (InterruptedException e) {
//            Thread.currentThread().interrupt();
        }
    }

    public static String elapsedTime(long startTime, long endTime) {
        return elapsedTimeStr(endTime - startTime);
    }
    public static String elapsedTime(long startTime) {
        return elapsedTimeStr(System.nanoTime() - startTime);
    }
    public static String elapsedTimeStr(long elapsed) {
        long seconds = TimeUnit.SECONDS.convert(elapsed, TimeUnit.NANOSECONDS);
        long miliSeconds = TimeUnit.MILLISECONDS.convert(elapsed, TimeUnit.NANOSECONDS) % 1000;
        long microSeconds = TimeUnit.MICROSECONDS.convert(elapsed, TimeUnit.NANOSECONDS) % 1000;
        long nanoSeconds = TimeUnit.NANOSECONDS.convert(elapsed, TimeUnit.NANOSECONDS) % 1000;

        if (seconds > 0) {
            return String.format("Elapsed: %,d sec. %3d ms. %3d us. %3d ns.", seconds, miliSeconds, microSeconds, nanoSeconds);
        }
        if (miliSeconds > 0) {
            return String.format("Elapsed: %3d ms. %3d us. %3d ns.", miliSeconds, microSeconds, nanoSeconds);
        }
        if (microSeconds > 0) {
            return String.format("Elapsed: --- ms. %3d us. %3d ns.", microSeconds, nanoSeconds);
        }
        return String.format("Elapsed: --- ms. --- us. %3d ns.", nanoSeconds);
    }
    public static long currentElapsedTime() {
        return System.nanoTime() / 1000000;
    }
    public static long currentTimeMillis() {
        return System.currentTimeMillis();
    }
    public static long currentTimeSeconds() {
        return TimeUnit.SECONDS.convert(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }
    public static Date elapsedTimeToDate(long elapsedTime) {
        long wallTime = currentTimeMillis() + elapsedTime - currentElapsedTime();
        return new Date(wallTime);
    }

    public static String getCurrentTimeString() {
        Calendar cal = Calendar.getInstance();
        return (new SimpleDateFormat("yyyyMMddHHmmss")).format(cal.getTime());
    }

    public static String getCurrentTimeString(String parmaFmt) {
        Calendar cal = Calendar.getInstance();
        return (new SimpleDateFormat(parmaFmt)).format(cal.getTime());
    }

    public static Date getCurrentDate() {
        Calendar cal = Calendar.getInstance();
        return cal.getTime();
    }

    public static Date stringToDate(String paramTime) {
        SimpleDateFormat transFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date to = null;

        try {
            to = transFormat.parse(paramTime);
        } catch (ParseException var4) {
            var4.printStackTrace();
        }

        return to;
    }

    public static String dateToString(Date paramDt, String paramFmt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(paramDt);
        return (new SimpleDateFormat(paramFmt)).format(cal.getTime());
    }

    public static String dateToString(Date paramDt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(paramDt);
        return (new SimpleDateFormat("yyyyMMddHHmmss")).format(cal.getTime());
    }

    public static String getNowDatetime() {
        Date today = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSZ");
        return sdf.format(today);
    }

    public static String now() {
        Date today = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(today);
    }

    public static long getCurrentTimeSeconds() {
        Calendar cal = Calendar.getInstance();
        return Math.round((double)cal.getTimeInMillis() / 1000.0D);
    }

    public static long getCurrentTimeMilliSeconds() {
        Calendar cal = Calendar.getInstance();
        return cal.getTimeInMillis();
    }

    public static String getFiveMinString(Date paramDt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(paramDt);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        int min = cal.get(Calendar.MINUTE);
        cal.add(Calendar.MINUTE, -(min % 5));
        return (new SimpleDateFormat("yyyyMMddHHmmss")).format(cal.getTime());
    }

    public static String getFiveMinString() {
        Calendar cal = Calendar.getInstance();
        return getFiveMinString(cal.getTime());
    }

    private static String getItsTimeString(Date paramDt, int cycle, int period) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(paramDt);
        cal.set(13, 0);
        cal.set(14, 0);
        int min = cal.get(12);
        cal.add(12, -(min % cycle) - cycle * period);
        return (new SimpleDateFormat("yyyyMMddHHmmss")).format(cal.getTime());
    }

    private static String getItsTimeToString(Date paramDt, int type) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(paramDt);
        switch(type) {
            case 0:
            case 1:
                cal.add(12, 5);
                break;
            case 2:
                cal.add(12, 15);
                break;
            case 3:
                cal.add(11, 1);
                break;
            case 4:
                cal.add(5, 1);
                break;
            case 5:
                cal.add(2, 1);
                break;
            case 6:
                cal.add(1, 1);
        }

        cal.add(13, -1);
        return (new SimpleDateFormat("yyyyMMddHHmmss")).format(cal.getTime());
    }

    public static String getTime(int type) {
        Calendar cal = Calendar.getInstance();
        return getTime(cal.getTime(), type);
    }

    public static String getTime(String paramStr, int type) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(stringToDate(paramStr));
        return getTime(cal.getTime(), type);
    }

    public static String getTime(Date paramDt, int type) {
        switch(type) {
            case 0:
                return getItsTimeString(paramDt, 5, 0);
            case 1:
                return getItsTimeString(paramDt, 5, 1);
            case 2:
                return getItsTimeString(paramDt, 15, 1);
            case 3:
                return getItsTimeString(paramDt, 60, 1);
            case 4:
                return getItsTimeString(paramDt, 1440, 1).substring(0, 8) + "000000";
            case 5:
                return getItsTimeString(paramDt, 1440, 1).substring(0, 6) + "01000000";
            case 6:
                return getItsTimeString(paramDt, 1440, 1).substring(0, 4) + "0101000000";
            default:
                return "";
        }
    }

    public static String getToTime(int type) {
        String prcsTime = getTime(type);
        return getToTime(prcsTime, type);
    }

    public static String getToTime(String paramStr, int type) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(stringToDate(paramStr));
        return getToTime(cal.getTime(), type);
    }

    public static String getToTime(Date paramDt, int type) {
        return getItsTimeToString(paramDt, type);
    }

    public static String getCurrMin() {
        Calendar cal = Calendar.getInstance();
        return getItsTimeString(cal.getTime(), 5, 0);
    }

    public static String getCurrMin(String paramStr) {
        return getItsTimeString(stringToDate(paramStr), 5, 0);
    }

    public static String getCurrMin(Date paramDt) {
        return getItsTimeString(paramDt, 5, 0);
    }

    public static String get05Min() {
        Calendar cal = Calendar.getInstance();
        return getItsTimeString(cal.getTime(), 5, 1);
    }

    public static String get05Min(String paramStr) {
        return getItsTimeString(stringToDate(paramStr), 5, 1);
    }

    public static String get05Min(Date paramDt) {
        return getItsTimeString(paramDt, 5, 1);
    }

    public static String get15Min() {
        Calendar cal = Calendar.getInstance();
        return getItsTimeString(cal.getTime(), 15, 1);
    }

    public static String get15Min(String paramStr) {
        return getItsTimeString(stringToDate(paramStr), 15, 1);
    }

    public static String get15Min(Date paramDt) {
        return getItsTimeString(paramDt, 15, 1);
    }

    public static String getHour() {
        Calendar cal = Calendar.getInstance();
        return getItsTimeString(cal.getTime(), 60, 1);
    }

    public static String getHour(String paramStr) {
        return getItsTimeString(stringToDate(paramStr), 60, 1);
    }

    public static String getHour(Date paramDt) {
        return getItsTimeString(paramDt, 60, 1);
    }

    public static String getDay() {
        Calendar cal = Calendar.getInstance();
        return getItsTimeString(cal.getTime(), 1440, 1).substring(0, 8) + "000000";
    }

    public static String getDay(String paramStr) {
        return getItsTimeString(stringToDate(paramStr), 1440, 1).substring(0, 8) + "000000";
    }

    public static String getDay(Date paramDt) {
        return getItsTimeString(paramDt, 1440, 1).substring(0, 8) + "000000";
    }

    public static String getToString(Date paramDt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(paramDt);
        cal.add(Calendar.SECOND, -1);
        return (new SimpleDateFormat("yyyyMMddHHmmss")).format(cal.getTime());
    }

    public static String getFiveMinToString(Date paramDt) {
        String strFiveMin = getFiveMinString(paramDt);
        Date dtFiveMin = stringToDate(strFiveMin);
        return getToString(dtFiveMin);
    }

    public static String getFiveMinToString() {
        Calendar cal = Calendar.getInstance();
        return getFiveMinToString(cal.getTime());
    }

    public static long getStringTimeToSeconds(String paramDt, String dateFmt, long defaultSeconds) {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFmt);
            LocalDateTime dateTime = LocalDateTime.parse(paramDt, formatter);

            return dateTime.toEpochSecond(ZoneId.systemDefault().getRules().getOffset(dateTime));
        } catch (Exception e) {
            return defaultSeconds;
        }
    }
    public static boolean isQuarterHour(String dateTimeStr) {
        // 날짜 형식 변환
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);

        // 분을 15로 나누어서 나머지 확인
        int minutes = dateTime.getMinute();
        return minutes % 15 == 0; // 0, 15, 30, 45분이면 true 반환
    }
    public static String addMinutes(String dateTimeStr, int minutesToAdd) {
        // 날짜 형식 변환
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);

        // 15분 추가
        LocalDateTime updatedDateTime = dateTime.plusMinutes(minutesToAdd);

        // 다시 문자열로 변환
        return updatedDateTime.format(formatter);
    }
    public static String roundToQuarterHour(String dateTimeStr) {
        // 날짜 형식 변환
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);

        // 현재 분을 가져옴
        int minutes = dateTime.getMinute();

        // 15분 단위로 반올림 (0, 15, 30, 45)
        int roundedMinutes;
        if (minutes == 0) {
            roundedMinutes = 0;
        } else if (minutes >= 1 && minutes <= 15) {
            roundedMinutes = 15;
        } else if (minutes >= 16 && minutes <= 30) {
            roundedMinutes = 30;
        } else if (minutes >= 31 && minutes <= 45) {
            roundedMinutes = 45;
        } else { // 45~59분 → 다음 시간의 0분으로 변경
            roundedMinutes = 0;
            dateTime = dateTime.plusHours(1);
        }

        // 새로운 분 설정
        dateTime = dateTime.withMinute(roundedMinutes).withSecond(0);

        // 다시 문자열로 변환하여 반환
        return dateTime.format(formatter);
    }

    public static String addDays(String dateTimeStr, int days) {
        // 날짜 형식 변환
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, formatter);

        // 일(day) 추가 또는 빼기
        LocalDateTime updatedDateTime = dateTime.plusDays(days);

        // 다시 문자열로 변환
        return updatedDateTime.format(formatter);
    }


//    public static String getQuarterHour(String dateTimeStr) {
//        String prcsTime = TimeUtils.getFiveMinString(TimeUtils.stringToDate(dateTimeStr));
//        Date paramDt = stringToDate(prcsTime);
//        Calendar cal = Calendar.getInstance();
//        cal.setTime(paramDt);
//        cal.set(Calendar.SECOND, 0);
//        cal.set(Calendar.MILLISECOND, 0);
//        int min = cal.get(Calendar.MINUTE);
//        int nam = min % 15;
//        int calMin = 15 - nam;
////        if (nam == 5) {
////            cal.add(Calendar.MINUTE, 10);
////        } else if (nam == 10) {
////            cal.add(Calendar.MINUTE, 5);
////        } else {
////            return prcsTime;
////        }
//        cal.add(Calendar.MINUTE, calMin);
//        return new SimpleDateFormat("yyyyMMddHHmmss").format(cal.getTime());
//    }
}
