package com.ama.core.architecture.util


import java.text.SimpleDateFormat
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.Calendar
import java.util.TimeZone


class DateUtil private constructor() {

    companion object {
        const val MS_NUM_ONE_DAY = (24 * 60 * 60 * 1000)

        private const val FORMAT_DATE = "yyyy-MM-dd"
        private const val FORMAT_DATETIME = "yyyy-MM-dd HH:mm:ss"



        fun getCurrentDateTime(format: String = FORMAT_DATETIME): String {
            return SimpleDateFormat(format, Locale.getDefault()).format(Date())
        }


        fun timestampToDate(timestamp: Long, format: String = FORMAT_DATE): String {
            return SimpleDateFormat(format, Locale.getDefault()).format(Date(timestamp))
        }


        fun stringToDate(dateString: String, format: String = FORMAT_DATE): Date? {
            return try {
                SimpleDateFormat(format, Locale.getDefault()).parse(dateString)
            } catch (e: Exception) {
                e.printStackTrace()
                null
            }
        }


        fun convertDateFormat(dateString: String, fromFormat: String, toFormat: String): String {
            return try {
                val date = SimpleDateFormat(fromFormat, Locale.getDefault()).parse(dateString)
                SimpleDateFormat(toFormat, Locale.getDefault()).format(date)
            } catch (e: Exception) {
                e.printStackTrace()
                dateString
            }
        }

        /**
         * 给定时间是否超过指定周期
         */
        fun isPeriodExpired(targetTime: Any, period: Long, timeUnit: TimeUnit): Boolean {
            val targetTimestamp = when (targetTime) {
                is Long -> targetTime
                is Date -> targetTime.time
                is String -> stringToTimestamp(targetTime) ?: 0L
                else -> 0L
            }

            if (targetTimestamp == 0L) return false

            val currentTime = System.currentTimeMillis()
            val periodMillis = timeUnit.toMillis(period)

            return currentTime - targetTimestamp > periodMillis
        }

        fun isPeriodExpired(startTimeMs: Long, dayNum: Int): Boolean {
            val periodMillis = dayNum * 24 * 3600000
            return startTimeMs + periodMillis < getCurTimeMs()
        }

        /**
         * 从起始时间到现在已经过去多少天
         */
        fun getDaysPassed(startTime: Any): Int {
            val startTimestamp = when (startTime) {
                is Long -> startTime
                is Date -> startTime.time
                is String -> stringToTimestamp(startTime) ?: 0
                else -> 0
            }

            if (startTimestamp == 0L) return 0

            val currentTime = System.currentTimeMillis()
            val diffMillis = currentTime - startTimestamp

            return TimeUnit.MILLISECONDS.toDays(diffMillis).toInt()
        }



        /**
         * 两个时间点之间的天数差
         */
        fun getDaysBetween(startTime: Any, endTime: Any): Long {
            val startTimestamp = convertToTimestamp(startTime)
            val endTimestamp = convertToTimestamp(endTime)

            if (startTimestamp == 0L || endTimestamp == 0L) return 0L

            val diffMillis = endTimestamp - startTimestamp
            return TimeUnit.MILLISECONDS.toDays(diffMillis)
        }

        /**
         * 判断今天是否是特定日期
         */
        fun isToday(targetTime: Any): Boolean {
            val targetDate = when (targetTime) {
                is Long -> Date(targetTime)
                is Date -> targetTime
                is String -> stringToDate(targetTime)
                else -> null
            }

            return targetDate?.let { isSameDay(it, Date()) } ?: false
        }

        /**
         * 两个日期是否是同一天
         */
        fun isSameDay(date1: Date, date2: Date): Boolean {
            val cal1 = Calendar.getInstance().apply { time = date1 }
            val cal2 = Calendar.getInstance().apply { time = date2 }

            return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR) &&
                    cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH) &&
                    cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH)
        }


        /**
         * 在指定日期上添加天数
         */
        fun addDays(date: Date, days: Int): Date {
            val cal = Calendar.getInstance().apply { time = date }
            cal.add(Calendar.DAY_OF_MONTH, days)
            return cal.time
        }

        fun getFirstDayOfMonth(date: Date = Date()): Date {
            val cal = Calendar.getInstance().apply { time = date }
            cal.set(Calendar.DAY_OF_MONTH, 1)
            return cal.time
        }

        fun getLastDayOfMonth(date: Date = Date()): Date {
            val cal = Calendar.getInstance().apply { time = date }
            cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH))
            return cal.time
        }



        // 私有工具方法
        private fun stringToTimestamp(dateString: String, format: String = FORMAT_DATE): Long? {
            return stringToDate(dateString, format)?.time
        }

        private fun convertToTimestamp(time: Any): Long {
            return when (time) {
                is Long -> time
                is Date -> time.time
                is String -> stringToTimestamp(time) ?: 0L
                else -> 0L
            }
        }





        //--------------------------- New added methods ----------------------------//
        fun getCurTimeMs(): Long {
            return System.currentTimeMillis()
        }

        fun getTodayStartTimeMs(): Long {
            val calendar = Calendar.getInstance().apply {
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }
            return calendar.timeInMillis
        }



        fun getPassedDayNum(periodStartMs: Long, currentMs: Long): Int {
            val utcTimeZone = TimeZone.getTimeZone("UTC") // 使用UTC时区

            val calendarStart = Calendar.getInstance(utcTimeZone).apply {
                timeInMillis = periodStartMs
            }
            val calendarCurrent = Calendar.getInstance(utcTimeZone).apply {
                timeInMillis = currentMs
            }

            // 清除时分秒毫秒信息
            fun Calendar.clearTime() {
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }

            calendarStart.clearTime()
            calendarCurrent.clearTime()

            return ((calendarCurrent.timeInMillis - calendarStart.timeInMillis) / MS_NUM_ONE_DAY).toInt()
        }

        fun formatMs2HMS(msNum: Long): List<Long> {
            val resultList = mutableListOf<Long>()
            val hours = msNum / (3600000)
            val minute = (msNum - hours * 3600000) / (60000)
            val second = (msNum - hours * 3600000 - minute * 60000) / (1000)

            resultList.add(hours)
            resultList.add(minute)
            resultList.add(second)
            return resultList
        }


    }

}
