package com.bc_chat.im.view

import android.content.Context
import android.support.v4.view.ViewCompat
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.StaggeredGridLayoutManager
import android.util.AttributeSet
import android.view.ViewGroup
import java.util.*


/**

 * 简单的带上拉自动加载更多的系统SwipeRefreshLayout+RecyclerView
 */
class SwipeRefreshRecyclerLayout : SwipeRefreshLayout, SwipeRefreshLayout.OnRefreshListener {


    lateinit var mRecyclerView: RecyclerView
    private var mAdapter: RecyclerView.Adapter<*>? = null
    private var state = State.RESET
    private var mode = Mode.START
    private var onRefreshListener: OnRefreshListener? = null
    private val scrollListeners = ArrayList<RecyclerView.OnScrollListener>()
    private var iterator: MutableIterator<RecyclerView.OnScrollListener>? = null
    private var lastVisibleItem = 0
    private var lastPositions: IntArray? = null

    constructor(context: Context) : super(context) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init()
    }

    internal fun init() {
        mRecyclerView = RecyclerView(context)
        mRecyclerView.setHasFixedSize(true)
        mRecyclerView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        addView(mRecyclerView)
        setOnRefreshListener(this)
        mRecyclerView.addOnScrollListener(onScrollListener)
    }

    private val onScrollListener = object : RecyclerView.OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            iterator = scrollListeners.iterator()
            while (iterator!!.hasNext()) {
                val listener = iterator?.next()
                listener?.onScrollStateChanged(recyclerView, newState)
            }
            if (newState == RecyclerView.SCROLL_STATE_IDLE && state == State.RESET) {
                resetLastVisibleItem()
                if (mAdapter != null && lastVisibleItem + 1 == mAdapter?.itemCount && !isRefreshing) {
                    if (!isCanScollVertically(recyclerView)) {
                        mode = Mode.END
                        state = State.REFRESHING
                        onRefreshListener?.onRefreshFromEnd()
                    }
                }
            }
        }

        override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
            super.onScrolled(recyclerView, dx, dy)
            synchronized(SwipeRefreshRecyclerLayout::class.java) {
                val iterator = scrollListeners.iterator()
                while (iterator.hasNext()) {
                    val listener = iterator.next()
                    listener.onScrolled(recyclerView, dx, dy)
                }
            }
        }
    }

    private fun isCanScollVertically(recyclerView: RecyclerView): Boolean {
        return if (android.os.Build.VERSION.SDK_INT < 14) {
            ViewCompat.canScrollVertically(recyclerView, 1) || recyclerView.scrollY < recyclerView.height
        } else {
            ViewCompat.canScrollVertically(recyclerView, 1)
        }
    }

    fun smoothScrollToPosition(position: Int) {
        mRecyclerView.smoothScrollToPosition(position)
    }

    fun addOnScrollListener(l: RecyclerView.OnScrollListener) {
        this.scrollListeners.add(l)
    }

    fun removeOnScrollListener(l: RecyclerView.OnScrollListener) {
        this.scrollListeners.remove(l)
    }

    fun removeCurrentOnScrollListener() {
        iterator?.remove()
    }

    fun setAdapter(adapter: RecyclerView.Adapter<*>?) {
        mAdapter = adapter
        mRecyclerView.adapter = mAdapter
    }

    fun setLayoutManager(layoutManager: RecyclerView.LayoutManager) {
        mRecyclerView.layoutManager = layoutManager
    }

    fun addItemDecoration(itemDecoration: RecyclerView.ItemDecoration) {
        mRecyclerView.addItemDecoration(itemDecoration)
    }

    fun removeItemDecoration(decoration: RecyclerView.ItemDecoration) {
        mRecyclerView.removeItemDecoration(decoration)
    }

    fun setOnRefreshListener(onRefreshListener: OnRefreshListener) {
        this.onRefreshListener = onRefreshListener
    }

    fun getRefreshState(): State {
        return state
    }

    /**
     * 重新获取可见item的位置
     */
    private fun resetLastVisibleItem() {
        val layoutManager = mRecyclerView.layoutManager
        if (layoutManager != null && layoutManager is LinearLayoutManager) {
            lastVisibleItem = layoutManager.findLastVisibleItemPosition()
        } else if (layoutManager != null && layoutManager is StaggeredGridLayoutManager) {
            if (lastPositions == null) {
                lastPositions = IntArray(layoutManager.spanCount)
            }
            layoutManager.findLastVisibleItemPositions(lastPositions)
            lastVisibleItem = findMax(lastPositions!!)
        }
    }

    private fun findMax(lastPositions: IntArray): Int {
        var max = lastPositions[0]
        for (value in lastPositions) {
            if (value > max) {
                max = value
            }
        }
        return max
    }

    fun setRefreshState(state: State) {
        this.state = state
        isRefreshing = state != State.RESET
    }

    fun getRefreshMode(): Mode {
        return mode
    }

    fun setRefreshMode(mode: Mode) {
        this.mode = mode
    }

    override fun onRefresh() {
        onRefreshListener?.onRefreshFromStart()
        state = State.REFRESHING
        mode = Mode.START
    }

    fun onRefreshStart(mode: Mode) {
        this.state = State.REFRESHING
        this.mode = mode
    }

    enum class State {
        REFRESHING,
        RESET
    }

    enum class Mode {
        START,
        END,
        BOTH
    }

    interface OnRefreshListener {
        fun onRefreshFromStart()

        fun onRefreshFromEnd()
    }
}
