package com.autotech.we1l.my_classes;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public abstract class BaseAdapter<VH extends RecyclerView.ViewHolder, ITEM extends BaseItem> extends RecyclerView.Adapter<VH> {

    protected final Context context;
    public final BaseList<ITEM> data = new BaseList<>();
    protected OnClickListener<ITEM> onClickListener;
    private int viewRes = -1;

    public BaseAdapter(Context context, BaseList<ITEM> data) {
        this.context = context;
        this.data.addAll(data);
        this.onClickListener = null;
    }

    public BaseAdapter(Context context, BaseList<ITEM> data, int viewRes) {
        this.context = context;
        this.data.addAll(data);
        this.onClickListener = null;
        this.viewRes = viewRes;
    }

    public BaseAdapter(Context context, BaseList<ITEM> data, OnClickListener<ITEM> onClickListener) {
        this(context, data);
        this.onClickListener = onClickListener;
    }

    public BaseAdapter(Context context, BaseList<ITEM> data, int viewRes, OnClickListener<ITEM>  onClickListener) {
        this(context, data);
        this.onClickListener = onClickListener;
        this.viewRes = viewRes;
    }

    public void updateData(BaseList<ITEM> newData) {
        this.data.clear();
        this.data.addAll(newData);
        notifyDataSetChanged();
    }

    public void addItem(ITEM addedItem) {
        this.data.add(0, addedItem);
        notifyItemInserted(0);
    }

    public int getItemCount() {
        return data.size();
    }

    protected View inflate(int resId, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(resId, parent, false);
    }

    public void add(ITEM item) {
        data.add(item);
        notifyItemInserted(data.indexOf(item));
    }

    public void add(int position, ITEM item) {
        data.add(position, item);
        notifyItemInserted(position);
    }

    public void addForceRefresh(int position, ITEM item) {
        data.add(position, item);
        notifyDataSetChanged();
    }

    public void remove(int position) {
        data.remove(position);
        notifyItemRemoved(position);
    }

    public void removeForceRefresh(int position) {
        data.remove(position);
        notifyDataSetChanged();
    }

    public void remove(ITEM item) {
        int position = data.indexOf(item);
        data.remove(item);
        notifyItemRemoved(position);
    }

    public void removeForceRefresh(ITEM item) {
        data.remove(item);
        notifyDataSetChanged();
    }

    public void removeAllFrom(int position) {
        int size = data.size();

        data.subList(position, size - 1).clear();
        notifyItemRangeRemoved(position, size - 1);
    }

    public void removeAllFromForceRefresh(int position) {
        int size = data.size();

        for (int i = position; i < size; i++) {
            data.remove(i);
        }
        notifyDataSetChanged();
    }

    public void removeLast() {
        int size = data.size();

        data.remove(size - 1);
        notifyItemRemoved(size - 1);
    }

    public void removeLastForceRefresh() {
        int size = data.size();

        data.remove(size - 1);
        notifyDataSetChanged();
    }

    public void refresh(int position) {
        notifyItemChanged(position);
    }

    public void clear() {
        data.clear();
        notifyDataSetChanged();
    }

    public void refresh() {
        for (int i = 0; i < data.size(); i++) {
            notifyItemChanged(i);
        }
    }

    public ITEM getItem(int index) {
        return data.get(index);
    }

    public void onBindViewHolder(@NonNull VH holder, int position) {
        holder.itemView.setOnClickListener(view -> {
                    if (onClickListener != null)
                        onClickListener.onClick(holder, position, data.get(position));
                }
        );

        holder.itemView.setOnLongClickListener(view -> {
            if (onClickListener != null)
                onClickListener.onLongClick(holder, position, data.get(position));
            return true;
        });
        onBindViewHolderToItem(holder, data.get(position), position);
    }

    public void onBindViewHolderToItem(@NonNull VH holder, @NonNull ITEM item, int position) {

    }

    public interface OnClickListener<ITEM extends BaseItem> {

        default void onClick(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull ITEM item) {
        }

        default void onLongClick(@NonNull RecyclerView.ViewHolder holder, int position, @NonNull ITEM item) {
        }

        default void onSpecialClick(@NonNull View view, @NonNull RecyclerView.ViewHolder holder, int position, @NonNull ITEM item) {
        }
    }

}
