package cn.muchinfo.rma.view.autoWidget

import android.content.Context
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.ViewManager
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import cn.muchinfo.rma.R
import com.qmuiteam.qmui.widget.QMUILoadingView

import org.jetbrains.anko.*
import org.jetbrains.anko.custom.ankoView

class StatusLayout internal constructor(context: Context) : FrameLayout(context) {
    lateinit var loadingView: LoadingStatusView
    lateinit var errorView: ErrorStatusView
    lateinit var emptyView: ErrorStatusView
    var contentView: View? = null
    var focusSuccess: Boolean = false
    var focusNotEmpty: Boolean = false
    var focusNotError: Boolean = false

    fun isSuccess(): Boolean = contentView?.visibility == View.VISIBLE
    fun isLoading(): Boolean = (loadingView as? View)?.visibility == View.VISIBLE
    fun isError(): Boolean = (errorView as? View)?.visibility == View.VISIBLE
    fun isEmpty(): Boolean = (emptyView as? View)?.visibility == View.VISIBLE

    fun setRetryAction(retryAction: (() -> Unit)) {
        errorView.retryAction = retryAction
        emptyView.retryAction = retryAction
    }

    fun showEmpty() {
        if (focusSuccess || focusNotEmpty) {
            showSuccess()
            return
        }
        loadingView.stopLoading()
        loadingView.hide()
        errorView.hide()
        emptyView.show()
        visibility = View.VISIBLE
        contentView?.visibility = View.GONE
    }

    fun showError(hint: CharSequence = "") {
        if (focusSuccess || focusNotError) {
            showSuccess()
            return
        }
        loadingView.stopLoading()
        loadingView.hide()
        errorView.setErrorHint(hint)
        errorView.show()
        emptyView.hide()
        visibility = View.VISIBLE
        contentView?.visibility = View.GONE
    }

    fun showLoading(hint: CharSequence = "") {
        loadingView.setLoadingText(hint)
        loadingView.show()
        errorView.hide()
        emptyView.hide()
        visibility = View.VISIBLE
        contentView?.visibility = View.GONE
    }

    fun showSuccess() {
        loadingView.hide()
        errorView.hide()
        emptyView.hide()
        if (contentView != null) {
            contentView?.visibility = View.VISIBLE
        } else {
            visibility = View.GONE
        }
    }
}

fun ViewManager.statusLayout(
        contentBlock: ((@AnkoViewDslMarker StatusLayout).() -> View)? = null,
        loadingBlock: ((@AnkoViewDslMarker StatusLayout).() -> LoadingStatusView)? = null,
        errorBlock: ((@AnkoViewDslMarker StatusLayout).() -> ErrorStatusView)? = null,
        emptyBlock: ((@AnkoViewDslMarker StatusLayout).() -> ErrorStatusView)? = null,
        contentViewSize: IntArray = intArrayOf(matchParent, matchParent),
        statusViewSize: IntArray = intArrayOf(matchParent, matchParent)
): StatusLayout = ankoView({ ctx: Context -> StatusLayout(ctx) }, theme = 0) {
    loadingView = loadingBlock?.invoke(this) ?: loadingView()
    (loadingView as? View)?.layoutParams = FrameLayout.LayoutParams(statusViewSize.getOrNull(0)
            ?: matchParent, statusViewSize.getOrNull(1) ?: matchParent)
    loadingView.hide()
    errorView = errorBlock?.invoke(this) ?: errorView()
    (errorView as? View)?.layoutParams = FrameLayout.LayoutParams(statusViewSize.getOrNull(0)
            ?: matchParent, statusViewSize.getOrNull(1) ?: matchParent)
    errorView.hide()
    emptyView = emptyBlock?.invoke(this) ?: emptyView()
    (emptyView as? View)?.layoutParams = FrameLayout.LayoutParams(statusViewSize.getOrNull(0)
            ?: matchParent, statusViewSize.getOrNull(1) ?: matchParent)
    emptyView.hide()
    contentView = contentBlock?.invoke(this)
    contentView?.layoutParams = FrameLayout.LayoutParams(contentViewSize.getOrNull(0)
            ?: matchParent, contentViewSize.getOrNull(1) ?: matchParent)
    layoutParams = ViewGroup.LayoutParams(matchParent, matchParent)
}

interface ErrorStatusView {

    val ivIcon: View

    var retryAction: (() -> Unit)?

    fun setErrorHint(hint: CharSequence = "")

    fun show() {
        (this as? View)?.visibility = View.VISIBLE
    }

    fun hide() {
        (this as? View)?.visibility = View.GONE
    }
}

class CommonErrorLayout internal constructor(context: Context) : LinearLayout(context), ErrorStatusView {

    override lateinit var ivIcon: ImageView
    lateinit var tvHint: TextView

    override var retryAction: (() -> Unit)? = null
        set(value) {
            field = value
            onThrottleFirstClick {
                value?.invoke()
            }
        }

    init {
        orientation = LinearLayout.VERTICAL
    }

    override fun setErrorHint(hint: CharSequence) {
        tvHint.text = hint
    }
}

fun StatusLayout.errorView(hint: CharSequence = ""): CommonErrorLayout = ankoView({ CommonErrorLayout(it) }, theme = 0) {
    gravity = Gravity.CENTER_HORIZONTAL
    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 1f)
    ivIcon = imageView { imageResource = R.drawable.ic_error_correction }
    ivIcon.layoutParams = LinearLayout.LayoutParams(autoSize(200), autoSize(200))
    space().layoutParams = LinearLayout.LayoutParams(matchParent, autoSize(32))
    tvHint = textView {
        textSizeAuto = 40
        textColorStr = "#6f7999"
        gravity = Gravity.CENTER
        text = hint
    }
    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 2f)
}

fun StatusLayout.error500View(hint: CharSequence = ""): CommonErrorLayout = ankoView({ CommonErrorLayout(it) }, theme = 0) {
    gravity = Gravity.CENTER_HORIZONTAL
    space(500)
    ivIcon = imageView { imageResource = R.drawable.ic_error_correction }
    ivIcon.layoutParams = LinearLayout.LayoutParams(autoSize(200), autoSize(200))
    space().layoutParams = LinearLayout.LayoutParams(matchParent, autoSize(32))
    tvHint = textView {
        textSizeAuto = 40
        textColorStr = "#6f7999"
        gravity = Gravity.CENTER
        text = hint
    }
    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 2f)
}


fun StatusLayout.emptyView(iconRes: Int = R.mipmap.withoutreport, hint: CharSequence = "暂无数据", iconHeight: Int = 240): CommonErrorLayout = ankoView({ CommonErrorLayout(it) }, theme = 0) {
    gravity = Gravity.CENTER_HORIZONTAL
    weightSum = 1350f
    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 360f)
    ivIcon = imageView { imageResource = iconRes }//暂时没有空页面的图片暂时不用
    ivIcon.layoutParams = LinearLayout.LayoutParams(wrapContent, autoSize(iconHeight))
//    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 48f)
    tvHint = textView {
        textSizeAuto = 36
        textColorInt = R.color.p_normal_summary_txt_color
        gravity = Gravity.CENTER
        text = hint
    }
    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 600f)
}

fun StatusLayout.empty500View(iconRes: Int = R.mipmap.withoutreport, hint: CharSequence = "暂无数据", iconHeight: Int = 240): CommonErrorLayout = ankoView({ CommonErrorLayout(it) }, theme = 0) {
    gravity = Gravity.CENTER_HORIZONTAL
    weightSum = 1350f
    space(500)
    ivIcon = imageView { imageResource = iconRes }//暂时没有空页面的图片暂时不用
    ivIcon.layoutParams = LinearLayout.LayoutParams(wrapContent, autoSize(iconHeight))
//    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 48f)
    tvHint = textView {
        textSizeAuto = 36
        textColorInt = R.color.p_normal_summary_txt_color
        gravity = Gravity.CENTER
        text = hint
    }
    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 600f)
}

interface LoadingStatusView {
    val ivIcon: View
    fun startLoading()
    fun setLoadingText(hint: CharSequence = "")
    fun stopLoading()
    fun show() {
        (this as? View)?.visibility = View.VISIBLE
        startLoading()
    }

    fun hide() {
        (this as? View)?.visibility = View.GONE
        stopLoading()
    }
}

class CommonLoadingLayout internal constructor(context: Context) : LinearLayout(context), LoadingStatusView {
    override lateinit var ivIcon: QMUILoadingView
    lateinit var tvHint: TextView

    init {
        orientation = LinearLayout.VERTICAL
    }

    override fun startLoading() {
        ivIcon.start()
    }

    override fun setLoadingText(hint: CharSequence) {
        tvHint.text = hint
    }

    override fun stopLoading() {
        ivIcon.stop()
    }
}

fun StatusLayout.loadingView(): CommonLoadingLayout = ankoView({ CommonLoadingLayout(it) }, theme = 0) {
    gravity = Gravity.CENTER
    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 1f)
//    space(400)
    ivIcon = ankoView({ QMUILoadingView(it) }, theme = 0) {
        layoutParams = LinearLayout.LayoutParams(autoSize(150), autoSize(150))
    }
    space().layoutParams = LinearLayout.LayoutParams(matchParent, autoSize(32))
    tvHint = textView {
        textSizeAuto = 40
        textColorStr = "#6f7999"
        gravity = Gravity.CENTER
    }
    space().layoutParams = LinearLayout.LayoutParams(matchParent, 0, 2f)
}