package app.fedilab.android.mastodon.helper;
/* Copyright 2022 Thomas Schneider
 *
 * This file is a part of Fedilab
 *
 * This program is free software; you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with Fedilab; if not,
 * see <http://www.gnu.org/licenses>. */


import static app.fedilab.android.BaseMainActivity.currentAccount;
import static app.fedilab.android.BaseMainActivity.currentInstance;
import static app.fedilab.android.BaseMainActivity.currentUserID;
import static app.fedilab.android.BaseMainActivity.show_boosts;
import static app.fedilab.android.BaseMainActivity.show_dms;
import static app.fedilab.android.BaseMainActivity.show_replies;

import android.annotation.SuppressLint;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatTextView;
import androidx.appcompat.widget.PopupMenu;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.PreferenceManager;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.tabs.TabLayout;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;

import app.fedilab.android.BaseMainActivity;
import app.fedilab.android.R;
import app.fedilab.android.activities.MainActivity;
import app.fedilab.android.databinding.ActivityMainBinding;
import app.fedilab.android.databinding.DialogBubbleExcludeVisibilityBinding;
import app.fedilab.android.databinding.DialogBubbleReplyVisibilityBinding;
import app.fedilab.android.databinding.TabCustomDefaultViewBinding;
import app.fedilab.android.databinding.TabCustomViewBinding;
import app.fedilab.android.mastodon.client.entities.api.MastodonList;
import app.fedilab.android.mastodon.client.entities.app.BottomMenu;
import app.fedilab.android.mastodon.client.entities.app.BubbleTimeline;
import app.fedilab.android.mastodon.client.entities.app.Pinned;
import app.fedilab.android.mastodon.client.entities.app.PinnedTimeline;
import app.fedilab.android.mastodon.client.entities.app.RemoteInstance;
import app.fedilab.android.mastodon.client.entities.app.StatusCache;
import app.fedilab.android.mastodon.client.entities.app.TagTimeline;
import app.fedilab.android.mastodon.client.entities.app.Timeline;
import app.fedilab.android.mastodon.exception.DBException;
import app.fedilab.android.mastodon.ui.fragment.timeline.FragmentMastodonConversation;
import app.fedilab.android.mastodon.ui.fragment.timeline.FragmentMastodonTimeline;
import app.fedilab.android.mastodon.ui.fragment.timeline.FragmentNotificationContainer;
import app.fedilab.android.mastodon.ui.pageadapter.FedilabPageAdapter;
import es.dmoral.toasty.Toasty;

public class PinnedTimelineHelper {


    public static void sortPositionAsc(List<PinnedTimeline> pinnedTimelineList) {
        //noinspection ComparatorCombinators
        Collections.sort(pinnedTimelineList, (obj1, obj2) -> Integer.compare(obj1.position, obj2.position));
    }

    public static void sortListPositionAsc(List<MastodonList> mastodonLists) {
        //noinspection ComparatorCombinators
        Collections.sort(mastodonLists, (obj1, obj2) -> Integer.compare(obj1.position, obj2.position));
    }

    public static void sortMenuItem(List<BottomMenu.MenuItem> menuItemList) {
        //noinspection ComparatorCombinators
        Collections.sort(menuItemList, (obj1, obj2) -> Integer.compare(obj1.position, obj2.position));
    }


    public synchronized static void redrawTopBarPinned(BaseMainActivity activity, ActivityMainBinding activityMainBinding, Pinned pinned, BottomMenu bottomMenu, List<MastodonList> mastodonLists) {
        //Values must be initialized if there is no records in db
        if (pinned == null) {
            pinned = new Pinned();
            pinned.user_id = currentUserID;
            pinned.instance = currentInstance;
        }
        if (pinned.pinnedTimelines == null) {
            pinned.pinnedTimelines = new ArrayList<>();
        }
        //Set the slug of first visible fragment
        /*String slugOfFirstFragment = PinnedTimelineHelper.firstTimelineSlug(activity, pinned, bottomMenu);
        Helper.setSlugOfFirstFragment(activity, slugOfFirstFragment, currentUserID, currentInstance);*/

        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
        boolean singleBar = sharedpreferences.getBoolean(activity.getString(R.string.SET_USE_SINGLE_TOPBAR), false);
        boolean timeInList = sharedpreferences.getBoolean(activity.getString(R.string.SET_TIMELINES_IN_A_LIST), false);
        if (timeInList) {
            activityMainBinding.moreTimelines.setVisibility(View.VISIBLE);
        } else {
            activityMainBinding.moreTimelines.setVisibility(View.GONE);
        }

        ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) activityMainBinding.viewPager.getLayoutParams();
        //Hiding/Showing bottom menu depending of settings
        if (singleBar) {
            activityMainBinding.bottomNavView.setVisibility(View.GONE);
            params.setMargins(0, 0, 0, 0);
        } else {
            TypedValue tv = new TypedValue();
            activityMainBinding.bottomNavView.setVisibility(View.VISIBLE);
            if (activity.getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) {
                int actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, activity.getResources().getDisplayMetrics());
                params.setMargins(0, 0, 0, actionBarHeight);
            }
        }

        activityMainBinding.viewPager.setLayoutParams(params);
        List<PinnedTimeline> pinnedTimelines = pinned.pinnedTimelines;
        boolean extraFeatures = sharedpreferences.getBoolean(activity.getString(R.string.SET_EXTAND_EXTRA_FEATURES) + MainActivity.currentUserID + MainActivity.currentInstance, false);

        if (singleBar) {
            boolean createDefaultAtTop = true;
            for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
                if (pinnedTimeline.type == Timeline.TimeLineEnum.HOME) {
                    createDefaultAtTop = false;
                    break;
                }
            }
            //Default item in top doesn't exist yet, we have to create them, it should be done once
            if (createDefaultAtTop) {
                //We shift all position
                for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
                    pinnedTimeline.position += FedilabPageAdapter.BOTTOM_TIMELINE_COUNT;
                }
                PinnedTimeline pinnedTimelineHome = new PinnedTimeline();
                pinnedTimelineHome.type = Timeline.TimeLineEnum.HOME;
                pinnedTimelineHome.position = 0;
                pinned.pinnedTimelines.add(pinnedTimelineHome);
                PinnedTimeline pinnedTimelineLocal = new PinnedTimeline();
                pinnedTimelineLocal.type = Timeline.TimeLineEnum.LOCAL;
                pinnedTimelineLocal.position = 1;
                pinned.pinnedTimelines.add(pinnedTimelineLocal);
                PinnedTimeline pinnedTimelinePublic = new PinnedTimeline();
                pinnedTimelinePublic.type = Timeline.TimeLineEnum.PUBLIC;
                pinnedTimelinePublic.position = 2;
                pinned.pinnedTimelines.add(pinnedTimelinePublic);
                PinnedTimeline pinnedTimelineNotifications = new PinnedTimeline();
                pinnedTimelineNotifications.type = Timeline.TimeLineEnum.NOTIFICATION;
                pinnedTimelineNotifications.position = 3;
                pinned.pinnedTimelines.add(pinnedTimelineNotifications);
                PinnedTimeline pinnedTimelineConversations = new PinnedTimeline();
                pinnedTimelineConversations.type = Timeline.TimeLineEnum.DIRECT;
                pinnedTimelineConversations.position = 4;
                pinned.pinnedTimelines.add(pinnedTimelineConversations);
                try {
                    new Pinned(activity).updatePinned(pinned);
                } catch (DBException e) {
                    e.printStackTrace();
                }
            }
        }
        if (extraFeatures) {
            try {
                Pinned pinnedAll = new Pinned(activity).getAllPinned(currentAccount);
                if (pinnedAll == null) {
                    pinnedAll = new Pinned();
                    pinnedAll.user_id = currentUserID;
                    pinnedAll.instance = currentInstance;
                    pinnedAll.pinnedTimelines = new ArrayList<>();
                }
                boolean createDefaultBubbleAtTop = true;
                for (PinnedTimeline pinnedTimeline : pinnedAll.pinnedTimelines) {
                    if (pinnedTimeline.type == Timeline.TimeLineEnum.BUBBLE) {
                        createDefaultBubbleAtTop = false;
                        break;
                    }
                }
                if (createDefaultBubbleAtTop) {
                    PinnedTimeline pinnedTimelineBubble = new PinnedTimeline();
                    pinnedTimelineBubble.type = Timeline.TimeLineEnum.BUBBLE;
                    pinnedTimelineBubble.position = pinnedAll.pinnedTimelines != null ? pinnedAll.pinnedTimelines.size() : 0;
                    pinned.pinnedTimelines.add(pinnedTimelineBubble);
                    boolean exist = new Pinned(activity).pinnedExist(pinned);
                    if (exist) {
                        new Pinned(activity).updatePinned(pinned);
                    } else {
                        new Pinned(activity).insertPinned(pinned);
                    }
                }
            } catch (DBException e) {
                e.printStackTrace();
            }
        }

        sortPositionAsc(pinnedTimelines);
        //Check if changes occurred, if mastodonLists is null it does need, because it is the first call to draw pinned
        boolean needRedraw = mastodonLists == null;
        //Lists have been fetched from remote account
        if (mastodonLists != null) { //Currently, needRedraw is set to false
            List<PinnedTimeline> pinnedToRemove = new ArrayList<>();
            for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
                if (pinnedTimeline.type == Timeline.TimeLineEnum.LIST) {
                    boolean present = false;
                    for (MastodonList mastodonList : mastodonLists) {
                        if (mastodonList.id.compareTo(pinnedTimeline.mastodonList.id) == 0) {
                            present = true;
                            if (!mastodonList.title.equalsIgnoreCase(pinnedTimeline.mastodonList.title)) {
                                pinnedTimeline.mastodonList.title = mastodonList.title;
                                Pinned finalPinned1 = pinned;
                                new Thread(() -> {
                                    try {
                                        new Pinned(activity).updatePinned(finalPinned1);
                                    } catch (DBException e) {
                                        e.printStackTrace();
                                    }
                                }).start();
                            }
                            break;
                        }
                    }
                    //Needs to be removed
                    if (!present) {
                        pinnedToRemove.add(pinnedTimeline);
                        needRedraw = true; //Something changed, redraw must be done
                    }
                }
            }
            if (pinnedToRemove.size() > 0) {
                pinned.pinnedTimelines.removeAll(pinnedToRemove);
                try {
                    new Pinned(activity).updatePinned(pinned);
                } catch (DBException e) {
                    e.printStackTrace();
                }
            }

            for (MastodonList mastodonList : mastodonLists) {
                boolean present = false;
                try {
                    Pinned pinnedAll = new Pinned(activity).getAllPinned(currentAccount);
                    if (pinnedAll == null) {
                        pinnedAll = pinned;
                    }
                    for (PinnedTimeline pinnedTimeline : pinnedAll.pinnedTimelines) {
                        if (pinnedTimeline.mastodonList != null && mastodonList.id.compareTo(pinnedTimeline.mastodonList.id) == 0) {
                            present = true;
                            break;
                        }
                    }
                    //Needs to be added
                    if (!present) {
                        needRedraw = true; //Something changed, redraw must be done
                        PinnedTimeline pinnedTimeline = new PinnedTimeline();
                        pinnedTimeline.type = Timeline.TimeLineEnum.LIST;
                        pinnedTimeline.position = pinnedAll.pinnedTimelines.size();
                        pinnedTimeline.mastodonList = mastodonList;
                        pinnedAll.pinnedTimelines.add(pinnedTimeline);

                        try {
                            boolean exist = new Pinned(activity).pinnedExist(pinnedAll);
                            if (exist) {
                                new Pinned(activity).updatePinned(pinnedAll);
                            } else {
                                new Pinned(activity).insertPinned(pinnedAll);
                            }
                        } catch (DBException e) {
                            e.printStackTrace();
                        }
                    }
                } catch (DBException e) {
                    e.printStackTrace();
                }

            }
        }
        if (!needRedraw) { //if there were no changes with list, no need to update tabs
            return;
        }
        //Pinned tab position will start after BOTTOM_TIMELINE_COUNT (ie 5)
        activityMainBinding.tabLayout.removeAllTabs();
        int toRemove = FedilabPageAdapter.BOTTOM_TIMELINE_COUNT;
        if (!singleBar) {
            //Small hack to hide first tabs (they represent the item of the bottom menu)
            toRemove = itemToRemoveInBottomMenu(activity);
            for (int i = 0; i < (FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - toRemove); i++) {
                activityMainBinding.tabLayout.addTab(activityMainBinding.tabLayout.newTab(), false);
                ((ViewGroup) activityMainBinding.tabLayout.getChildAt(0)).getChildAt(i).setVisibility(View.GONE);
            }
        }
        List<PinnedTimeline> pinnedTimelineVisibleList = new ArrayList<>();
        List<PinnedTimeline> pinnedToRemove = new ArrayList<>();
        for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) {
            //Default timelines are not added if we are not in the single bar mode
            String ident = null;
            if (!singleBar) {
                switch (pinnedTimeline.type) {
                    case HOME:
                    case LOCAL:
                    case PUBLIC:
                    case NOTIFICATION:
                    case DIRECT:
                        pinnedToRemove.add(pinnedTimeline);
                        continue;
                }
            }
            if (pinnedTimeline.displayed) {
                TabLayout.Tab tab = activityMainBinding.tabLayout.newTab();
                String name = "";
                switch (pinnedTimeline.type) {
                    case LIST:
                        name = pinnedTimeline.mastodonList.title;
                        ident = "@l@" + pinnedTimeline.mastodonList.id;
                        break;
                    case TAG:
                        name = pinnedTimeline.tagTimeline.displayName != null && !pinnedTimeline.tagTimeline.displayName.isEmpty() ? pinnedTimeline.tagTimeline.displayName : pinnedTimeline.tagTimeline.name.replaceAll("#", "");
                        ident = "@T@" + name;
                        break;
                    case REMOTE:
                        name = pinnedTimeline.remoteInstance.host;
                        if (pinnedTimeline.remoteInstance.type == RemoteInstance.InstanceType.NITTER) {
                            String remoteInstance = sharedpreferences.getString(activity.getString(R.string.SET_NITTER_HOST), activity.getString(R.string.DEFAULT_NITTER_HOST)).toLowerCase();
                            //Custom name for Nitter instances
                            if (pinnedTimeline.remoteInstance.displayName != null && pinnedTimeline.remoteInstance.displayName.trim().length() > 0) {
                                name = pinnedTimeline.remoteInstance.displayName;
                            }
                            ident = "@R@" + remoteInstance;
                        } else {
                            ident = "@R@" + pinnedTimeline.remoteInstance.host;
                        }
                        break;
                }

                if (pinnedTimeline.type == Timeline.TimeLineEnum.LIST || pinnedTimeline.type == Timeline.TimeLineEnum.TAG || pinnedTimeline.type == Timeline.TimeLineEnum.REMOTE) {
                    TabCustomViewBinding tabCustomViewBinding = TabCustomViewBinding.inflate(activity.getLayoutInflater());
                    tabCustomViewBinding.title.setText(name);
                    switch (pinnedTimeline.type) {
                        case LIST:
                            tabCustomViewBinding.icon.setImageResource(R.drawable.ic_tl_list);
                            break;
                        case TAG:
                            tabCustomViewBinding.icon.setImageResource(R.drawable.ic_tl_tag);
                            break;
                        case REMOTE:
                            switch (pinnedTimeline.remoteInstance.type) {
                                case PIXELFED:
                                    tabCustomViewBinding.icon.setImageResource(R.drawable.pixelfed);
                                    break;
                                case MASTODON:
                                    tabCustomViewBinding.icon.setImageResource(R.drawable.mastodon_icon_item);
                                    break;

                                case MISSKEY:
                                    tabCustomViewBinding.icon.setImageResource(R.drawable.misskey);
                                    break;
                                case NITTER:
                                    tabCustomViewBinding.icon.setImageResource(R.drawable.nitter);
                                    break;
                                case GNU:
                                    tabCustomViewBinding.icon.setImageResource(R.drawable.ic_gnu_social);
                                    break;
                                case PEERTUBE:
                                    tabCustomViewBinding.icon.setImageResource(R.drawable.peertube_icon);
                                    break;
                            }
                            break;
                    }
                    tab.setCustomView(tabCustomViewBinding.getRoot());
                } else {
                    TabCustomDefaultViewBinding tabCustomDefaultViewBinding = TabCustomDefaultViewBinding.inflate(activity.getLayoutInflater());
                    switch (pinnedTimeline.type) {
                        case HOME:
                            tabCustomDefaultViewBinding.icon.setImageResource(R.drawable.ic_baseline_home_24);
                            break;
                        case LOCAL:
                            tabCustomDefaultViewBinding.icon.setImageResource(R.drawable.ic_baseline_supervisor_account_24);
                            break;
                        case PUBLIC:
                            tabCustomDefaultViewBinding.icon.setImageResource(R.drawable.ic_baseline_public_24);
                            break;
                        case NOTIFICATION:
                            tabCustomDefaultViewBinding.icon.setImageResource(R.drawable.ic_baseline_notifications_24);
                            break;
                        case DIRECT:
                            tabCustomDefaultViewBinding.icon.setImageResource(R.drawable.ic_baseline_mail_24);
                            break;
                        case BUBBLE:
                            tabCustomDefaultViewBinding.icon.setImageResource(R.drawable.ic_baseline_bubble_chart_24);
                            break;
                    }
                    tab.setCustomView(tabCustomDefaultViewBinding.getRoot());
                }
                //We be used to fetch position of tabs
                String slug = pinnedTimeline.type.getValue() + (ident != null ? "|" + ident : "");
                tab.setTag(slug);
                activityMainBinding.tabLayout.addTab(tab, false);
                pinnedTimelineVisibleList.add(pinnedTimeline);
            }
        }
        pinned.pinnedTimelines.removeAll(pinnedToRemove);

        Pinned finalPinned = pinned;
        int finalToRemove1 = toRemove;
        activityMainBinding.moreTimelines.setOnClickListener(v -> {
            PopupMenu popup = new PopupMenu(activity, v);
            try {
                @SuppressLint("PrivateApi")
                Method method = popup.getMenu().getClass().getDeclaredMethod("setOptionalIconsVisible", boolean.class);
                method.setAccessible(true);
                method.invoke(popup.getMenu(), true);
            } catch (Exception e) {
                e.printStackTrace();
            }
            int i = 0;
            int j = 0;
            for (PinnedTimeline pinnedTimeline : finalPinned.pinnedTimelines) {
                MenuItem item = null;
                switch (pinnedTimeline.type) {
                    case LIST:
                        item = popup.getMenu().add(0, 0, Menu.NONE, pinnedTimeline.mastodonList.title);
                        item.setIcon(R.drawable.ic_tl_list);
                        break;
                    case TAG:
                        String name = (pinnedTimeline.tagTimeline.displayName != null && pinnedTimeline.tagTimeline.displayName.length() > 0) ? pinnedTimeline.tagTimeline.displayName : pinnedTimeline.tagTimeline.name;
                        item = popup.getMenu().add(0, 0, Menu.NONE, name);
                        item.setIcon(R.drawable.ic_tl_tag);
                        break;
                    case REMOTE:
                        item = popup.getMenu().add(0, 0, Menu.NONE, pinnedTimeline.remoteInstance.host);
                        switch (pinnedTimeline.remoteInstance.type) {
                            case MASTODON:
                                item.setIcon(R.drawable.mastodon_icon_item);
                                break;
                            case PEERTUBE:
                                item.setIcon(R.drawable.peertube_icon);
                                break;
                            case GNU:
                                item.setIcon(R.drawable.ic_gnu_social);
                                break;
                            case MISSKEY:
                                item.setIcon(R.drawable.misskey);
                                break;
                            case PIXELFED:
                                item.setIcon(R.drawable.pixelfed);
                                break;
                            case NITTER:
                                item.setIcon(R.drawable.nitter);
                                if (pinnedTimeline.remoteInstance.displayName != null && pinnedTimeline.remoteInstance.displayName.trim().length() > 0) {
                                    item.setTitle(pinnedTimeline.remoteInstance.displayName);
                                } else {
                                    item.setTitle(pinnedTimeline.remoteInstance.host);
                                }
                                break;
                        }
                        break;
                }
                if (item != null) {
                    int finalI;
                    if (singleBar) {
                        finalI = i;
                    } else {
                        finalI = FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - finalToRemove1 + j;
                    }
                    item.setOnMenuItemClickListener(item1 -> {
                        if (finalI < activityMainBinding.tabLayout.getTabCount() && activityMainBinding.tabLayout.getTabAt(finalI) != null) {
                            TabLayout.Tab tab = activityMainBinding.tabLayout.getTabAt(finalI);
                            if (tab != null) {
                                tab.select();
                            }
                        }
                        return false;
                    });
                    j++;
                }
                i++;
            }
            popup.show();
        });


        LinearLayout tabStrip = (LinearLayout) activityMainBinding.tabLayout.getChildAt(0);
        int finalToRemove = toRemove;
        for (int i = 0; i < tabStrip.getChildCount(); i++) {
            // Set LongClick listener to each Tab
            int finalI = i;
            tabStrip.getChildAt(i).setOnLongClickListener(v -> {

                int position = finalI - (FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - finalToRemove);
                switch (pinnedTimelineVisibleList.get(position).type) {
                    case LIST:

                        break;
                    case TAG:
                        tagClick(activity, finalPinned, v, activityMainBinding, finalI, activityMainBinding.tabLayout.getTabAt(finalI).getTag().toString());
                        break;
                    case BUBBLE:
                        bubbleClick(activity, finalPinned, v, activityMainBinding, finalI, activityMainBinding.tabLayout.getTabAt(finalI).getTag().toString());
                        break;
                    case REMOTE:
                        if (pinnedTimelineVisibleList.get(position).remoteInstance.type != RemoteInstance.InstanceType.NITTER) {
                            instanceClick(activity, finalPinned, v, activityMainBinding, finalI, activityMainBinding.tabLayout.getTabAt(finalI).getTag().toString());
                        } else {
                            nitterClick(activity, finalPinned, v, activityMainBinding, finalI, activityMainBinding.tabLayout.getTabAt(finalI).getTag().toString());
                        }
                        break;
                    case HOME:
                    case LOCAL:
                    case PUBLIC:
                        defaultClick(activity, pinnedTimelineVisibleList.get(position).type, v, activityMainBinding, finalI);
                        break;
                }
                return true;
            });
        }

        activityMainBinding.viewPager.setAdapter(null);
        activityMainBinding.viewPager.clearOnPageChangeListeners();
        activityMainBinding.tabLayout.clearOnTabSelectedListeners();
        FedilabPageAdapter fedilabPageAdapter = new FedilabPageAdapter(activity, activity.getSupportFragmentManager(), pinned, bottomMenu);
        activityMainBinding.viewPager.setAdapter(fedilabPageAdapter);
        activityMainBinding.viewPager.setOffscreenPageLimit(tabStrip.getChildCount());
        activityMainBinding.viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(activityMainBinding.tabLayout));
        if (!singleBar) {
            activityMainBinding.viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                }

                @Override
                public void onPageSelected(int position) {
                    if (position < FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - finalToRemove) {
                        activityMainBinding.bottomNavView.getMenu().getItem(position).setChecked(true);
                    } else {
                        activityMainBinding.bottomNavView.getMenu().setGroupCheckable(0, true, false);
                        for (int i = 0; i < activityMainBinding.bottomNavView.getMenu().size(); i++) {
                            activityMainBinding.bottomNavView.getMenu().getItem(i).setChecked(false);
                        }
                        activityMainBinding.bottomNavView.getMenu().setGroupCheckable(0, true, true);
                    }
                }

                @Override
                public void onPageScrollStateChanged(int state) {
                }
            });
        }


        activityMainBinding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                activityMainBinding.viewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                if (!singleBar && tab.getTag() != null) {
                    if (tab.getTag().equals(Timeline.TimeLineEnum.HOME.getValue())) {
                        activityMainBinding.bottomNavView.removeBadge(R.id.nav_home);
                    } else if (tab.getTag().equals(Timeline.TimeLineEnum.LOCAL.getValue())) {
                        activityMainBinding.bottomNavView.removeBadge(R.id.nav_local);
                    } else if (tab.getTag().equals(Timeline.TimeLineEnum.PUBLIC.getValue())) {
                        activityMainBinding.bottomNavView.removeBadge(R.id.nav_public);
                    } else if (tab.getTag().equals(Timeline.TimeLineEnum.NOTIFICATION.getValue())) {
                        activityMainBinding.bottomNavView.removeBadge(R.id.nav_notifications);
                    } else if (tab.getTag().equals(Timeline.TimeLineEnum.CONVERSATION.getValue())) {
                        activityMainBinding.bottomNavView.removeBadge(R.id.nav_privates);
                    }

                }
                Fragment fragment = fedilabPageAdapter.getCurrentFragment();
                View view = tab.getCustomView();
                if (view != null) {
                    TextView counter = view.findViewById(R.id.tab_counter);
                    if (counter != null) {
                        counter.setVisibility(View.GONE);
                        counter.setText("0");
                    }
                }
                if (fragment instanceof FragmentMastodonTimeline) {
                    ((FragmentMastodonTimeline) fragment).scrollToTop();
                } else if (fragment instanceof FragmentMastodonConversation) {
                    ((FragmentMastodonConversation) fragment).scrollToTop();
                } else if (fragment instanceof FragmentNotificationContainer) {
                    ((FragmentNotificationContainer) fragment).scrollToTop();
                }
            }
        });

    }

    /**
     * Manage long clicks on default timelines
     *
     * @param activity - BaseMainActivity activity
     * @param view     - View
     * @param position - int position of the tab
     */
    public static void defaultClick(BaseMainActivity activity, Timeline.TimeLineEnum timeLineEnum, View view, ActivityMainBinding activityMainBinding, int position) {
        boolean showExtendedFilter = timeLineEnum == Timeline.TimeLineEnum.HOME;
        PopupMenu popup = new PopupMenu(activity, view);
        popup.getMenuInflater()
                .inflate(R.menu.option_filter_toots, popup.getMenu());
        Menu menu = popup.getMenu();
        final MenuItem itemShowBoosts = menu.findItem(R.id.action_show_boosts);
        final MenuItem itemShowReplies = menu.findItem(R.id.action_show_replies);
        final MenuItem itemShowDMs = menu.findItem(R.id.action_show_dms);
        final MenuItem itemFilter = menu.findItem(R.id.action_filter);
        if (!showExtendedFilter) {
            itemShowBoosts.setVisible(false);
            itemShowReplies.setVisible(false);
            itemShowDMs.setVisible(false);
        } else {
            itemShowBoosts.setVisible(true);
            itemShowReplies.setVisible(true);
            itemShowDMs.setVisible(true);
        }
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
        String show_filtered = null;
        if (timeLineEnum == Timeline.TimeLineEnum.HOME) {
            show_filtered = sharedpreferences.getString(activity.getString(R.string.SET_FILTER_REGEX_HOME) + currentUserID + currentInstance, null);
        } else if (timeLineEnum == Timeline.TimeLineEnum.LOCAL) {
            show_filtered = sharedpreferences.getString(activity.getString(R.string.SET_FILTER_REGEX_LOCAL) + currentUserID + currentInstance, null);
        } else if (timeLineEnum == Timeline.TimeLineEnum.PUBLIC) {
            show_filtered = sharedpreferences.getString(activity.getString(R.string.SET_FILTER_REGEX_PUBLIC) + currentUserID + currentInstance, null);
        }

        itemShowBoosts.setChecked(show_boosts);
        itemShowReplies.setChecked(show_replies);
        itemShowDMs.setChecked(show_dms);
        if (show_filtered != null && show_filtered.length() > 0) {
            itemFilter.setTitle(show_filtered);
        }
        popup.setOnDismissListener(menu1 -> {
            if (activityMainBinding.viewPager.getAdapter() != null && activityMainBinding.tabLayout.getSelectedTabPosition() != -1) {
                Fragment fragment = (Fragment) activityMainBinding.viewPager.getAdapter().instantiateItem(activityMainBinding.viewPager, activityMainBinding.tabLayout.getSelectedTabPosition());
                if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
                    FragmentMastodonTimeline fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
                    fragmentMastodonTimeline.refreshAllAdapters();
                }
            }
        });
        String finalShow_filtered = show_filtered;
        popup.setOnMenuItemClickListener(item -> {
            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
            item.setActionView(new View(activity));
            item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    return false;
                }

                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    return false;
                }
            });
            final SharedPreferences.Editor editor = sharedpreferences.edit();
            int itemId = item.getItemId();
            if (itemId == R.id.action_show_boosts) {
                show_boosts = !show_boosts;
                editor.putBoolean(activity.getString(R.string.SET_SHOW_BOOSTS) + currentUserID + currentInstance, show_boosts);
                itemShowBoosts.setChecked(show_boosts);
                editor.apply();
            } else if (itemId == R.id.action_show_replies) {
                show_replies = !show_replies;
                editor.putBoolean(activity.getString(R.string.SET_SHOW_REPLIES) + currentUserID + currentInstance, show_replies);
                itemShowReplies.setChecked(show_replies);
                editor.apply();
            } else if (itemId == R.id.action_show_dms) {
                show_dms = !show_dms;
                editor.putBoolean(activity.getString(R.string.SET_SHOW_DMS) + currentUserID + currentInstance, show_dms);
                itemShowDMs.setChecked(show_dms);
                editor.apply();
            } else if (itemId == R.id.action_filter) {
                AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
                LayoutInflater inflater = activity.getLayoutInflater();
                View dialogView = inflater.inflate(R.layout.popup_filter_regex, new LinearLayout(activity), false);
                dialogBuilder.setView(dialogView);
                final EditText editText = dialogView.findViewById(R.id.filter_regex);
                Toast alertRegex = Toasty.warning(activity, activity.getString(R.string.alert_regex), Toast.LENGTH_LONG);
                editText.addTextChangedListener(new TextWatcher() {
                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    }

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                        try {
                            Pattern.compile("(" + s.toString() + ")", Pattern.CASE_INSENSITIVE);
                        } catch (Exception e) {
                            if (!alertRegex.getView().isShown()) {
                                alertRegex.show();
                            }
                        }

                    }
                });
                if (finalShow_filtered != null) {
                    editText.setText(finalShow_filtered);
                    editText.setSelection(editText.getText().toString().length());
                }
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    itemFilter.setTitle(editText.getText().toString().trim());
                    if (position == 0) {
                        editor.putString(activity.getString(R.string.SET_FILTER_REGEX_HOME) + currentUserID + currentInstance, editText.getText().toString().trim());
                        BaseMainActivity.regex_home = editText.getText().toString().trim();
                    } else if (position == 1) {
                        editor.putString(activity.getString(R.string.SET_FILTER_REGEX_LOCAL) + currentUserID + currentInstance, editText.getText().toString().trim());
                        BaseMainActivity.regex_local = editText.getText().toString().trim();
                    } else if (position == 2) {
                        editor.putString(activity.getString(R.string.SET_FILTER_REGEX_PUBLIC) + currentUserID + currentInstance, editText.getText().toString().trim());
                        BaseMainActivity.regex_public = editText.getText().toString().trim();
                    }
                    editor.apply();
                });
                AlertDialog alertDialog = dialogBuilder.create();
                alertDialog.show();
                return true;
            }
            return false;
        });
        popup.show();
    }


    public static int itemToRemoveInBottomMenu(BaseMainActivity activity) {
        //Small hack to hide first tabs (they represent the item of the bottom menu)
        BottomMenu bottomMenuDb;
        int toRemove = 0;
        try {
            //If some menu items have been hidden we should not create tab for them
            bottomMenuDb = new BottomMenu(activity).getAllBottomMenu(currentAccount);
            if (bottomMenuDb != null) {
                List<BottomMenu.MenuItem> menuItemList = bottomMenuDb.bottom_menu;
                if (menuItemList != null) {
                    for (BottomMenu.MenuItem menuItem : menuItemList) {
                        if (!menuItem.visible) {
                            toRemove++;
                        }
                    }
                }
            }
        } catch (DBException e) {
            e.printStackTrace();
        }
        return toRemove;
    }


    /**
     * Manage long clicks on Tag timelines
     *
     * @param activity - BaseMainActivity activity
     * @param pinned   - {@link Pinned}
     * @param view     - View
     * @param position - int position of the tab
     */
    public static void tagClick(BaseMainActivity activity, Pinned pinned, View view, ActivityMainBinding activityMainBinding, int position, String slug) {
        int toRemove = itemToRemoveInBottomMenu(activity);
        PopupMenu popup = new PopupMenu(activity, view);
        int offSetPosition = position - (FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - toRemove);
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
        boolean singleBar = sharedpreferences.getBoolean(activity.getString(R.string.SET_USE_SINGLE_TOPBAR), false);
        if (singleBar) {
            offSetPosition = position;
        }
        String tag;
        TagTimeline tagTimeline = pinned.pinnedTimelines.get(offSetPosition).tagTimeline;
        if (tagTimeline == null)
            return;
        if (tagTimeline.displayName != null)
            tag = tagTimeline.displayName;
        else
            tag = tagTimeline.name;
        popup.getMenuInflater()
                .inflate(R.menu.option_tag_timeline, popup.getMenu());
        Menu menu = popup.getMenu();


        final MenuItem itemMediaOnly = menu.findItem(R.id.action_show_media_only);
        final MenuItem itemShowNSFW = menu.findItem(R.id.action_show_nsfw);


        final boolean[] changes = {false};
        final boolean[] mediaOnly = {false};
        final boolean[] showNSFW = {false};
        mediaOnly[0] = tagTimeline.isART;
        showNSFW[0] = tagTimeline.isNSFW;
        itemMediaOnly.setChecked(mediaOnly[0]);
        itemShowNSFW.setChecked(showNSFW[0]);
        popup.setOnDismissListener(menu1 -> {
            if (changes[0]) {
                if (activityMainBinding.viewPager.getAdapter() != null) {
                    try {
                        new StatusCache(activity).deleteForSlug(slug);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }

                    SharedPreferences.Editor editor = sharedpreferences.edit();
                    editor.putString(activity.getString(R.string.SET_INNER_MARKER) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance + slug, null);
                    editor.commit();
                    if (activityMainBinding.tabLayout.getSelectedTabPosition() != -1) {
                        Fragment fragmentMastodonTimeline = (Fragment) activityMainBinding.viewPager.getAdapter().instantiateItem(activityMainBinding.viewPager, activityMainBinding.tabLayout.getSelectedTabPosition());
                        if (fragmentMastodonTimeline instanceof FragmentMastodonTimeline && fragmentMastodonTimeline.isVisible()) {
                            FragmentTransaction fragTransaction = activity.getSupportFragmentManager().beginTransaction();
                            fragTransaction.detach(fragmentMastodonTimeline).commit();
                            Bundle bundle = new Bundle();
                            bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TAG);
                            bundle.putSerializable(Helper.ARG_TAG_TIMELINE, tagTimeline);
                            bundle.putSerializable(Helper.ARG_INITIALIZE_VIEW, false);
                            fragmentMastodonTimeline.setArguments(bundle);
                            FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
                            fragTransaction2.attach(fragmentMastodonTimeline);
                            fragTransaction2.commit();
                            ((FragmentMastodonTimeline) fragmentMastodonTimeline).recreate();
                        }
                    }
                }
            }
        });


        int finalOffSetPosition = offSetPosition;
        popup.setOnMenuItemClickListener(item -> {
            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
            item.setActionView(new View(activity));
            item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    return false;
                }

                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    return false;
                }
            });
            changes[0] = true;
            int itemId = item.getItemId();
            if (itemId == R.id.action_show_media_only) {
                mediaOnly[0] = !mediaOnly[0];
                tagTimeline.isART = mediaOnly[0];
                pinned.pinnedTimelines.get(finalOffSetPosition).tagTimeline = tagTimeline;
                itemMediaOnly.setChecked(mediaOnly[0]);
                try {
                    new Pinned(activity).updatePinned(pinned);
                } catch (DBException e) {
                    e.printStackTrace();
                }
            } else if (itemId == R.id.action_show_nsfw) {
                showNSFW[0] = !showNSFW[0];
                tagTimeline.isNSFW = showNSFW[0];
                pinned.pinnedTimelines.get(finalOffSetPosition).tagTimeline = tagTimeline;
                itemShowNSFW.setChecked(showNSFW[0]);
                try {
                    new Pinned(activity).updatePinned(pinned);
                } catch (DBException e) {
                    e.printStackTrace();
                }
            } else if (itemId == R.id.action_any) {
                AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
                LayoutInflater inflater = activity.getLayoutInflater();
                View dialogView = inflater.inflate(R.layout.tags_any, new LinearLayout(activity), false);
                dialogBuilder.setView(dialogView);
                final EditText editText = dialogView.findViewById(R.id.filter_any);
                if (tagTimeline.any != null) {
                    StringBuilder valuesTag = new StringBuilder();
                    for (String val : tagTimeline.any)
                        valuesTag.append(val).append(" ");
                    editText.setText(valuesTag.toString());
                    editText.setSelection(editText.getText().toString().length());
                }
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    String[] values = editText.getText().toString().trim().split("\\s+");
                    tagTimeline.any = new ArrayList<>(Arrays.asList(values));
                    pinned.pinnedTimelines.get(finalOffSetPosition).tagTimeline = tagTimeline;
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                });
                AlertDialog alertDialog = dialogBuilder.create();
                alertDialog.show();
            } else if (itemId == R.id.action_all) {
                AlertDialog.Builder dialogBuilder;
                LayoutInflater inflater;
                View dialogView;
                AlertDialog alertDialog;
                dialogBuilder = new MaterialAlertDialogBuilder(activity);
                inflater = activity.getLayoutInflater();
                dialogView = inflater.inflate(R.layout.tags_all, new LinearLayout(activity), false);
                dialogBuilder.setView(dialogView);
                final EditText editTextAll = dialogView.findViewById(R.id.filter_all);
                if (tagTimeline.all != null) {
                    StringBuilder valuesTag = new StringBuilder();
                    for (String val : tagTimeline.all)
                        valuesTag.append(val).append(" ");
                    editTextAll.setText(valuesTag.toString());
                    editTextAll.setSelection(editTextAll.getText().toString().length());
                }
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    String[] values = editTextAll.getText().toString().trim().split("\\s+");
                    tagTimeline.all = new ArrayList<>(Arrays.asList(values));
                    pinned.pinnedTimelines.get(finalOffSetPosition).tagTimeline = tagTimeline;
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                });
                alertDialog = dialogBuilder.create();
                alertDialog.show();
            } else if (itemId == R.id.action_none) {
                AlertDialog.Builder dialogBuilder;
                LayoutInflater inflater;
                View dialogView;
                AlertDialog alertDialog;
                dialogBuilder = new MaterialAlertDialogBuilder(activity);
                inflater = activity.getLayoutInflater();
                dialogView = inflater.inflate(R.layout.tags_all, new LinearLayout(activity), false);
                dialogBuilder.setView(dialogView);
                final EditText editTextNone = dialogView.findViewById(R.id.filter_all);
                if (tagTimeline.none != null) {
                    StringBuilder valuesTag = new StringBuilder();
                    for (String val : tagTimeline.none)
                        valuesTag.append(val).append(" ");
                    editTextNone.setText(valuesTag.toString());
                    editTextNone.setSelection(editTextNone.getText().toString().length());
                }
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    String[] values = editTextNone.getText().toString().trim().split("\\s+");
                    tagTimeline.none = new ArrayList<>(Arrays.asList(values));
                    pinned.pinnedTimelines.get(finalOffSetPosition).tagTimeline = tagTimeline;
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                });
                alertDialog = dialogBuilder.create();
                alertDialog.show();
            } else if (itemId == R.id.action_displayname) {
                AlertDialog.Builder dialogBuilder;
                LayoutInflater inflater;
                View dialogView;
                AlertDialog alertDialog;
                dialogBuilder = new MaterialAlertDialogBuilder(activity);
                inflater = activity.getLayoutInflater();
                dialogView = inflater.inflate(R.layout.tags_name, new LinearLayout(activity), false);
                dialogBuilder.setView(dialogView);
                final EditText editTextName = dialogView.findViewById(R.id.column_name);
                if (tagTimeline.displayName != null) {
                    editTextName.setText(tagTimeline.displayName);
                    editTextName.setSelection(editTextName.getText().toString().length());
                }
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    String values = editTextName.getText().toString();
                    if (values.trim().length() == 0)
                        values = tag;
                    tagTimeline.displayName = values;
                    View titleView = view.findViewById(R.id.title);
                    if (titleView instanceof AppCompatTextView) {
                        ((AppCompatTextView) titleView).setText(tagTimeline.displayName);
                    }
                    pinned.pinnedTimelines.get(finalOffSetPosition).tagTimeline = tagTimeline;
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                });
                alertDialog = dialogBuilder.create();
                alertDialog.show();
            }
            return false;
        });
        popup.show();
    }


    /**
     * Manage long clicks on Bubble timelines
     *
     * @param activity - BaseMainActivity activity
     * @param pinned   - {@link Pinned}
     * @param view     - View
     * @param position - int position of the tab
     */
    public static void bubbleClick(BaseMainActivity activity, Pinned pinned, View view, ActivityMainBinding activityMainBinding, int position, String slug) {
        int toRemove = itemToRemoveInBottomMenu(activity);
        PopupMenu popup = new PopupMenu(activity, view);
        int offSetPosition = position - (FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - toRemove);
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
        boolean singleBar = sharedpreferences.getBoolean(activity.getString(R.string.SET_USE_SINGLE_TOPBAR), false);
        if (singleBar) {
            offSetPosition = position;
        }

        if (pinned.pinnedTimelines.get(offSetPosition).bubbleTimeline == null) {
            pinned.pinnedTimelines.get(offSetPosition).bubbleTimeline = new BubbleTimeline();
        }
        BubbleTimeline bubbleTimeline = pinned.pinnedTimelines.get(offSetPosition).bubbleTimeline;

        popup.getMenuInflater()
                .inflate(R.menu.option_bubble_timeline, popup.getMenu());
        Menu menu = popup.getMenu();

        final MenuItem itemMediaOnly = menu.findItem(R.id.action_show_media_only);
        final MenuItem itemRemote = menu.findItem(R.id.action_remote);


        final boolean[] changes = {false};
        final boolean[] mediaOnly = {false};
        final boolean[] remote = {false};
        mediaOnly[0] = bubbleTimeline.only_media;
        remote[0] = bubbleTimeline.remote;
        itemMediaOnly.setChecked(mediaOnly[0]);
        itemRemote.setChecked(remote[0]);
        popup.setOnDismissListener(menu1 -> {
            if (changes[0]) {
                if (activityMainBinding.viewPager.getAdapter() != null) {
                    try {
                        new StatusCache(activity).deleteForSlug(slug);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }

                    SharedPreferences.Editor editor = sharedpreferences.edit();
                    editor.putString(activity.getString(R.string.SET_INNER_MARKER) + BaseMainActivity.currentUserID + BaseMainActivity.currentInstance + slug, null);
                    editor.commit();
                    if (activityMainBinding.tabLayout.getSelectedTabPosition() != -1) {
                        Fragment fragmentMastodonTimeline = (Fragment) activityMainBinding.viewPager.getAdapter().instantiateItem(activityMainBinding.viewPager, activityMainBinding.tabLayout.getSelectedTabPosition());
                        if (fragmentMastodonTimeline instanceof FragmentMastodonTimeline && fragmentMastodonTimeline.isVisible()) {
                            FragmentTransaction fragTransaction = activity.getSupportFragmentManager().beginTransaction();
                            fragTransaction.detach(fragmentMastodonTimeline).commit();
                            Bundle bundle = new Bundle();
                            bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.BUBBLE);
                            bundle.putSerializable(Helper.ARG_BUBBLE_TIMELINE, bubbleTimeline);
                            bundle.putSerializable(Helper.ARG_INITIALIZE_VIEW, false);
                            fragmentMastodonTimeline.setArguments(bundle);
                            FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
                            fragTransaction2.attach(fragmentMastodonTimeline);
                            fragTransaction2.commit();
                            ((FragmentMastodonTimeline) fragmentMastodonTimeline).recreate();
                        }
                    }
                }
            }
        });


        int finalOffSetPosition = offSetPosition;
        popup.setOnMenuItemClickListener(item -> {
            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
            item.setActionView(new View(activity));
            item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    return false;
                }

                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    return false;
                }
            });
            changes[0] = true;
            int itemId = item.getItemId();
            if (itemId == R.id.action_show_media_only) {
                mediaOnly[0] = !mediaOnly[0];
                bubbleTimeline.only_media = mediaOnly[0];
                pinned.pinnedTimelines.get(finalOffSetPosition).bubbleTimeline = bubbleTimeline;
                itemMediaOnly.setChecked(mediaOnly[0]);
                try {
                    new Pinned(activity).updatePinned(pinned);
                } catch (DBException e) {
                    e.printStackTrace();
                }
            } else if (itemId == R.id.action_remote) {
                remote[0] = !remote[0];
                bubbleTimeline.remote = remote[0];
                pinned.pinnedTimelines.get(finalOffSetPosition).bubbleTimeline = bubbleTimeline;
                itemRemote.setChecked(remote[0]);
                try {
                    new Pinned(activity).updatePinned(pinned);
                } catch (DBException e) {
                    e.printStackTrace();
                }
            } else if (itemId == R.id.action_exclude_visibility) {
                AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
                DialogBubbleExcludeVisibilityBinding dialogBinding = DialogBubbleExcludeVisibilityBinding.inflate(activity.getLayoutInflater());
                dialogBuilder.setView(dialogBinding.getRoot());
                dialogBuilder.setTitle(R.string.exclude_visibility);
                if (bubbleTimeline.exclude_visibilities == null) {
                    bubbleTimeline.exclude_visibilities = new ArrayList<>();
                }
                for (String value : bubbleTimeline.exclude_visibilities) {
                    if (value.equalsIgnoreCase("public")) {
                        dialogBinding.valuePublic.setChecked(true);
                    }
                    if (value.equalsIgnoreCase("local")) {
                        dialogBinding.valueLocal.setChecked(true);
                    }
                    if (value.equalsIgnoreCase("direct")) {
                        dialogBinding.valueDirect.setChecked(true);
                    }
                    if (value.equalsIgnoreCase("list")) {
                        dialogBinding.valueList.setChecked(true);
                    }
                    if (value.equalsIgnoreCase("private")) {
                        dialogBinding.valuePrivate.setChecked(true);
                    }
                    if (value.equalsIgnoreCase("unlisted")) {
                        dialogBinding.valueUnlisted.setChecked(true);
                    }
                }
                dialogBinding.valuePrivate.setOnCheckedChangeListener((compoundButton, checked) -> {
                    if (checked) {
                        if (!bubbleTimeline.exclude_visibilities.contains("private")) {
                            bubbleTimeline.exclude_visibilities.add("private");
                        }
                    } else {
                        bubbleTimeline.exclude_visibilities.remove("private");
                    }
                });
                dialogBinding.valueDirect.setOnCheckedChangeListener((compoundButton, checked) -> {
                    if (checked) {
                        if (!bubbleTimeline.exclude_visibilities.contains("direct")) {
                            bubbleTimeline.exclude_visibilities.add("direct");
                        }
                    } else {
                        bubbleTimeline.exclude_visibilities.remove("direct");
                    }
                });
                dialogBinding.valueList.setOnCheckedChangeListener((compoundButton, checked) -> {
                    if (checked) {
                        if (!bubbleTimeline.exclude_visibilities.contains("list")) {
                            bubbleTimeline.exclude_visibilities.add("list");
                        }
                    } else {
                        bubbleTimeline.exclude_visibilities.remove("list");
                    }
                });
                dialogBinding.valueLocal.setOnCheckedChangeListener((compoundButton, checked) -> {
                    if (checked) {
                        if (!bubbleTimeline.exclude_visibilities.contains("local")) {
                            bubbleTimeline.exclude_visibilities.add("local");
                        }
                    } else {
                        bubbleTimeline.exclude_visibilities.remove("local");
                    }
                });
                dialogBinding.valuePublic.setOnCheckedChangeListener((compoundButton, checked) -> {
                    if (checked) {
                        if (!bubbleTimeline.exclude_visibilities.contains("public")) {
                            bubbleTimeline.exclude_visibilities.add("public");
                        }
                    } else {
                        bubbleTimeline.exclude_visibilities.remove("public");
                    }
                });
                dialogBinding.valueUnlisted.setOnCheckedChangeListener((compoundButton, checked) -> {
                    if (checked) {
                        if (!bubbleTimeline.exclude_visibilities.contains("unlisted")) {
                            bubbleTimeline.exclude_visibilities.add("unlisted");
                        }
                    } else {
                        bubbleTimeline.exclude_visibilities.remove("unlisted");
                    }
                });
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    pinned.pinnedTimelines.get(finalOffSetPosition).bubbleTimeline = bubbleTimeline;
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                });
                AlertDialog alertDialog = dialogBuilder.create();
                alertDialog.show();
            } else if (itemId == R.id.action_reply_visibility) {
                AlertDialog.Builder dialogBuilder;
                AlertDialog alertDialog;
                dialogBuilder = new MaterialAlertDialogBuilder(activity);
                DialogBubbleReplyVisibilityBinding dialogBinding = DialogBubbleReplyVisibilityBinding.inflate(activity.getLayoutInflater());
                dialogBuilder.setView(dialogBinding.getRoot());
                dialogBuilder.setTitle(R.string.reply_visibility);
                int checkedId = R.id.all;
                if (bubbleTimeline.reply_visibility != null && bubbleTimeline.reply_visibility.equalsIgnoreCase("following")) {
                    checkedId = R.id.following;
                } else if (bubbleTimeline.reply_visibility != null && bubbleTimeline.reply_visibility.equalsIgnoreCase("self")) {
                    checkedId = R.id.self;
                }
                dialogBinding.replyVisibility.check(checkedId);
                dialogBinding.replyVisibility.setOnCheckedChangeListener((radioGroup, checkedElement) -> {
                    if (checkedElement == R.id.all) {
                        bubbleTimeline.reply_visibility = null;
                    } else if (checkedElement == R.id.following) {
                        bubbleTimeline.reply_visibility = "following";
                    } else if (checkedElement == R.id.self) {
                        bubbleTimeline.reply_visibility = "self";
                    }
                });
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    pinned.pinnedTimelines.get(finalOffSetPosition).bubbleTimeline = bubbleTimeline;
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                });
                alertDialog = dialogBuilder.create();
                alertDialog.show();
            }
            return false;
        });
        popup.show();
    }


    /**
     * Manage long clicks on followed instances
     *
     * @param activity - BaseMainActivity activity
     * @param pinned   - {@link Pinned}
     * @param view     - View
     * @param position - int position of the tab
     */
    public static void instanceClick(BaseMainActivity activity, Pinned pinned, View view, ActivityMainBinding activityMainBinding, int position, String slug) {

        PopupMenu popup = new PopupMenu(activity, view);
        int toRemove = itemToRemoveInBottomMenu(activity);
        int offSetPosition = position - (FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - toRemove);
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
        boolean singleBar = sharedpreferences.getBoolean(activity.getString(R.string.SET_USE_SINGLE_TOPBAR), false);
        if (singleBar) {
            offSetPosition = position;
        }
        RemoteInstance remoteInstance = pinned.pinnedTimelines.get(offSetPosition).remoteInstance;

        if (remoteInstance == null)
            return;
        final String[] currentFilter = {remoteInstance.filteredWith};
        final boolean[] changes = {false};
        String title;
        if (currentFilter[0] == null) {
            title = "✔ " + activity.getString(R.string.all);
        } else {
            title = activity.getString(R.string.all);
        }

        MenuItem itemAll = popup.getMenu().add(0, 0, Menu.NONE, title);

        int finalOffSetPosition = offSetPosition;
        itemAll.setOnMenuItemClickListener(item -> {
            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
            item.setActionView(new View(activity));
            item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    return false;
                }

                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    return false;
                }
            });
            changes[0] = true;
            FragmentMastodonTimeline fragmentMastodonTimeline = null;
            try {
                new StatusCache(activity).deleteForSlug(slug);
            } catch (DBException e) {
                e.printStackTrace();
            }
            if (activityMainBinding.viewPager.getAdapter() != null && activityMainBinding.tabLayout.getSelectedTabPosition() != -1) {
                Fragment fragment = (Fragment) activityMainBinding.viewPager.getAdapter().instantiateItem(activityMainBinding.viewPager, activityMainBinding.tabLayout.getSelectedTabPosition());
                if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
                    fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
                }
            }
            if (fragmentMastodonTimeline == null)
                return false;
            FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction();

            pinned.pinnedTimelines.get(finalOffSetPosition).remoteInstance.filteredWith = null;
            remoteInstance.filteredWith = null;
            currentFilter[0] = null;
            pinned.pinnedTimelines.get(finalOffSetPosition).remoteInstance = remoteInstance;
            try {
                new Pinned(activity).updatePinned(pinned);
            } catch (DBException e) {
                e.printStackTrace();
            }
            fragTransaction1.detach(fragmentMastodonTimeline).commit();
            Bundle bundle = new Bundle();
            bundle.putSerializable(Helper.ARG_REMOTE_INSTANCE, pinned.pinnedTimelines.get(finalOffSetPosition));
            bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE);
            bundle.putSerializable(Helper.ARG_INITIALIZE_VIEW, false);
            fragmentMastodonTimeline.setArguments(bundle);
            FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
            fragTransaction2.attach(fragmentMastodonTimeline);
            fragTransaction2.commit();
            fragmentMastodonTimeline.recreate();
            popup.getMenu().close();
            return false;
        });

        java.util.List<String> tags = remoteInstance.tags;
        if (tags != null && tags.size() > 0) {
            java.util.Collections.sort(tags);
            for (String tag : tags) {
                if (tag == null || tag.length() == 0)
                    continue;
                if (currentFilter[0] != null && currentFilter[0].equals(tag)) {
                    title = "✔ " + tag;
                } else {
                    title = tag;
                }
                MenuItem item = popup.getMenu().add(0, 0, Menu.NONE, title);
                int finalOffSetPosition1 = offSetPosition;
                item.setOnMenuItemClickListener(item1 -> {
                    FragmentMastodonTimeline fragmentMastodonTimeline = null;
                    if (activityMainBinding.viewPager.getAdapter() != null && activityMainBinding.tabLayout.getSelectedTabPosition() != -1) {
                        Fragment fragment = (Fragment) activityMainBinding.viewPager.getAdapter().instantiateItem(activityMainBinding.viewPager, activityMainBinding.tabLayout.getSelectedTabPosition());
                        if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
                            fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
                            fragmentMastodonTimeline.refreshAllAdapters();
                        }
                    }
                    try {
                        new StatusCache(activity).deleteForSlug(slug);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                    FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction();
                    if (fragmentMastodonTimeline == null)
                        return false;
                    pinned.pinnedTimelines.get(finalOffSetPosition1).remoteInstance.filteredWith = tag;
                    remoteInstance.filteredWith = tag;
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                    currentFilter[0] = remoteInstance.filteredWith;
                    fragTransaction1.detach(fragmentMastodonTimeline).commit();
                    Bundle bundle = new Bundle();
                    bundle.putSerializable(Helper.ARG_REMOTE_INSTANCE, pinned.pinnedTimelines.get(finalOffSetPosition1));
                    bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE);
                    bundle.putSerializable(Helper.ARG_INITIALIZE_VIEW, false);
                    fragmentMastodonTimeline.setArguments(bundle);
                    FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
                    fragTransaction2.attach(fragmentMastodonTimeline);
                    fragTransaction2.commit();
                    fragmentMastodonTimeline.recreate();
                    return false;
                });
            }
        }


        MenuItem itemadd = popup.getMenu().add(0, 0, Menu.NONE, activity.getString(R.string.add_tags));
        itemadd.setOnMenuItemClickListener(item -> {
            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
            item.setActionView(new View(activity));
            item.setOnActionExpandListener(new MenuItem.OnActionExpandListener() {
                @Override
                public boolean onMenuItemActionExpand(MenuItem item) {
                    return false;
                }

                @Override
                public boolean onMenuItemActionCollapse(MenuItem item) {
                    return false;
                }
            });
            changes[0] = true;
            AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
            LayoutInflater inflater = activity.getLayoutInflater();
            View dialogView = inflater.inflate(R.layout.tags_instance, new LinearLayout(activity), false);
            dialogBuilder.setView(dialogView);
            final EditText editText = dialogView.findViewById(R.id.filter_words);
            if (remoteInstance.tags != null) {
                StringBuilder valuesTag = new StringBuilder();
                for (String val : remoteInstance.tags)
                    valuesTag.append(val).append(" ");
                editText.setText(valuesTag.toString());
                editText.setSelection(editText.getText().toString().length());
            }
            dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                String[] values = editText.getText().toString().trim().split("\\s+");
                remoteInstance.tags = new ArrayList<>(Arrays.asList(values));
                try {
                    new Pinned(activity).updatePinned(pinned);
                } catch (DBException e) {
                    e.printStackTrace();
                }
                popup.getMenu().clear();
                popup.getMenu().close();
                instanceClick(activity, pinned, view, activityMainBinding, position, slug);
            });
            AlertDialog alertDialog = dialogBuilder.create();
            alertDialog.show();
            return false;
        });

        int finalOffSetPosition2 = offSetPosition;
        popup.setOnDismissListener(menu -> {
            if (changes[0]) {
                FragmentMastodonTimeline fragmentMastodonTimeline = null;
                try {
                    new StatusCache(activity).deleteForSlug(slug);
                } catch (DBException e) {
                    e.printStackTrace();
                }
                if (activityMainBinding.viewPager.getAdapter() != null && activityMainBinding.tabLayout.getSelectedTabPosition() != -1) {
                    Fragment fragment = (Fragment) activityMainBinding.viewPager.getAdapter().instantiateItem(activityMainBinding.viewPager, activityMainBinding.tabLayout.getSelectedTabPosition());
                    if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
                        fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
                        fragmentMastodonTimeline.refreshAllAdapters();
                    }
                }
                FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction();
                if (fragmentMastodonTimeline == null)
                    return;
                fragTransaction1.detach(fragmentMastodonTimeline).commit();
                Bundle bundle = new Bundle();
                bundle.putSerializable(Helper.ARG_REMOTE_INSTANCE, pinned.pinnedTimelines.get(finalOffSetPosition2));
                bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE);
                bundle.putSerializable(Helper.ARG_INITIALIZE_VIEW, false);
                fragmentMastodonTimeline.setArguments(bundle);
                FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
                fragTransaction2.attach(fragmentMastodonTimeline);
                fragTransaction2.commit();
                fragmentMastodonTimeline.recreate();
            }
        });

        popup.show();
    }

    /**
     * Manage long clicks on Nitter instances
     *
     * @param activity - BaseMainActivity activity
     * @param pinned   - {@link Pinned}
     * @param position - int position of the tab
     */
    public static void nitterClick(BaseMainActivity activity, Pinned pinned, View view, ActivityMainBinding activityMainBinding, int position, String slug) {

        int toRemove = itemToRemoveInBottomMenu(activity);
        int offSetPosition = position - (FedilabPageAdapter.BOTTOM_TIMELINE_COUNT - toRemove);
        SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(activity);
        boolean singleBar = sharedpreferences.getBoolean(activity.getString(R.string.SET_USE_SINGLE_TOPBAR), false);
        if (singleBar) {
            offSetPosition = position;
        }
        RemoteInstance remoteInstance = pinned.pinnedTimelines.get(offSetPosition).remoteInstance;
        if (remoteInstance == null)
            return;
        PopupMenu popup = new PopupMenu(activity, view);
        popup.getMenuInflater()
                .inflate(R.menu.option_nitter_timeline, popup.getMenu());
        int finalOffSetPosition = offSetPosition;
        popup.setOnMenuItemClickListener(item -> {
            int itemId = item.getItemId();
            if (itemId == R.id.action_displayname) {
                AlertDialog.Builder dialogBuilder;
                LayoutInflater inflater;
                View dialogView;
                AlertDialog alertDialog;
                dialogBuilder = new MaterialAlertDialogBuilder(activity);
                inflater = activity.getLayoutInflater();
                dialogView = inflater.inflate(R.layout.tags_name, new LinearLayout(activity), false);
                dialogBuilder.setView(dialogView);
                final EditText editTextName = dialogView.findViewById(R.id.column_name);
                if (remoteInstance.displayName != null) {
                    editTextName.setText(remoteInstance.displayName);
                    editTextName.setSelection(editTextName.getText().toString().length());
                }
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    String values = editTextName.getText().toString();
                    if (values.trim().length() == 0) {
                        values = remoteInstance.displayName;
                    }
                    remoteInstance.displayName = values;
                    View titleView = view.findViewById(R.id.title);
                    if (titleView instanceof AppCompatTextView) {
                        ((AppCompatTextView) titleView).setText(remoteInstance.displayName);
                    }
                    pinned.pinnedTimelines.get(finalOffSetPosition).remoteInstance = remoteInstance;
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                });
                alertDialog = dialogBuilder.create();
                alertDialog.show();
            } else if (itemId == R.id.action_nitter_manage_accounts) {
                String accounts = remoteInstance.host;
                AlertDialog.Builder dialogBuilder = new MaterialAlertDialogBuilder(activity);
                LayoutInflater inflater = activity.getLayoutInflater();
                View dialogView = inflater.inflate(R.layout.tags_any, new LinearLayout(activity), false);
                dialogBuilder.setView(dialogView);
                final EditText editText = dialogView.findViewById(R.id.filter_any);
                editText.setHint(R.string.list_of_twitter_accounts);
                if (accounts != null) {
                    editText.setText(accounts);
                    editText.setSelection(editText.getText().toString().length());
                }
                dialogBuilder.setPositiveButton(R.string.validate, (dialog, id) -> {
                    pinned.pinnedTimelines.get(finalOffSetPosition).remoteInstance.host = editText.getText().toString().trim();
                    try {
                        new Pinned(activity).updatePinned(pinned);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                    FragmentMastodonTimeline fragmentMastodonTimeline = null;
                    try {
                        new StatusCache(activity).deleteForSlug(slug);
                    } catch (DBException e) {
                        e.printStackTrace();
                    }
                    if (activityMainBinding.viewPager.getAdapter() != null && activityMainBinding.tabLayout.getSelectedTabPosition() != -1) {
                        Fragment fragment = (Fragment) activityMainBinding.viewPager.getAdapter().instantiateItem(activityMainBinding.viewPager, activityMainBinding.tabLayout.getSelectedTabPosition());
                        if (fragment instanceof FragmentMastodonTimeline && fragment.isVisible()) {
                            fragmentMastodonTimeline = ((FragmentMastodonTimeline) fragment);
                            fragmentMastodonTimeline.refreshAllAdapters();
                        }
                    }
                    FragmentTransaction fragTransaction1 = activity.getSupportFragmentManager().beginTransaction();
                    if (fragmentMastodonTimeline == null)
                        return;
                    fragTransaction1.detach(fragmentMastodonTimeline).commit();
                    Bundle bundle = new Bundle();
                    bundle.putSerializable(Helper.ARG_REMOTE_INSTANCE, pinned.pinnedTimelines.get(finalOffSetPosition));
                    bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.REMOTE);
                    bundle.putSerializable(Helper.ARG_INITIALIZE_VIEW, false);
                    fragmentMastodonTimeline.setArguments(bundle);
                    FragmentTransaction fragTransaction2 = activity.getSupportFragmentManager().beginTransaction();
                    fragTransaction2.attach(fragmentMastodonTimeline);
                    fragTransaction2.commit();
                    fragmentMastodonTimeline.recreate();
                });
                AlertDialog alertDialog = dialogBuilder.create();
                alertDialog.show();
            }
            return true;
        });
        popup.show();
    }


}