Bookmark profile
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale

data class CalendarDay(
    val date: Date,
    val disabled: Boolean
)

object CalendarUtils {

    fun getStartOfWeek(date: Date): Date {
        val calendar = Calendar.getInstance().apply {
            time = date
            set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }
        return calendar.time
    }

    fun getEndOfWeek(date: Date): Date {
        val calendar = Calendar.getInstance().apply {
            time = date
            set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
            add(Calendar.DAY_OF_WEEK, 7)
            add(Calendar.SECOND, -1)
        }
        return calendar.time
    }

    fun getStartOfMonth(date: Date): Date {
        val calendar = Calendar.getInstance().apply {
            time = date
            set(Calendar.DAY_OF_MONTH, 1)
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)
        }
        return calendar.time
    }

    fun getEndOfMonth(date: Date): Date {
        val calendar = Calendar.getInstance().apply {
            time = date
            set(Calendar.DAY_OF_MONTH, 1)
            set(Calendar.HOUR_OF_DAY, 0)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
            set(Calendar.MILLISECOND, 0)

            add(Calendar.MONTH, 1)
            add(Calendar.SECOND, -1)
        }
        return calendar.time
    }

    fun formatDate(date: Date, format: String): String {
        val formatter = SimpleDateFormat(format, Locale.getDefault())
        return formatter.format(date)
    }

    fun getWeeklyDays(date: Date = Date()): List<Date> {
        val calendar = Calendar.getInstance()
        calendar.time = date
        val dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK)

        // Calculate the first day of the week (Sunday)
        val days = mutableListOf<Date>()
        for (i in 1..7) {
            val day = Date(date.time)
            day.time -= ((dayOfWeek - i) * 24 * 60 * 60 * 1000)
            days.add(day)
        }

        return days
    }

    fun getEndOfPreviousMonth(date: Date): Date {
        val calendar = Calendar.getInstance()
        calendar.time = date
        calendar.set(Calendar.DAY_OF_MONTH, 1) // 달의 첫째 날로 설정
        calendar.add(Calendar.DATE, -1)
        return calendar.time
    }

    fun getEndOfPreviousWeek(date: Date): Date {
        val calendar = Calendar.getInstance()
        calendar.time = date
        calendar.add(Calendar.WEEK_OF_YEAR, -1)
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY)
        return calendar.time
    }

    fun getStartOfNextMonth(date: Date): Date {
        val calendar = Calendar.getInstance()
        calendar.time = date
        calendar.set(Calendar.DAY_OF_MONTH, 1) // 달의 첫째 날로 설정
        calendar.add(Calendar.MONTH, 1)
        return calendar.time
    }

    fun getStartOfNextWeek(date: Date): Date {
        val calendar = Calendar.getInstance()
        calendar.time = date
        calendar.add(Calendar.WEEK_OF_YEAR, 1)
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)
        return calendar.time
    }

    fun getCalendarWeeks(date: Date): List<List<CalendarDay>> {
        val weeks = mutableListOf<List<CalendarDay>>()

        val calendar = Calendar.getInstance().apply {
            time = date
        }

        val startDate = getStartOfWeek(getStartOfMonth(date))
        val endDate = getEndOfWeek(getEndOfMonth(date))

        val calendarOfDate = Calendar.getInstance().apply {
            time = startDate
        }

        for (j in 0 until 6) {
            val week = mutableListOf<CalendarDay>()
            for (j in 0 until 7) {
                val disabled = calendar.get(Calendar.MONTH) != calendarOfDate.get(Calendar.MONTH)
                week.add(CalendarDay(calendarOfDate.time, disabled))
                calendarOfDate.add(Calendar.DATE, 1)
            }
            weeks.add(week)
            if (calendarOfDate.time > endDate) {
                break
            }
        }

        return weeks
    }
}