package com.adealink.weparty.util

import android.annotation.SuppressLint
import com.adealink.frame.aab.util.getCompatString
import com.adealink.frame.util.ONE_HOUR
import com.adealink.frame.util.ONE_MINUTE
import com.adealink.frame.util.ONE_SECOND
import com.adealink.weparty.R
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale
import kotlin.math.abs


enum class TimeHour(vararg val time: String) {
    TIME_00_00("00:00", "23:59"),
    TIME_01_00("01:00"),
    TIME_02_00("02:00"),
    TIME_03_00("03:00"),
    TIME_04_00("04:00"),
    TIME_05_00("05:00"),
    TIME_06_00("06:00"),
    TIME_07_00("07:00"),
    TIME_08_00("08:00"),
    TIME_09_00("09:00"),
    TIME_10_00("10:00"),
    TIME_11_00("11:00"),
    TIME_12_00("12:00"),
    TIME_13_00("13:00"),
    TIME_14_00("14:00"),
    TIME_15_00("15:00"),
    TIME_16_00("16:00"),
    TIME_17_00("17:00"),
    TIME_18_00("18:00"),
    TIME_19_00("19:00"),
    TIME_20_00("20:00"),
    TIME_21_00("21:00"),
    TIME_22_00("22:00"),
    TIME_23_00("23:00");

    fun time(): String {
        return time.first()
    }

    companion object {
        @JvmStatic
        fun map(time: String?): TimeHour? {
            time ?: return null
            return entries.find { hour ->
                hour.time.find { it == time } != null
            }
        }

        @JvmStatic
        fun map(index: Int): TimeHour? {
            return entries.getOrNull(index)
        }
    }
}

enum class WeekDay(val day: Int) {
    SUNDAY(1),      //周日
    MONDAY(2),      //周一
    TUESDAY(3),     //周二
    WEDNESDAY(4),   //周三
    THURSDAY(5),    //周四
    FRIDAY(6),      //周五
    SATURDAY(7);    //周六

    fun getDesc(): String {
        return when (this) {
            SUNDAY -> {
                getCompatString(R.string.common_week_sunday)
            }

            MONDAY -> {
                getCompatString(R.string.common_week_monday)
            }

            TUESDAY -> {
                getCompatString(R.string.common_week_tuesday)
            }

            WEDNESDAY -> {
                getCompatString(R.string.common_week_wednesday)
            }

            THURSDAY -> {
                getCompatString(R.string.common_week_thursday)
            }

            FRIDAY -> {
                getCompatString(R.string.common_week_friday)
            }

            SATURDAY -> {
                getCompatString(R.string.common_week_saturday)
            }
        }
    }

    companion object {
        @JvmStatic
        fun map(day: Int?): WeekDay? {
            day ?: return null
            return entries.find { it.day == day }
        }
    }
}


const val TIME_FORMAT_DMY = "dd/MM/yyyy"
const val TIME_FORMAT_DMY_HMS = "dd/MM/yyyy HH:mm:ss"

fun get18YearsAgoTs(): Long {
    val cal = Calendar.getInstance()
    cal.clear()
    cal.setTime(Date(System.currentTimeMillis() - 86_400_000)) //前一天
    val currYear = cal.get(Calendar.YEAR)
    cal.set(Calendar.YEAR, currYear - 18)
    return cal.timeInMillis
}


@SuppressLint("SimpleDateFormat")
fun formatTimeTo(timestamp: Long, format: String, locale: Locale = Locale.ENGLISH): String {
    return SimpleDateFormat(format, locale).format(Date(timestamp))
}

/**
 * 倒计时格式化方法，使用 frame 库常量
 * @param millis 毫秒数
 * @return 格式化的倒计时字符串，如 "02h : 30m : 45s"
 */
fun formatCountdownTime(millis: Long): String {
    val hours = millis / ONE_HOUR
    val leftMS = millis % ONE_HOUR
    val minutes = leftMS / ONE_MINUTE
    val seconds = (leftMS % ONE_MINUTE) / ONE_SECOND

    fun formatTime(time: Long) = if (time < 10) "0$time" else "$time"

    return "${formatTime(hours)}h : ${formatTime(minutes)}m : ${formatTime(seconds)}s"
}

fun isSameDay(timestamp1: Long, timestamp2: Long): Boolean {
    return (timestamp1 / 86400_000) == (timestamp2 / 86400_000)
}

//快速计算是否同一年(不适用精准场景)
fun isSameYearApprox(timestamp1: Long, timestamp2: Long): Boolean {
    // 按平均一年365.2425天计算
    //31,556,952,000 =365.2425 * 24 * 60 * 60 * 1000
    return timestamp1 / 31_556_952_000 == timestamp2 / 31_556_952_000
}


// 精确判断（考虑闰年）
fun isSameYearExact(timestamp1: Long, timestamp2: Long): Boolean {
    val cal1 = Calendar.getInstance().apply { timeInMillis = timestamp1 }
    val cal2 = Calendar.getInstance().apply { timeInMillis = timestamp2 }
    return cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
}


private const val JUST_NOW = 900_000 //15x60x1000 //15分钟内
private const val JUST_ONE_DAY = 86400_000 //24x60x60x1000 //24小时

/**
 * IM列表时间格式化
 *
 * ≤15min，现在
 * ＞15min且小于24h，并且是今天内，显示实际的时分，如10:21, (格式:HH:mm)
 * ＞15min且小于24h，并且不是今天内，显示日期，如28/11 (格式:dd/MM)
 * ≥24h，显示日期，28/11 (格式:dd/MM)
 * 跨年，显示日月年，28/11/2025 (格式:dd/MM/yyyy)
 */
fun Long.formatTimeStr(): String {
    val now = Date()
    val ts = Date(this)
    val tsOffset = abs(now.time - ts.time)
    return if (tsOffset <= JUST_NOW) {
        //≤15min，现在
        getCompatString(R.string.common_just_now)
    } else if (tsOffset <= JUST_ONE_DAY && isSameDay(now.time, ts.time)) {
        //＞15min且小于24h，并且是今天内，显示实际的时分，如10:21, (格式:HH:mm)
        formatTimeTo(this, "HH:mm")
    } else if (tsOffset <= JUST_ONE_DAY) {
        //＞15min且小于24h，并且不是今天内，显示日期，如28/11 (格式:dd/MM)
        formatTimeTo(this, "dd/MM")
    } else if (isSameYearApprox(now.time, ts.time)) {
        //≥24h，显示日期，28/11 (格式:dd/MM)
        formatTimeTo(this, "dd/MM")
    } else {
        //跨年，显示日月年，28/11/2025 (格式:dd/MM/yyyy)
        formatTimeTo(this, "dd/MM/yyyy")
    }
}

/**
 * 距离现在过去了多久
 */
fun Long.timePass(): String {
    val now = Date()
    val ts = Date(this)
    val tsOffset = now.time - ts.time
    return if (tsOffset <= 300_000) { //5分钟内
        //≤5min，现在
        getCompatString(R.string.common_just_now)
    } else if (tsOffset < 3_600_000) { //1小时内
        getCompatString(R.string.common_pass_minute, (tsOffset / 60_000).toString())
    } else if (tsOffset < 86_400_000) { //1天内
        getCompatString(R.string.common_pass_hour, (tsOffset / 3_600_000).toString())
    } else {
        getCompatString(R.string.common_pass_day, (tsOffset / 86_400_000).toString())
    }
}


/**
 * IM会话时间格式化
 * 时间格式规则：
 * 今天：today
 * 昨天：Yesterday
 * 同一年：28/11
 * 跨年：MM-DD-YYYY  28/11/2025
 */
fun Long.sessionTimeStr(): String {
    val now = Date()
    val ts = Date(this)
    val tsOffset = abs(now.time - ts.time)
    return if (tsOffset <= JUST_ONE_DAY && isSameDay(now.time, ts.time)) {
        //小于24h，并且是今天内，显示实际的时分，如10:21, (格式:HH:mm)
        formatTimeTo(this, "HH:mm")
    } else if (tsOffset <= JUST_ONE_DAY) {
        //小于24h，并且不是今天内，显示日期，如28/11 (格式:dd/MM)
        formatTimeTo(this, "dd/MM")
    } else if (isSameYearApprox(now.time, ts.time)) {
        //≥24h，显示日期，28/11 (格式:dd/MM)
        formatTimeTo(this, "dd/MM")
    } else {
        //跨年，显示日月年，28/11/2025 (格式:dd/MM/yyyy)
        formatTimeTo(this, "dd/MM/yyyy")
    }
}

/**
 * 获取IM会话时间
 * @param lastTime 上一条消息的时间
 * @return null 不展示
 */
fun getSessionTimeStr(thisTime: Long, lastTime: Long?): String? {
    if (lastTime == null) {
        return thisTime.sessionTimeStr()
    }
    val nowTs = Date().time
    val nowOffset = abs(nowTs - thisTime)
    return if (nowOffset <= JUST_ONE_DAY && isSameDay(nowTs, thisTime)) {
        //小于24h，并且是今天内，显示实际的时分，如10:21, (格式:HH:mm)
        if (isSameDay(lastTime, thisTime)) {
            null
        } else {
            formatTimeTo(thisTime, "HH:mm")
        }
    } else if (nowOffset <= JUST_ONE_DAY) {
        //小于24h，并且不是今天内，显示日期，如28/11 (格式:dd/MM)
        if (isSameDay(lastTime, thisTime)) {
            null
        } else {
            formatTimeTo(thisTime, "dd/MM")
        }
    } else if (isSameYearApprox(nowTs, thisTime)) {
        //≥24h，显示日期，28/11 (格式:dd/MM)
        if (isSameDay(lastTime, thisTime)) {
            null
        } else {
            formatTimeTo(thisTime, "dd/MM")
        }
    } else {
        //跨年，显示日月年，28/11/2025 (格式:dd/MM/yyyy)
        if (isSameDay(lastTime, thisTime)) {
            null
        } else {
            formatTimeTo(thisTime, "dd/MM/yyyy")
        }
    }
}


fun formatMissTime(seconds: Int): String {
    // String hh = miss / 3600 > 9 ? miss / 3600 + "" : "0" + miss / 3600;
    val mm =
        if ((seconds % 3600) / 60 > 9) ((seconds % 3600) / 60).toString() + "" else "0" + (seconds % 3600) / 60
    val ss =
        if ((seconds % 3600) % 60 > 9) ((seconds % 3600) % 60).toString() + "" else "0" + (seconds % 3600) % 60
    return "$mm:$ss"
}

private val WEEK_DAY_ORDER = listOf(
    WeekDay.SUNDAY,
    WeekDay.MONDAY,
    WeekDay.TUESDAY,
    WeekDay.WEDNESDAY,
    WeekDay.THURSDAY,
    WeekDay.FRIDAY,
    WeekDay.SATURDAY
)

/**
 * @param weekDays, 需要保证顺序
 */
fun formatWeekdays(days: List<WeekDay>): String {
    if (days.isEmpty()) return ""
    if (days.size == 1) return days[0].getDesc()

    // 验证并排序
    val validDays = days.filter { it in WEEK_DAY_ORDER }
    if (validDays.size != days.size) {
        println("警告：输入包含无效的星期格式")
    }

    val sortedDays = validDays.sortedBy { WEEK_DAY_ORDER.indexOf(it) }

    val ranges = mutableListOf<String>()
    var startIndex = 0

    while (startIndex < sortedDays.size) {
        var endIndex = startIndex

        // 寻找连续区间
        while (endIndex + 1 < sortedDays.size) {
            val currentIdx = WEEK_DAY_ORDER.indexOf(sortedDays[endIndex])
            val nextIdx = WEEK_DAY_ORDER.indexOf(sortedDays[endIndex + 1])

            if (nextIdx == currentIdx + 1) {
                endIndex++
            } else {
                break
            }
        }

        // 构建区间字符串
        val startDay = sortedDays[startIndex]
        val endDay = sortedDays[endIndex]

        ranges.add(
            if (startIndex == endIndex) {
                startDay.getDesc()
            } else {
                getCompatString(R.string.common_week_from_to, startDay.getDesc(), endDay.getDesc())
            }
        )

        startIndex = endIndex + 1
    }

    return ranges.joinToString("，")
}


fun parseDate(dateStr: String?, pattern: String = "yyyy-MM-dd"): Date? {
    if (dateStr.isNullOrEmpty()) {
        return null
    }
    return try {
        val format = SimpleDateFormat(pattern, Locale.getDefault())
        format.parse(dateStr)
    } catch (e: Exception) {
        null
    }
}