package com.hanwha.morakmorak.util

//import com.ntels.product.chatbot.data.DataManager
import android.annotation.SuppressLint
import android.content.Context
import android.provider.Settings.Secure
import timber.log.Timber
import java.io.BufferedReader
import java.io.IOException
import java.io.InputStreamReader
import java.nio.charset.Charset
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern


/**
 * Created by aaron on 2018-05-30
 */

class CommonUtils {

    companion object {
        private const val PASSWORD_PATTERN = "^[a-zA-Z0-9!@#$%^&*()_+\\[\\]{}'\";:/?.>,<]{6,16}$"
        private const val ID_PATTERN = "^[a-zA-Z][a-zA-Z0-9!@#$%^&*()_+\\[\\]{}'\";:/?.>,<]{5,15}$"
        private const val EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"

        //영문만 있는 잘못된 암호
        const private val COMMON_INVALIDE_ONLY_ENGLISH_PATTERN = "^[a-zA-Z]{1,16}$"
        //숫자만 있는 잘못된 암호
        const private val COMMON_INVALIDE_ONLY_NUMBER_PATTERN = "^[0-9]{1,16}$"

        var CURRENT_UNIX_TIME: Long = 0
            private set
            get() = System.currentTimeMillis()

        /*val timeStamp: String
            get() = SimpleDateFormat(AppConstants.TIMESTAMP_FORMAT, Locale.US).format(Date())

        @JvmStatic fun showLoadingDialog(context: Context)
                = ProgressDialog(context).apply {
            show()
            window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            setContentView(R.layout.progress_dialog)
            isIndeterminate = true
            setCancelable(false)
            setCanceledOnTouchOutside(false)
        }*/

        @SuppressLint("all")
        @JvmStatic fun getDeviceId(context: Context) = Secure.getString(context.contentResolver, Secure.ANDROID_ID)

        @JvmStatic fun isEmailValid(email: String) = Pattern.compile(EMAIL_PATTERN).matcher(email).matches()

        @Throws(IOException::class)
        @JvmStatic fun loadJSONFromAsset(context: Context, jsonFileName: String): String {
            context.assets.open(jsonFileName).run {
                val buffer = ByteArray(available())
                read(buffer)
                close()
                return@loadJSONFromAsset String(buffer, Charset.forName("UTF-8"))
            }
        }

        @JvmStatic fun readTermsFromAssets(context: Context): String? {
            var tempStr = ""
            val inputStreamReader: InputStreamReader? = InputStreamReader(context.assets.open("terms.txt"))
            val reader: BufferedReader? = BufferedReader(inputStreamReader)

            try {
                var line: String?
                while (!reader!!.readLine().also { line = it }.isNullOrEmpty()) tempStr += "$line\n"
                reader.close()
                inputStreamReader?.close()
            } catch (e: Exception) {
                e.printStackTrace()
            }

            return tempStr
        }

        /* id 조건
            완료 -> 6~16자 영문, 숫자, 특수문자*만 가능 -> !@#$%^&*()_+[]{}’”;:/?.>,<
            3개 반복된 문자/숫자 제한
            공백/중복 불가
        */
        @JvmStatic fun checkIdValidate(id: String?): Int {
            val matcher = Pattern.compile(ID_PATTERN).matcher(id)
            val englishMatcher = Pattern.compile(COMMON_INVALIDE_ONLY_ENGLISH_PATTERN).matcher(id)
            val numberMatcher = Pattern.compile(COMMON_INVALIDE_ONLY_NUMBER_PATTERN).matcher(id)

            return when {
                id.isNullOrEmpty() -> 1
                id.length < 6 -> 2
                id.contains(" ") -> 3
                (!matcher.matches() || englishMatcher.matches() || numberMatcher.matches()) -> 4
                (!checkContinueChar(id)) -> 6
                (!checkSameChar(id)) -> 7
                else -> 0
            }
        }

        //3자 이상 연속 중복되는 문자 제한
        @JvmStatic private fun checkSameChar(checkText: String): Boolean {
            var sumCheckSameChar = 0
            var lastChar = 0.toChar()
            if (!checkText.isEmpty()) {
                checkText.toCharArray().forEach {
                    if (lastChar == it) {
                        sumCheckSameChar++
                        if (sumCheckSameChar >= 2) return@checkSameChar false
                    } else {
                        lastChar = it
                        sumCheckSameChar = 0
                    }
                }
            }
            return true
        }

        //연속된 입력 제한
        @JvmStatic private fun checkContinueChar(checkText: String): Boolean {
            var lastchar: Char = 0.toChar()
            var countContinueChar = 0
            if (!checkText.isEmpty()) {
                checkText.toCharArray().forEach {
                    if (lastchar.toInt() + 1 == it.toInt()) {
                        countContinueChar++
                        if (countContinueChar >= 2) return@checkContinueChar false
                    } else
                        countContinueChar = 0

                    lastchar = it
                }
            }
            return true
        }

        @JvmStatic fun checkPasswordValidate(password: String, id: String): Int {
            val matcher = Pattern.compile(PASSWORD_PATTERN).matcher(password)
            val englishMatcher = Pattern.compile(COMMON_INVALIDE_ONLY_ENGLISH_PATTERN).matcher(password)
            val numberMatcher = Pattern.compile(COMMON_INVALIDE_ONLY_NUMBER_PATTERN).matcher(password)

            return when {
                password.isEmpty() -> 1
                password.length < 6 -> 2
                password.contains(" ") -> 3
                !matcher.matches() || englishMatcher.matches() || numberMatcher.matches() -> 5
                !checkContinueChar(password) -> 6
                !checkSameChar(password) -> 7
                !checkSameIdChar(password, id) -> 8
                else -> 0
            }
        }

        @JvmStatic private fun checkSameIdChar(password: String, id: String) = when {
            password.isEmpty() || (password.length < 3) -> true
            id.isEmpty() || (id.length < 3) -> true
            else -> (0..id.length - 3).map { id.substring(it, it + 3) }.none { password.contains(it) }
        }

        @JvmStatic fun checkTryPasswordValidate(password: String, tryPassword: String, id: String) = when {
            password.isEmpty() || tryPassword.isEmpty() -> 1
            password != tryPassword -> 10
            else -> checkPasswordValidate(tryPassword, id)
        }

        /**
         * 휴대폰번호 패턴 체크.
         *
         * @param number 체크할 휴대폰 번호
         * @return 패턴 정상 여부
         */
        @JvmStatic fun isCellphone(number: String): Boolean {

            //010, 011, 016, 017, 018, 019
//            Timber.i(number + " = " + number.matches("(01[016789])([1-9]\\d{3,4})(\\d{4})".toRegex()))
            Timber.i("number = ${number.matches("(01[016789])([1-9]\\\\d{3,4})(\\\\d{4})".toRegex())}")
            return number.matches("(01[016789])([1-9]\\d{3,4})(\\d{4})".toRegex())
        }

        /**
         * 휴대폰번호에 하이픈 삽입.
         *
         * @param phone 하이픈을 삽입 할 휴대폰번호
         * @return 하이픈이 삽입된 휴대폰번호
         */
        @JvmStatic fun insertHyphenPhone(phone: String) = when {
            phone.length == 10 -> phone.replaceRange(3..5, "*")
            phone.length == 11 -> phone.replaceRange(3..6, "*")
            else -> phone
        }

        /**
         * String 특수문자 제거.
         *
         * @param str 특수문자 제거 할 String
         * @return 특수문자 제거된 String
         */
        @JvmStatic fun delSpecialChar(str: String) = str.replace("[^\uAC00-\uD7A3xfe0-9a-zA-Z\\s]".toRegex(), "")

//        @JvmStatic fun getDeviceUUID(context: Context, dataManager: DataManager): String {
//            val id = dataManager.deviceId
//
//            var uuid: UUID? = null
//            if (id.isNotEmpty()) {
//                uuid = UUID.fromString(id)
//            } else {
//                val androidId = Secure.getString(context.contentResolver, Secure.ANDROID_ID)
//                try {
//                    uuid = if ("9774d56d682e549c" != androidId) {
//                        UUID.nameUUIDFromBytes(androidId.toByteArray(Charset.forName("utf-8")))
//                    } else {
//                        val deviceId = (context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager).deviceId
//                        if (deviceId != null) UUID.nameUUIDFromBytes(deviceId.toByteArray(Charset.forName("utf-8"))) else UUID.randomUUID()
//                    }
//                } catch (e: UnsupportedEncodingException) {
//                    throw RuntimeException(e)
//                } catch (e: SecurityException) {
//                    throw RuntimeException(e)
//                }
//
//                dataManager.deviceId = uuid.toString()
//            }
//
//            return uuid.toString()
//        }

//        @JvmStatic fun unixTimeToDate(unixTime: Long): String {
//            val date = Date(unixTime * 1000L)
//            val sdf = SimpleDateFormat("a hh:mm", Locale.getDefault())
////            sdf.timeZone = TimeZone.getDefault()
//            return sdf.format(date)
//        }

        @JvmStatic fun getUuid(context: Context) = Secure.getString(context.contentResolver, Secure.ANDROID_ID)

        @JvmStatic
        fun unixTimeToDate(unixTime: Long): String {
            val cal = Calendar.getInstance()
            val tz = cal.timeZone
            Timber.i("unixTime: $unixTime")
            Timber.i("timezone: ${tz.displayName}")
            Timber.i("locale: ${Locale.getDefault().displayName}")
            val sdf = SimpleDateFormat("aa hh:mm", Locale.getDefault()).apply { timeZone = tz }
            Timber.i("localeTime: ${sdf.format(Date(unixTime))}")
            return sdf.format(Date(unixTime))
        }

    }

}// This utility class is not publicly instantiable

fun ClosedRange<Int>.random() = Random().nextInt((endInclusive + 1) - start) + start
