package org.mercury_im.messenger.ui.account;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Switch;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;

import org.jetbrains.annotations.NotNull;
import org.mercury_im.messenger.R;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.ui.avatar.AvatarDrawable;
import org.mercury_im.messenger.ui.account.AccountsFragment.OnAccountListItemClickListener;
import org.mercury_im.messenger.util.AbstractDiffCallback;
import org.mercury_im.messenger.xmpp.MercuryConnection;

import java.util.ArrayList;
import java.util.List;

import io.reactivex.android.schedulers.AndroidSchedulers;

public class AccountsRecyclerViewAdapter extends RecyclerView.Adapter<AccountsRecyclerViewAdapter.ViewHolder> {

    private final List<MercuryConnection> connections = new ArrayList<>();
    private final OnAccountListItemClickListener onAccountClickListener;
    private final AccountsViewModel viewModel;

    public AccountsRecyclerViewAdapter(AccountsViewModel viewModel, OnAccountListItemClickListener listener) {
        onAccountClickListener = listener;
        this.viewModel = viewModel;
    }

    @NotNull
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item_account, parent, false);
        return new ViewHolder(view);
    }

    public void setValues(List<MercuryConnection> values) {
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(
                new AccountsDiffCallback(values, connections), true);
        connections.clear();
        connections.addAll(values);
        diffResult.dispatchUpdatesTo(this);
    }

    @Override
    public int getItemCount() {
        return connections.size();
    }

    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {
        MercuryConnection connection = connections.get(position);
        Account account = connection.getAccount();

        holder.account = account;
        holder.jid.setText(account.getAddress());
        holder.avatar.setImageDrawable(new AvatarDrawable(account.getAddress(), account.getAddress()));
        holder.enabled.setChecked(account.isEnabled());
        holder.enabled.setOnCheckedChangeListener((compoundButton, checked) ->
                viewModel.setAccountEnabled(account, checked));

        setClickListenersOnViewHolder(holder);
    }

    private void setClickListenersOnViewHolder(ViewHolder holder) {
        holder.mView.setOnClickListener(v -> {
            if (null != onAccountClickListener) {
                onAccountClickListener.onAccountListItemClick(holder.account);
            }
        });

        holder.mView.setOnLongClickListener(v -> {
            if (null != onAccountClickListener) {
                onAccountClickListener.onAccountListItemLongClick(holder.account);
            }
            return true;
        });
    }

    class ViewHolder extends RecyclerView.ViewHolder {
        private Account account;
        final View mView;
        final ImageView avatar;
        final TextView jid;
        final Switch enabled;
        final TextView status;

        public ViewHolder(View view) {
            super(view);
            mView = view;
            avatar = view.findViewById(R.id.avatar_account);
            jid = view.findViewById(R.id.text_account_jid);
            enabled = view.findViewById(R.id.switch_account_enabled);
            status = view.findViewById(R.id.text_account_status);
        }
    }

    public class AccountsDiffCallback extends AbstractDiffCallback<MercuryConnection> {

        public AccountsDiffCallback(List<MercuryConnection> newItems, List<MercuryConnection> oldItems) {
            super(newItems, oldItems);
        }

        @Override
        public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
            return oldItems.get(oldItemPosition).getAccount().getId().equals(newItems.get(newItemPosition).getAccount().getId());
        }

        @Override
        public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
            Account oldM = oldItems.get(oldItemPosition).getAccount();
            Account newM = newItems.get(newItemPosition).getAccount();
            return oldM.equals(newM);
        }
    }
}
