package com.hanwha.morakmorak.util

import android.text.TextUtils
import androidx.annotation.NonNull
import java.text.SimpleDateFormat
import java.util.*


/**
 * Created by sanghoonkwon on 2018. 1. 18..
 */

class DateUtil {

    companion object {
        /**
         * 기본 날짜 포맷
         */
        const val FORMAT_COMMON_SERVER = "yyyy-MM-dd HH:mm:ss"
        /**
         * TASK 기한설정 날짜 포맷 - Server
         */
        const val FORMAT_TASK_DUEDATE_SERVER = "yyyy-MM-dd HH:mm:ss"
        /**
         * HOME 기본 오늘 날짜 포맷
         */
        const val FORMAT_DEFAULT_HOME = "d MMMM, EEEE"
        /**
         * TASK 등록시 사용하는 날짜 포맷
         */
        const val FORMAT_TASK_ADD_DUEDATE_SERVER = "yyyy-MM-dd"
        /**
         * 캘린더용 월 표시 포맷
         */
        const val FORMAT_CALENDAR_MONTH_DISPLAY = "MMMM"
        /**
         * TASK 기한 설정 날짜 포맷
         */
        const val FORMAT_TASK_DUEDATE_DISPLAY = "yyyy-MM-dd"
        /**
         * 계정 만료 날짜 포맷
         */
        const val FORMAT_EXPIRED_AT = "yyyy-MM-dd HH:mm:ss.S"
        /**
         * yyyy-MM-dd
         */
        const val FORMAT_YYYY_MM_DD = "yyyy-MM-dd"
        const val FORMAT_MM_DD = "MM-dd"
        const val FORMAT_MMM_D = "MMM d일"
        const val FORMAT_YEAR = "yyyy"
        const val FORMAT_MONTH = "M"
        const val FORMAT_DAY = "d"

        const val FORMAT_MM_DOT_DD = "MM.dd"
        const val FORMAT_HH_MM_A = "hh:mma"
        const val FORMAT_HOME_DETAIL = "yyyy.MM.dd E   a h:mm"

        private const val SEC = 60
        private const val MIN = 60
        private const val HOUR = 24
        private const val DAY = 30
        private const val MONTH = 12

        /**
         * 오늘 날짜
         *
         * @return 날짜 포맷 d, MMMM, EEEE
         */
        @JvmStatic
        val dateFormatToday: String
            get() = getDateFormatToday(FORMAT_DEFAULT_HOME)

        /**
         * 도와줘야 개발팀 - 기한설정(2주)
         */
        @JvmStatic
        val dateHelpdesk: String
            get() {
                val calendar = Calendar.getInstance()
                calendar.timeInMillis = System.currentTimeMillis()
                calendar.add(Calendar.DATE, 13)
                val formatter = SimpleDateFormat(FORMAT_TASK_ADD_DUEDATE_SERVER, Locale.US)

                return formatter.format(calendar.time)
            }

        /**
         * 현재 시각(Timestamp)
         *
         * @return Timestamp
         */
        @JvmStatic
        val timestampToday: Long
            get() {
                val calendar = Calendar.getInstance()
                calendar.timeInMillis = System.currentTimeMillis()

                return calendar.time.time
            }

        /**
         * 오늘 날짜
         *
         * @return 지정 날짜 포맷
         */
        @JvmStatic
        fun getDateFormatToday(@NonNull format: String): String {
            val calendar = Calendar.getInstance()
            calendar.timeInMillis = System.currentTimeMillis()
            val formatter = SimpleDateFormat(format, Locale.US)

            return formatter.format(calendar.time)
        }

        /**
         * 오늘 날짜
         *
         * @return 지정 날짜 포맷
         */
        @JvmStatic
        fun getDateFormat(year: Int, month: Int, date: Int, format: String): String {
            val calendar = Calendar.getInstance()
            calendar.set(year, month - 1, date)
            val formatter = SimpleDateFormat(format, Locale.US)

            return formatter.format(calendar.time)
        }

        /**
         * 오늘인지 확인
         *
         * @param inputDate 입력 날짜
         * @param format    입력 날짜 포맷
         * @return Boolean
         */
        @JvmStatic
        fun checkIsToday(@NonNull inputDate: String, @NonNull format: String): Boolean {
            val input = getChangeDateFormat(inputDate, format, FORMAT_YYYY_MM_DD)
            val today = getDateFormatToday(FORMAT_YYYY_MM_DD)
            return today == input
        }

        /**
         * @param inputDate String 형식 날짜
         * @return 시간 표시
         */
//    fun getDateFormatCommon(@NonNull context: Context, @NonNull inputDate: String): String {
//        var inputDate = inputDate
//        val inputFormat = FORMAT_COMMON_SERVER
//        val outputFormat: String
//        val inputTime = getTimestampFromStringFormat(inputDate, inputFormat)
//        val currentTime = timestampToday
//        val d = (currentTime - inputTime) / 1000
//
//        try {
//            /*
//            2018.4.24 변경
//            http://www.junstarok.com/redmine/issues/978
//             */
//            if (d > 60 * 60 * 24) {
//                outputFormat = "yyyy-MM-dd a hh:mm"
//                inputDate = getDateFormatFromTimestamp(inputTime, outputFormat)
//            } else if (d > 60 * 60) {
//                inputDate = java.lang.Long.toString(d / (60 * 60)) + context.getString(R.string.date_hours_ago)
//            } else if (d > 60) {
//                inputDate = java.lang.Long.toString(d / 60) + context.getString(R.string.date_minutes_ago)
//            } else {
//                inputDate = 1.toString() + context.getString(R.string.date_minutes_ago)
//            }
//        } catch (e: Exception) {
//            e.printStackTrace()
//        }
//
//        return inputDate
//    }

        /**
         * 날짜 포맷 변경
         *
         * @param inputDate    String 형식 날짜
         * @param inputFormat  입력 날짜 포맷
         * @param outputFormat 출력 날짜 포맷
         * @return String
         */
        @JvmStatic
        fun getChangeDateFormat(@NonNull inputDate: String, @NonNull inputFormat: String, @NonNull outputFormat: String): String {
            if (TextUtils.isEmpty(inputDate)) return ""
            val timestamp = getTimestampFromStringFormat(inputDate, inputFormat)
            return getDateFormatFromTimestamp(timestamp, outputFormat)
        }

        /**
         * 날짜 포맷 변경
         *
         * @param time   Timestamp
         * @param format 지정 포맷
         * @return String
         */
        @JvmStatic
        private fun getDateFormatFromTimestamp(@NonNull time: Long, @NonNull format: String): String {
            val calendar = Calendar.getInstance()
            calendar.timeInMillis = time
            val formatter = SimpleDateFormat(format, Locale.US) // TODO - CHECK Locale

            return formatter.format(calendar.time)
        }

        /**
         * 마지막 날짜 반환
         *
         * @param year  년도
         * @param month 월
         * @return 일
         */
        @JvmStatic
        fun getActualMaximum(year: Int, month: Int): Int {
            val calendar = Calendar.getInstance()
            calendar.set(year, month - 1, 1)
            return calendar.getActualMaximum(Calendar.DATE)
        }

        /**
         * 요일 반환
         *
         * @param year  년도
         * @param month 월
         * @param date  일
         * @return 요일
         */
        @JvmStatic
        fun getDayOfWeek(year: Int, month: Int, date: Int): Int {
            val calendar = Calendar.getInstance()
            calendar.set(year, month - 1, date)
            return calendar.get(Calendar.DAY_OF_WEEK)
        }

        /**
         * 오늘 포함 2주 이내인지 확인
         *
         * @param year  년도
         * @param month 월
         * @param date  일
         * @return Boolean
         */
        @JvmStatic
        fun checkTwoWeeksFromToday(year: Int, month: Int, date: Int): Boolean {
            val calendar = Calendar.getInstance()
            calendar.set(year, month - 1, date)

            val today = Calendar.getInstance()
            today.timeInMillis = System.currentTimeMillis()

            if (today.timeInMillis > calendar.timeInMillis) return false

            today.add(Calendar.DATE, 14)
            return today.time.time > calendar.time.time
        }

        /**
         * 날짜 비교
         *
         * @param year
         * @param month
         * @param date
         * @param dueTime
         * @return Boolean
         */
        @JvmStatic
        fun checkSelectedDate(year: Int, month: Int, date: Int, dueTime: String): Boolean {
            val calendar = Calendar.getInstance()
            calendar.set(year, month - 1, date)
            val checkDate = getDateFormatFromTimestamp(calendar.timeInMillis, FORMAT_TASK_ADD_DUEDATE_SERVER)
            return checkDate == dueTime
        }

        /**
         * 오늘 날짜 -> 지정 포맷으로 변경
         *
         * @param format 지정 포맷
         * @return String
         */
        @JvmStatic
        fun getDateFormatFromToday(format: String): String {
            val timestamp = timestampToday
            return getDateFormatFromTimestamp(timestamp, format)
        }

        /**
         * String Date -> Timestamp
         *
         * @param inputDate 날짜 문자열
         * @param format    날짜 포맷
         * @return Timestamp
         */
        @JvmStatic
        fun getTimestampFromStringFormat(@NonNull inputDate: String, @NonNull format: String): Long {

            var date = Date()
            try {
                if (TextUtils.isEmpty(inputDate) == false) {
                    val simpleDateFormat = SimpleDateFormat(format)
                    date = simpleDateFormat.parse(inputDate)
                }
            } catch (e: Exception) {
                e.printStackTrace()
            }

            return date.time
        }

        /**
         * D-Day 계산
         *
         * @param inputDate
         * @param format
         * @return D-day 계산
         */
        @JvmOverloads
        @JvmStatic
        fun getCalculateDDayFromToday(@NonNull inputDate: String, @NonNull format: String = FORMAT_TASK_DUEDATE_SERVER): Int {
            val date = getTimestampFromStringFormat(inputDate, format)
            val today = timestampToday

            val result = date - today
            return (result / (1000 * 60 * 60 * 24)).toInt() - if (result < 0) 1 else 0
        }

        /**
         * D-Day 계산
         *
         * @param dueDate
         * @param completeDate
         * @param format
         * @return D-day 계산
         */
        @JvmStatic
        fun getCalculateDDayFromToday(@NonNull dueDate: String, @NonNull completeDate: String, @NonNull format: String): Int {
            val due = getTimestampFromStringFormat(dueDate, format)
            val complete = getTimestampFromStringFormat(completeDate, format)

            val result = due - complete
            return (result / (1000 * 60 * 60 * 24)).toInt() - if (result < 0) 1 else 0
        }

        @JvmStatic
        fun checkOverDuedate(@NonNull inputDate: String): Boolean {
            return getCalculateDDayFromToday(inputDate, FORMAT_TASK_DUEDATE_SERVER) < 0
        }

        @JvmStatic
        fun checkOverDuedate(@NonNull dueDate: String, completeDate: String): Boolean {
            return getCalculateDDayFromToday(dueDate, completeDate, FORMAT_TASK_DUEDATE_SERVER) < 0
        }

        @JvmStatic
        fun getMeetingDate(@NonNull inputDate: String): String {
            return when (getCalculateDDayFromToday(inputDate)) {
                0 -> "오늘"
                1 -> "내일"
                else -> getChangeDateFormat(inputDate, FORMAT_TASK_DUEDATE_SERVER, FORMAT_MM_DOT_DD)
            }
        }

        @JvmStatic
        fun getMeetingTime(@NonNull inputDate: String) = getChangeDateFormat(inputDate, FORMAT_TASK_DUEDATE_SERVER, FORMAT_HH_MM_A)

        @JvmStatic
        fun getTalkingTimeString(inputDate: String?) = inputDate?.run {
            val curTime = System.currentTimeMillis()
            var diffTime = (curTime - getTimestampFromStringFormat(inputDate, FORMAT_TASK_DUEDATE_SERVER)) / 1000

            if (diffTime < SEC) return "방금전"
            diffTime /= SEC.toLong()
            if (diffTime < MIN) return "${diffTime}분전"
            diffTime /= MIN.toLong()
            if (diffTime < HOUR) return "${diffTime}시간전"
            diffTime /= HOUR.toLong()
            if (diffTime < DAY) return "${diffTime}일전"
            diffTime /= DAY.toLong()
            if (diffTime < MONTH) return "${diffTime}달전"

            return "${diffTime}년전"
        } ?: ""

        @JvmStatic
        fun getDetailTime(inputDate: String?) = inputDate?.run {
            getChangeDateFormat(inputDate, FORMAT_TASK_DUEDATE_SERVER, FORMAT_HOME_DETAIL).toUpperCase()
        } ?: ""
    }
}
