package com.ysnows.base.base

import android.content.Context
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.annotation.ArrayRes
import androidx.annotation.ColorRes
import androidx.annotation.IdRes
import androidx.annotation.StringRes
import androidx.databinding.ViewDataBinding
import androidx.lifecycle.ViewModelProvider
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.hwangjr.rxbus.RxBus
import com.kingja.loadsir.callback.Callback.OnReloadListener
import com.kingja.loadsir.core.LoadService
import com.kingja.loadsir.core.LoadSir
import com.trello.rxlifecycle2.components.support.RxFragment
import com.ysnows.base.BR
import com.ysnows.base.R
import com.ysnows.base.utils.Toasts
import com.ysnows.base.utils.UiSwitch
import com.ysnows.base.view.BView
import com.ysnows.base.widget.TitleBar
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlin.coroutines.CoroutineContext

/**
 * Base Fragment
 *
 * @param <VM>
 * @param <B>
</B></VM> */
abstract class BFragment<VM : BViewModel<*>, B : ViewDataBinding> : RxFragment(), BView, OnReloadListener, TitleBar.DataSource, CoroutineScope {
    override var loadService: LoadService<*>? = null

    protected lateinit var vm: VM
    protected lateinit var binding: B
    private var swipeRefreshLayout: SwipeRefreshLayout? = null


    private val job = SupervisorJob()

    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job


    override fun coroutine(): CoroutineScope {
        return this
    }

    private var isRefresh=false//没有数据时候点击不刷新

    protected var titleBar: TitleBar? = null

    private var page_status = 0
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        swipeRefreshLayout = view.findViewById(R.id.refresh_layout)
        if (swipeRefreshLayout != null) {
            setSwipeRefreshLayoutStyle()
        }
        var contentView: View? = null

        if (provideContainerId() != -1) {
            contentView = view.findViewById(provideContainerId())
        }
        if (contentView != null) {
            loadService = LoadSir.getDefault().register(contentView, this)
        }
        __before(savedInstanceState)
        initView(view)
        listeners()
        customizeEmptyView()
        init(savedInstanceState)
        isRefresh=true
        onReload(view)
    }

    open fun __before(savedInstanceState: Bundle?) {}
    override fun onDestroy() {
        super.onDestroy()
        unRegister()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        register()
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = binding(inflater, container)
        binding.lifecycleOwner = this
        vm = ViewModelProvider(this).get(vmClass())
        vm.init()
        vm.attachView(this)
        binding.setVariable(BR.vm, vm)
        val view = binding.root as ViewGroup
        if (title() != null) {
            titleBar = TitleBar(context()!!, this)
            view.addView(titleBar, 0)
        }
        return view
    }

    override fun initView(view: View?) {}

    /**
     * 初始化
     *
     * @param savedInstanceState
     */
    protected open fun init(savedInstanceState: Bundle?) {}
    override fun customizeEmptyView() {}

    /**
     * 初始化Listeners
     */
    override fun listeners() {}
    protected abstract fun binding(inflater: LayoutInflater, container: ViewGroup?): B

    protected open fun vmClass(): Class<VM> {
        return BViewModel::class.java as Class<VM>
    }

    override fun context(): Context {
        return requireContext()
    }


    override fun onReload(v: View?) {
        if (needLogin() && user() == null) {
            toLogin()
            return
        }
        if(isRefresh) {
            vm.firstReq()
            isRefresh=false
        }
    }

    override fun finishActivity() {
        requireActivity().onBackPressed()
        requireActivity().overridePendingTransition(0, R.anim.acitivity_show_out_amination)
    }

    override fun finish() {
        requireActivity().onBackPressed()
    }

    override fun toast(msg: String?) {
        if (!TextUtils.isEmpty(msg)) {
            runOnUi(Runnable { Toasts.toast(context(), msg) })
        }
    }

    override fun toast(@StringRes msgID: Int) {
        toast(resources.getString(msgID))
    }

    override fun needLogin(): Boolean {
        return false
    }

    override fun processCodeOffline() {

    }

    override fun toLogin() {
        page_status = BActivity.TO_LOGIN
    }

    override fun onResume() {
        super.onResume()
        if (page_status == BActivity.TO_LOGIN) {
            onRefresh()
            page_status = 0
        }
    }

    override fun getEdtStr(editText: EditText?): String? {
        return editText!!.text.toString().trim { it <= ' ' }
    }

    override fun getStr(stringId: Int): String? {
        return getString(stringId)
    }

    override fun getStrArr(@ArrayRes strArrId: Int): Array<String?>? {
        return resources.getStringArray(strArrId)
    }

    override fun <T> single(clazz: Class<T>?) {
        UiSwitch.single(context(), clazz)
    }

    override fun <T> bundle(clazz: Class<T>?, bundle: Bundle?) {
        UiSwitch.bundle(context(), clazz, bundle)
    }

    override val isRxbus: Boolean
        get() = false

    override fun register() {
        if (isRxbus) {
            RxBus.get().register(this)
        }
    }

    override fun unRegister() {
        if (isRxbus) {
            RxBus.get().unregister(this)
        }
    }

    override fun view(): BView? {
        return this
    }

    override fun title(): String? {
        return ""
    }

    override fun backable(): Boolean {
        return true
    }

    @ColorRes
    override fun titleColor(): Int {
        return R.color.white
    }


    @ColorRes
    override fun rightTextColor(): Int {
        return R.color.white
    }


    override fun titleSize(): Int {
        return 17
    }

    fun setTitle(title: String?) {
        val activity = getActivity()
        activity?.runOnUiThread {
            if (titleBar != null) {
                if (!TextUtils.isEmpty(title)) {
                    titleBar!!.tv_title_bottom!!.visibility = View.VISIBLE
                    titleBar!!.tv_title_bottom!!.text = title
                } else {
                    titleBar!!.tv_title_bottom!!.visibility = View.GONE
                }
            }
        }
    }

    override fun runOnUi(runnable: Runnable?) {
        requireActivity().runOnUiThread(runnable)
    }


    override fun setStatusBar() {}
    override fun transluent(): Boolean = false

    override fun onRefresh() {
        isRefresh=true
        onReload(null)
    }

    override fun refreshing(refreshing: Boolean) {
        if (swipeRefreshLayout != null) {
            swipeRefreshLayout!!.isRefreshing = refreshing
        }
    }

    override val isNeedRefresh: Boolean
        get() = true

    fun setSwipeRefreshLayoutStyle() {
        /*下拉刷新设置*/
        if (swipeRefreshLayout != null) {
            swipeRefreshLayout!!.setColorSchemeResources(R.color.refresh_colorPrimary, R.color.refresh_colorAccent, R.color.refresh_colorPrimaryDark)
            swipeRefreshLayout!!.setOnRefreshListener { onRefresh() }
            swipeRefreshLayout!!.isEnabled = isNeedRefresh
        }
    }

    @IdRes
    override fun provideContainerId(): Int {
        return R.id.refresh_layout
    }

    override fun exitFromTopAnim(): Boolean {
        return false
    }
}
