/*
 * Tencent is pleased to support the open source community by making QMUI_Android available.
 *
 * Copyright (C) 2017-2018 THL A29 Limited, a Tencent company. All rights reserved.
 *
 * Licensed under the MIT License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 *
 * http://opensource.org/licenses/MIT
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.abbidot.baselibrary.list

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView

/**
 * @author cginechen
 * @date 2016-10-19
 * @description 配合DiffUtil使用取消notifyDataSetChanged()方法
 */
abstract class BaseRecyclerAdapter<T>(ctx: Context, list: MutableList<T>?) :
    RecyclerView.Adapter<RecyclerViewHolder>() {

    private var mData: MutableList<T> = mutableListOf()
    val mContext: Context
    private val mInflater: LayoutInflater
    private var mClickListener: OnItemClickListener? = null
    private var mLongClickListener: OnItemLongClickListener? = null

    //是否显示没有数据的添加按钮
    var isShowNoDataAddButton = true

    // 是否显示空布局，默认显示
    private var showEmptyView = true

    //重试事件,整个view点击
    private var mAgainClickListener: OnAgainClickListener? = null

    /**
     * viewType--分别为item以及空view
     */
    private val mViewTypeEmpty = 0
    private val mViewTypeItem = 1

    init {
        list?.apply {
            mData.addAll(this.toList())
        }
        mContext = ctx
        mInflater = LayoutInflater.from(ctx)
    }

    open fun setData(list: MutableList<T>?, isNeedNotifyData: Boolean = false) {
        clearData()
        if (null == list) {
            if (mData.size == 0) {
                showEmptyView(true)
            } else {
                showEmptyView(false)
            }
        }
        list?.apply {
            mData.addAll(list)
            //出现没有数据就显示空布局
            if (mData.size == 0) {
                showEmptyView(true)
            } else {
                showEmptyView(false)
            }
            if (isNeedNotifyData) {
                notifyItemRangeInserted(0, list.size)
//                notifyItemRangeChanged(0, list.size)
            }
        }
    }

    private fun clearData() {
        notifyItemRangeRemoved(0, mData.size)
        mData.clear()
    }

    fun getData() = mData

    fun remove(oldList: MutableList<T>, pos: Int): MutableList<T> {
        val newList: MutableList<T> = oldList.toMutableList()
        newList.removeAt(pos)
        return newList
    }


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
        val holder: RecyclerViewHolder
        //空布局
        if (getEmptyLayoutId(viewType) != 0 && viewType == mViewTypeEmpty) {
            holder = RecyclerViewHolder(
                mContext, mInflater.inflate(getEmptyLayoutId(viewType), parent, false)
            )
            if (null != mAgainClickListener) {
                holder.itemView.setOnClickListener {
                    mAgainClickListener!!.onAgainListener()
                }
            }
            mEmptyViewHolder = holder
        } else {
            holder = RecyclerViewHolder(
                mContext, mInflater.inflate(getItemLayoutId(viewType), parent, false)
            )
            if (null != mClickListener) {
                holder.itemView.setOnClickListener {
                    mClickListener!!.onItemClick(holder.itemView, holder.layoutPosition)
                }
            }
            if (null != mLongClickListener) {
                holder.itemView.setOnLongClickListener {
                    mLongClickListener!!.onItemLongClick(holder.itemView, holder.layoutPosition)
                    true
                }
            }
        }
        return holder
    }

    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
        if (mData.size > 0) bindData(holder, position, mData[position])
        else noData(holder)
    }

    private var mEmptyViewHolder: RecyclerViewHolder? = null

    override fun onBindViewHolder(
        holder: RecyclerViewHolder, position: Int, payloads: MutableList<Any>
    ) {
        if (payloads.isEmpty()) {
            onBindViewHolder(holder, position)
        } else {
            partBindData(holder, position, payloads[0] as T)
        }
    }

    /**
     * 判断是否是空布局
     */
    private fun isEmptyPosition(position: Int): Boolean {
        val count = mData.size
        return position == 0 && showEmptyView && count == 0
    }

    /**
     * 设置空布局显示。默认显示
     */
    private fun showEmptyView(isShow: Boolean) {
        if (isShow != showEmptyView) {
            showEmptyView = isShow
            notifyDataSetChanged()
        }
    }

    fun getItem(pos: Int) = mData[pos]

    //只有空布局默认才有一个item
    override fun getItemCount() =
        if (mData.size == 0 && getEmptyLayoutId(mViewTypeEmpty) != 0) 1 else mData.size

    override fun getItemViewType(position: Int) =
        if (isEmptyPosition(position)) mViewTypeEmpty else mViewTypeItem

    fun add(pos: Int, item: T) {
        mData.add(pos, item)
        notifyItemInserted(pos)
    }

    fun prepend(items: List<T>) {
        mData.addAll(0, items)
        notifyDataSetChanged()
    }

    fun append(items: List<T>) {
        mData.addAll(items)
        notifyDataSetChanged()
    }

    fun delete(pos: Int) {
        mData.removeAt(pos)
        notifyItemRemoved(pos)
    }

    fun showNoDataAddButton(show: Boolean) {
        isShowNoDataAddButton = show
        notifyDataSetChanged()
    }

    /**
     * 设置显示空布局 等于0不显示空布局
     */
    abstract fun getEmptyLayoutId(viewType: Int): Int
    abstract fun getItemLayoutId(viewType: Int): Int
    abstract fun bindData(holder: RecyclerViewHolder?, position: Int, item: T)

    //没有数据，空布局的情况
    open fun noData(holder: RecyclerViewHolder?) {

    }

    //局部刷新数据
    open fun partBindData(holder: RecyclerViewHolder, position: Int, item: T) {
        bindData(holder, position, mData[position])
    }

    fun setOnItemClickListener(listener: OnItemClickListener?) {
        mClickListener = listener
    }

    fun setOnItemLongClickListener(listener: OnItemLongClickListener?) {
        mLongClickListener = listener
    }

    fun setOnAgainClickListener(listener: OnAgainClickListener?) {
        mAgainClickListener = listener
    }

    interface OnItemClickListener {
        fun onItemClick(itemView: View?, pos: Int)
    }

    interface OnItemLongClickListener {
        fun onItemLongClick(itemView: View?, pos: Int)
    }

    /**
     * 点击屏幕重试 接口
     */
    interface OnAgainClickListener {
        /**
         * 点击屏幕重试
         */
        fun onAgainListener()
    }

}