package es.verdnatura.presentation.common

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.media.AudioManager
import android.os.Bundle
import android.text.InputType
import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentTransaction
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import java.util.*


inline fun FragmentManager.inTransaction(func: FragmentTransaction.() -> FragmentTransaction) =
    beginTransaction().func().commit()


fun <T> Context.openActivity(it: Class<T>, extras: Bundle.() -> Unit = {}) {
    val intent = Intent(this, it)
    intent.putExtras(Bundle().apply(extras))
    startActivity(intent)
}

fun FragmentActivity.replaceFragment(
    fragment: Fragment,
    frameId: Int,
    tag: String,
    addToBackStack: Boolean = false
) {
    supportFragmentManager.inTransaction {
        replace(frameId, fragment, tag)
        if (addToBackStack) addToBackStack(tag)
        setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
    }
}

fun FragmentActivity.addFragment(
    fragment: Fragment,
    frameId: Int,
    tag: String = "",
    addToBackStack: Boolean = false
) {
    supportFragmentManager.inTransaction {
        add(frameId, fragment, tag)
        if (addToBackStack) addToBackStack(tag)
        setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
    }
}

fun View.setDimensions(width: Int, height: Int) {
    val layoutParams = this.layoutParams
    layoutParams?.width = width
    layoutParams?.height = height
    this.layoutParams = layoutParams
}

fun View.setMargins(left: Int, top: Int, right: Int, bottom: Int) {
    val mlp = this.layoutParams as ViewGroup.MarginLayoutParams
    mlp.setMargins(left, top, right, bottom)
}

fun ImageView.loadUrl(url: String) {
    Glide.with(context)
        .asBitmap()
        .load(url)
        .into(object : CustomTarget<Bitmap>() {

            override fun onLoadCleared(placeholder: Drawable?) {}

            override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
                setImageBitmap(resource)
            }
        })
}

inline val <reified T> T.TAG: String
    get() = T::class.java.canonicalName ?: T::class.simpleName ?: T::class.java.simpleName

fun Calendar.convertToDateString(): String {
    var dayOfWeek = ""
    var dayOfMonth = ""
    val day = this[Calendar.DATE]

    when (this[Calendar.DAY_OF_WEEK]) {
        1 -> dayOfWeek = "Dom"
        2 -> dayOfWeek = "Lun"
        3 -> dayOfWeek = "Mar"
        4 -> dayOfWeek = "Mie"
        5 -> dayOfWeek = "Jue"
        6 -> dayOfWeek = "Vie"
        7 -> dayOfWeek = "Sab"
    }

    when (this[Calendar.MONTH]) {
        0 -> dayOfMonth = "Ene"
        1 -> dayOfMonth = "Feb"
        2 -> dayOfMonth = "Mar"
        3 -> dayOfMonth = "Abr"
        4 -> dayOfMonth = "May"
        5 -> dayOfMonth = "Jun"
        6 -> dayOfMonth = "Jul"
        7 -> dayOfMonth = "Ago"
        8 -> dayOfMonth = "Sep"
        9 -> dayOfMonth = "Oct"
        10 -> dayOfMonth = "Nov"
        11 -> dayOfMonth = "Dic"
    }

    return dayOfWeek + " " + day + " " + dayOfMonth
}

fun RecyclerView.addViewObserver(function: () -> Unit) {
    val view = this
    view.viewTreeObserver.addOnGlobalLayoutListener(object :
        ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            view.viewTreeObserver.removeOnGlobalLayoutListener(this)
            function.invoke()
        }
    })
}

fun Fragment.hideKeyboard() {
    view?.let { activity?.hideKeyboard(it) }
}

fun Activity.hideKeyboard() {
    hideKeyboard(currentFocus ?: View(this))
}

fun Activity.showKeyboardIn() {
    showKeyboardIn(currentFocus ?: View(this))
}

fun Context.hideKeyboard(view: View) {
    val inputMethodManager = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
    inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0)
}

fun Context.showKeyboard() {
    val imm = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager?
    imm!!.toggleSoftInput(InputType.TYPE_CLASS_NUMBER, 0)

}

fun Context.showKeyboardIn(view: View) {
    val imm = getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager?
    imm!!.showSoftInput(view, 0)

}

// Extension function to change media volume programmatically
fun AudioManager.setMediaVolume(volumeIndex: Int) {
    // Set media volume level
    this.setStreamVolume(
        AudioManager.STREAM_MUSIC, // Stream type
        volumeIndex, // Volume index
        AudioManager.FLAG_SHOW_UI// Flags
    )
}

// Extension property to get media maximum volume index
val AudioManager.mediaMaxVolume: Int
    get() = this.getStreamMaxVolume(AudioManager.STREAM_MUSIC)

// Extension property to get media/music current volume index
val AudioManager.mediaCurrentVolume: Int
    get() = this.getStreamVolume(AudioManager.STREAM_MUSIC)
