package ch.threema.app.adapters.poll;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.RadioButton;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.google.android.material.button.MaterialButton;

import java.util.List;
import java.util.Map;

import ch.threema.app.R;
import ch.threema.app.ThreemaApplication;
import ch.threema.app.managers.ServiceManager;
import ch.threema.app.ui.CheckableRelativeLayout;
import ch.threema.storage.models.poll.PollChoiceModel;

public class PollVoteListAdapter extends ArrayAdapter<PollChoiceModel> {

    private final Context context;
    private final List<PollChoiceModel> values;
    private final Map<Integer, Integer> selected;
    private final boolean readonly;
    private final boolean multipleChoice;
    private final boolean showVoting;

    public PollVoteListAdapter(
        Context context,
        List<PollChoiceModel> values,
        Map<Integer, Integer> selected,
        boolean readonly,
        boolean multipleChoice,
        boolean showVoting
    ) {
        super(context, R.layout.item_poll_choice_vote, values);

        this.context = context;
        this.readonly = readonly;
        this.multipleChoice = multipleChoice;
        this.showVoting = showVoting;
        this.values = values;
        this.selected = selected;
    }

    private static class PollAdminChoiceItemHolder {
        public TextView name;
        public MaterialButton voteCount;
        public RadioButton radioButton;
        public CheckBox checkBox;
        int originalPosition;
    }

    @NonNull
    @Override
    public View getView(int position, View convertView, @NonNull ViewGroup parent) {
        CheckableRelativeLayout itemView = (CheckableRelativeLayout) convertView;
        PollAdminChoiceItemHolder holder;

        if (convertView == null) {
            holder = new PollAdminChoiceItemHolder();
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            itemView = (CheckableRelativeLayout) inflater.inflate(R.layout.item_poll_choice_vote, parent, false);

            holder.name = itemView.findViewById(R.id.choice_name);
            holder.voteCount = itemView.findViewById(R.id.vote_count);
            holder.radioButton = itemView.findViewById(R.id.choice_radio);
            holder.checkBox = itemView.findViewById(R.id.choice_checkbox);

            itemView.setTag(holder);
        } else {
            holder = (PollAdminChoiceItemHolder) itemView.getTag();
        }

        itemView.setOnCheckedChangeListener(null);

        final PollChoiceModel choiceModel = values.get(position);
        holder.originalPosition = position;

        if (choiceModel != null) {
            if (holder.name != null) {
                holder.name.setText(choiceModel.getName());
            }
            if (holder.voteCount != null) {
                holder.voteCount.setVisibility(this.showVoting ? View.VISIBLE : View.GONE);
                if (this.showVoting) {
                    long c = 0;
                    try {
                        c = ServiceManager.require().getPollService().getVotingCount(choiceModel);
                    } catch (Exception ignored) {
                    }
                    holder.voteCount.setText(String.valueOf(c));
                    holder.voteCount.setVisibility(View.VISIBLE);
                }
            }
            itemView.setChecked(this.isSelected(choiceModel));
        }

        if (holder.checkBox != null && holder.radioButton != null) {
            holder.radioButton.setVisibility(!this.multipleChoice ? View.VISIBLE : View.GONE);
            holder.radioButton.setEnabled(!this.readonly);

            holder.checkBox.setVisibility(this.multipleChoice ? View.VISIBLE : View.GONE);
            holder.checkBox.setEnabled(!this.readonly);
        }

        if (!this.readonly) {
            itemView.setOnCheckedChangeListener((checkableView, isChecked) -> {
                select(values.get(((PollAdminChoiceItemHolder) checkableView.getTag()).originalPosition), isChecked);
            });
        }

        return itemView;
    }

    public Map<Integer, Integer> getSelectedChoices() {
        return this.selected;
    }

    public boolean isSelected(final PollChoiceModel model) {
        synchronized (this.selected) {
            int k = model.getId();
            return selected.containsKey(k) && selected.get(k) == 1;
        }
    }

    public void select(final PollChoiceModel model, boolean select) {
        synchronized (this.selected) {
            int id = model.getId();

            if (!this.multipleChoice) {
                this.selected.clear();
                this.selected.put(id, 1);
                notifyDataSetChanged();
            } else {
                this.selected.put(id, (select ? 1 : 0));
            }
        }
    }
}
