package com.nivesh.production.partnerOnBoarding.util

import android.app.Activity
import android.app.AlertDialog
import android.app.DatePickerDialog
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.net.Uri
import android.os.Build
import android.provider.Settings
import android.text.TextUtils
import android.util.Patterns
import android.view.Gravity
import android.view.View
import android.view.Window
import android.webkit.WebView
import android.widget.ImageView
import androidx.appcompat.app.ActionBar
import com.google.android.material.textfield.MaterialAutoCompleteTextView
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import com.google.gson.JsonObject
import com.nivesh.production.partnerOnBoarding.R
import com.nivesh.production.partnerOnBoarding.ui.activities.SignUpActivity
import kotlinx.coroutines.CoroutineExceptionHandler
import retrofit2.HttpException
import retrofit2.Response
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Matcher
import java.util.regex.Pattern


class Common {

    companion object {
        //internet check
        fun isNetworkAvailable(activity: Activity): Boolean {
            val connectivityManager = activity.getSystemService(
                Context.CONNECTIVITY_SERVICE
            ) as ConnectivityManager


            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                val activeNetwork = connectivityManager.activeNetwork ?: return false
                val capabilities =
                    connectivityManager.getNetworkCapabilities(activeNetwork) ?: return false
                return when {
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> true
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> true
                    capabilities.hasTransport(NetworkCapabilities.TRANSPORT_ETHERNET) -> true
                    else -> false
                }
            } else {
                connectivityManager.activeNetworkInfo?.run {
                    return when (type) {
                        ConnectivityManager.TYPE_WIFI -> true
                        ConnectivityManager.TYPE_MOBILE -> true
                        ConnectivityManager.TYPE_ETHERNET -> true
                        else -> false
                    }
                }
            }
            return false
        }

        //valid email check
        fun isValidEmail(target: String?): Boolean {
            return Patterns.EMAIL_ADDRESS.matcher(target.toString()).matches()
        }


        //validPanCard
        fun isValidPan(pan: String?): Boolean {
            val mPattern = Pattern.compile("[A-Z]{5}\\d{4}[A-Z]")
            val mMatcher = mPattern.matcher(pan.toString())
            return mMatcher.matches()
        }

        fun isValidIndividualPan(pan: String): Boolean {
//            val mPattern = Pattern.compile("[A-Z]{3}P[A-Z]\\d{4}[A-Z]")
//            val mMatcher = mPattern.matcher(pan.toString())
//            return mMatcher.matches()
            return pan.length > 3 && pan[3] != 'P'
        }

        //is Indian mobile Number
        fun isIndianMobileNo(mobileNumber: String?): Boolean {
            //(0/91): number starts with (0/91)
            //[7-9]: starting of the number may contain a digit between 0 to 9
            //[0-9]: then contains digits 0 to 9
            val pattern: Pattern = Pattern.compile("^[6-9]\\d{9}$")
            //the matcher() method creates a matcher that will match the given input against this pattern
            val match: Matcher = pattern.matcher(mobileNumber.toString())
            //returns a boolean value
            return match.matches()
        }

        fun isValidMobileNumber(mobileNumber : String) : Boolean{
            return mobileNumber.length == 10
        }

        fun removeError(textInputLayout: TextInputLayout) {
            if (textInputLayout.error != null) {
                textInputLayout.error = null
                if (textInputLayout.isErrorEnabled) {
                    textInputLayout.isErrorEnabled = false
                }
            }
        }

        fun showDialogValidation(activity: Activity?, message: CharSequence?) {
            val builder = AlertDialog.Builder(activity)
            builder.setMessage(message)
            builder.setCancelable(false)
            if (activity != null) {
                builder.setPositiveButton(activity.getString(R.string.Ok)) { dialogInterface, _ ->
                    dialogInterface.dismiss()
                }
            }
            builder.show()
        }

        fun showWebViewDialogBottom(context: Context, url: String, height: Int) {
            val dialog = Dialog(context)
            dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
            dialog.setContentView(R.layout.web_view_bottom_dialog)
            val webView: WebView = dialog.findViewById(R.id.webView)
            val imageCross: ImageView = dialog.findViewById(R.id.imageCross)

            imageCross.setOnClickListener {
                dialog.dismiss()
            }
            webView.isScrollbarFadingEnabled = false
            webView.isHorizontalScrollBarEnabled = false
            webView.settings.javaScriptEnabled = true
            webView.settings.userAgentString = "AndroidWebView"
            webView.clearCache(true)
            webView.loadUrl(url)
            dialog.show()
            val window: Window = dialog.window!!
            window.setGravity(Gravity.BOTTOM)
            window.setLayout(ActionBar.LayoutParams.MATCH_PARENT, (height - 400))
            window.setWindowAnimations(R.style.DialogBottomAnimation)
        }

        fun showDialogWithTwoButtons(activity: Activity?, message: CharSequence?, title: String) {
            val builder = AlertDialog.Builder(activity)
            builder.setTitle(title)
            builder.setMessage(message)
            if (activity != null) {
                builder.setPositiveButton(activity.getString(R.string.Ok)) { dialogInterface, _ ->
                    val intent = Intent(
                        Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
                        Uri.fromParts(
                            "package",
                            (activity).packageName,
                            null
                        )
                    )
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    activity.startActivity(intent)
                    dialogInterface.dismiss()
                }
                builder.setNegativeButton(activity.getString(R.string.cancel)) { dialogInterface, _ ->
                    dialogInterface.dismiss()
                }
            }
            builder.show()
        }

        fun commonErrorMethod(
            inputText: TextInputEditText,
            inputError: TextInputLayout,
            strMessage: String
        ): Boolean {
            inputText.requestFocus()
            inputError.error = strMessage
            return false
        }

        fun commonSpinnerErrorMethod(
            inputText: MaterialAutoCompleteTextView,
            inputError: TextInputLayout,
            strMessage: String
        ): Boolean {
            inputText.requestFocus()
            inputError.error = strMessage
            return false
        }

        fun handleResponse(response: Response<JsonObject>): Resource<JsonObject> {
            if (response.isSuccessful && response.body() != null) {
                response.body()?.let { resultResponse ->
                    return Resource.Success(resultResponse)
                }
            }
            return Resource.Error(response.message())
        }

        fun handleError(activity: Activity): CoroutineExceptionHandler {
            val handler = CoroutineExceptionHandler { _, exception ->
                if (exception is IOException || exception is HttpException) {
                    showDialogValidation(
                        activity,
                        "Response : ".plus(exception.message).plus(" Cause: ").plus(exception.cause)
                    )
                } else {
                    showDialogValidation(
                        activity,
                        "Response : ".plus(exception.localizedMessage?.toString())
                    )
                }
            }
            return handler
        }

        /* this function is used for file size in readable format(End)*/
        fun getFileSizeInMB(length: Long): Double { // Get length of file in bytes
            val fileSizeInBytes =
                length.toDouble() // Convert the bytes to Kilobytes (1 KB = 1024 Bytes)
            val fileSizeInKB =
                fileSizeInBytes / 1024 // Convert the KB to MegaBytes (1 MB = 1024 KBytes)
            return fileSizeInKB / 1024
        }

        fun getFileExtension(name: String): String {
            val index = name.lastIndexOf('.')
            return if (index > 0) {
                name.substring(index + 1)
            } else {
                ""
            }
        }

        fun datePicker(activity: Activity, edtDOB: TextInputEditText,futureDate: Boolean): String {
            val cal = Calendar.getInstance()
            var preSelectedDate = ""
            val year: Int
            val month: Int
            val day: Int

            if (edtDOB.text.toString().isNotEmpty()) {
                val formatter: java.text.DateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.US)
                val dateObject = formatter.parse(edtDOB.text.toString()) as Date
                preSelectedDate = SimpleDateFormat("yyyy-MM-dd", Locale.US).format(dateObject)
                val items1: Array<String> = preSelectedDate.split("-").toTypedArray()
                year = items1[0].toInt()
                month = items1[1].toInt() - 1
                day = items1[2].toInt()
            } else {
                year = cal.get(Calendar.YEAR)
                month = cal.get(Calendar.MONTH)
                day = cal.get(Calendar.DAY_OF_MONTH)
            }

            val datePickerDialog = DatePickerDialog(
                activity as SignUpActivity, { _, years, monthOfYear, dayOfMonth ->
                    var monthsCount = (monthOfYear+1)
                    var selectedDay = if(dayOfMonth.toString().length == 1){
                        "0$dayOfMonth"
                    }else {
                        dayOfMonth
                    }
                    var monthYear = if (monthsCount.toString().length == 1) {
                        "0".plus(monthOfYear)
                    }else {
                        monthOfYear
                    }

                    preSelectedDate = years.toString().plus("-").plus(monthYear).plus("-").plus(selectedDay)
                    edtDOB.setText(preSelectedDate)
                    edtDOB.setSelection(edtDOB.text.toString().length)
                }, year, month, day
            )

            if(!futureDate) datePickerDialog.datePicker.maxDate = cal.timeInMillis
            val c = Calendar.getInstance()
            c.add(Calendar.YEAR, -140)
            datePickerDialog.datePicker.minDate = c.timeInMillis
            datePickerDialog.show()
            return preSelectedDate
        }

        fun getDateFromTimeMills(long: Long): String {
            val sdf = SimpleDateFormat("yyyy-MM-dd", Locale.US)
            val resultDate = Date(long)
            return sdf.format((resultDate))
        }

        //valid email check
        fun isValidPinCode(target: String): Boolean {
            return target.length != 6
        }
    }
}