package co.pixelbeard.theanfieldwrap.wallet;


import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.tonyodev.fetch2.Download;

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

import butterknife.BindView;
import butterknife.ButterKnife;
import co.pixelbeard.theanfieldwrap.R;
import co.pixelbeard.theanfieldwrap.data.Podcast;
import co.pixelbeard.theanfieldwrap.data.Transaction;
import co.pixelbeard.theanfieldwrap.data.Video;
import co.pixelbeard.theanfieldwrap.data.Wallet;
import co.pixelbeard.theanfieldwrap.data.source.DataRepository;
import co.pixelbeard.theanfieldwrap.data.source.local.LocalRepository;
import co.pixelbeard.theanfieldwrap.data.source.remote.RemoteRepository;
import co.pixelbeard.theanfieldwrap.home.HomeFragmentListener;
import co.pixelbeard.theanfieldwrap.networking.NetworkConstants;
import co.pixelbeard.theanfieldwrap.playerService.MediaPlayerInterface;
import co.pixelbeard.theanfieldwrap.playerService.PodcastStorageUtil;
import co.pixelbeard.theanfieldwrap.podcasts.OnPodcastSelectedListener;
import co.pixelbeard.theanfieldwrap.utils.AnimUtils;
import co.pixelbeard.theanfieldwrap.utils.BaseFragment;
import co.pixelbeard.theanfieldwrap.utils.ConnectionUtils;
import co.pixelbeard.theanfieldwrap.utils.FontUtils;
import co.pixelbeard.theanfieldwrap.utils.PrefKey;
import co.pixelbeard.theanfieldwrap.utils.PrefUtils;
import co.pixelbeard.theanfieldwrap.utils.ScreenUtils;
import co.pixelbeard.theanfieldwrap.utils.TawController;
import co.pixelbeard.theanfieldwrap.videos.OnVideoSelectedListener;
import io.realm.Realm;

public class WalletFragment extends BaseFragment implements WalletContract.View, OnPodcastSelectedListener, OnVideoSelectedListener {

    private static final String TAG = WalletFragment.class.getSimpleName();

    @BindView(R.id.ll_back)
    LinearLayout llBack;
    @BindView(R.id.txt_wallet_title)
    TextView txtWalletTitle;

    @BindView(R.id.txt_no_purchases)
    TextView txtNoPurchases;

    @BindView(R.id.txt_token_balance)
    TextView txtTokenBalance;

    @BindView(R.id.img_add_tokens)
    ImageView imgAddTokens;

    @BindView(R.id.rv_wallet)
    RecyclerView rvPurchases;

    @BindView(R.id.srl_wallet)
    SwipeRefreshLayout srlWallet;

    @BindView(R.id.ll_wallet_lazy_loader)
    ConstraintLayout llWalletLazyLoader;

    private int mCurrentPage = 1;
    private boolean isLastPage = false;

    private HomeFragmentListener mListener;
    private MediaPlayerInterface mediaPlayerInterface;
    private Context mContext;
    private WalletContract.Presenter mPresenter;

    private WalletAdapter adapter;
    private Wallet mWallet;

    public WalletFragment() {
        // Required empty public constructor
    }

    public static WalletFragment newInstance() {
        WalletFragment fragment = new WalletFragment();
        Bundle args = new Bundle();

        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        mListener = (HomeFragmentListener) context;
        mediaPlayerInterface = (MediaPlayerInterface) context;
        this.mContext = context;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {

        }

        new WalletPresenter(this, new DataRepository(new LocalRepository(Realm.getDefaultInstance()), new RemoteRepository()));
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_wallet, container, false);
        ButterKnife.bind(this, view);
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        setTextViewFont();
        setClickListeners();

        setRecyclerViewLayoutManager();

        new Handler().postDelayed(() -> setScrollViewListener(), 100);
        setSwipeRefreshListener();
    }

    @Override
    public void onResume() {
        super.onResume();
        TawController.setCurrentPage(TAG);
        if (isAdded()) {
            txtTokenBalance.setText(String.format(getString(R.string.tokens_argument), PrefUtils.getInstance().getIntPref(PrefKey.TOKEN_BALANCE)));
        }
//        if (adapter == null) {
        mCurrentPage = 1;
        mPresenter.getWallet(1);
//        } else {
//            setWalletAdapter(mWallet);
//        }
    }

    private void setTextViewFont() {
        txtWalletTitle.setTypeface(FontUtils.getInstance().getDinBlack());
        txtTokenBalance.setTypeface(FontUtils.getInstance().getDinAlternateBold());
        txtNoPurchases.setTypeface(FontUtils.getInstance().getDinAlternateBold());

    }

    private void setClickListeners() {
        llBack.setOnClickListener(v -> mListener.goBack());

        imgAddTokens.setOnClickListener(v -> mListener.setBuyTokensFragment());
    }


    private void setRecyclerViewLayoutManager() {
        rvPurchases.setLayoutManager(new LinearLayoutManager(mContext, RecyclerView.VERTICAL, false));
    }

    private void setScrollViewListener() {

        //TODO move to presenter

        rvPurchases.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
                    recyclerView.stopScroll();
                }
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                int visibleItemCount = recyclerView.getLayoutManager().getChildCount();
                int totalItemCount = recyclerView.getLayoutManager().getItemCount();
                int pastVisibleItems = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();

                if ((visibleItemCount + pastVisibleItems) >= totalItemCount && !srlWallet.isRefreshing() && !isLastPage) {
                    srlWallet.setRefreshing(true);
                    mPresenter.getWallet(mCurrentPage);
                }
            }
        });

    }

    private void setSwipeRefreshListener() {
        srlWallet.setColorSchemeColors(ContextCompat.getColor(mContext, R.color.red801812));

        srlWallet.setProgressViewOffset(false, 0, (int) ScreenUtils.dpToPx(80, mContext));
        srlWallet.setOnRefreshListener(() -> {
            mCurrentPage = 1;
            mPresenter.getWallet(mCurrentPage);
        });
    }

    @Override
    public void setPresenter(WalletContract.Presenter presenter) {
        if (presenter != null) {
            this.mPresenter = presenter;
        } else {
            throw new RuntimeException("Presenter is null");
        }
    }

    @Override
    public void goBack() {
        mListener.goBack();
    }

    @Override
    public void showLoader(String text) {
        if (!srlWallet.isRefreshing() && mCurrentPage == 1 && isAdded()) {
            llWalletLazyLoader.setVisibility(View.VISIBLE);
            llWalletLazyLoader.startAnimation(AnimUtils.getPulsateFade(mContext));
        }
    }

    @Override
    public void hideLoader() {
        if (isAdded()) {
            llWalletLazyLoader.clearAnimation();
            llWalletLazyLoader.setVisibility(View.GONE);

            if (srlWallet.isRefreshing()) {
                srlWallet.setRefreshing(false);
            }
        }
    }

    @Override
    public void onUnknownError(String error) {
        if (mListener != null && isAdded()) {
            mListener.showSingleButtonDialog(getString(R.string.error), error, null);
        }
    }

    @Override
    public void onTimeout() {
        if (mListener != null && isAdded()) {
            mListener.showSingleButtonDialog(getString(R.string.timeout_title), getString(R.string.timeout_body), null);
        }
    }

    @Override
    public void onNetworkError() {
        if (mListener != null && isAdded()) {
            mListener.showSingleButtonDialog(getString(R.string.network_error_title), getString(R.string.network_error_body), null);
        }
    }

    @Override
    public void onConnectionError() {
        if (mListener != null && isAdded()) {
            setSwipeRefreshRefreshing(false);
            hideLoader();
            mListener.showNoInternetHeader();
        }
    }

    @Override
    public void logoutUser() {
        mPresenter.clearUserData(mContext);

        if (mediaPlayerInterface.isPlaying()) {
            mediaPlayerInterface.stop();
        }
        PodcastStorageUtil.getInstance().clearStoredPodcast();
        mListener.startWalkThroughActivity();
    }

    @Override
    public boolean checkConnection() {
        return ConnectionUtils.userHasConnection(mContext);
    }

    @Override
    public void setWalletAdapter(Wallet wallet) {
        this.mWallet = wallet;


        if (mCurrentPage == 1) {
            isLastPage = false;
            adapter = null;
        }

        if (wallet.getTransactions().size() < NetworkConstants.PAGE_SIZE) {
            isLastPage = true;
        }


        if (isAdded() && !isDetached()) {
            txtTokenBalance.setText(String.format(getString(R.string.tokens_argument), wallet.getBalance()));
            if (adapter == null) {
                List<Transaction> transactions = wallet.getTransactions();
                List<Transaction> nonNullTransactions = new ArrayList<>();
                for (Transaction transaction :
                        transactions) {
                    if (transaction != null) {
                        nonNullTransactions.add(transaction);
                    }
                }

                adapter = new WalletAdapter(nonNullTransactions, this, this);
                rvPurchases.setAdapter(adapter);
                if (wallet.getTransactions().size() == 0) {
                    txtNoPurchases.setVisibility(View.VISIBLE);
                } else {
                    txtNoPurchases.setVisibility(View.GONE);
                }
            } else {
                adapter.add(wallet.getTransactions());
            }
            mCurrentPage++;
            if (srlWallet.isRefreshing()) {
                srlWallet.setRefreshing(false);
            }

        }
    }

    @Override
    public void showUi() {
        if (isAdded() && !isDetached()) {
            new Handler().postDelayed(() -> {
                if (isAdded() && !isDetached()) {
                    AnimUtils.startTranslateAlphaEntryAnimationSet(rvPurchases, ScreenUtils.dpToPx(50, mContext), 0, null);
                }
            }, 50);
        }
    }

    @Override
    public void setSwipeRefreshRefreshing(boolean refreshing) {
        if (isAdded() && srlWallet.isRefreshing() == !refreshing) {
            srlWallet.setRefreshing(refreshing);
        }
    }

    @Override
    public void showSingleButtonDialog(String error, String message) {
        if (isAdded() && mListener != null) {
            mListener.showSingleButtonDialog(error, message, null);
        }
    }

    @Override
    public void onPodcastSelected(Podcast podcast) {
        if (isAdded() && mListener != null) {
            mListener.setPodcastDetailsFrag(podcast);
        }
    }

    @Override
    public void onDownloadPodcastSelected(Podcast podcast, int adapterPosition) {
        //Not needed
    }

    @Override
    public boolean isDownloaded(long id) {
        //Not needed
        return false;
    }

    @Override
    public Download isDownloading(String podcastFullUrl) {
        //Not needed
        return null;
    }

    @Override
    public void savePodcast(Podcast podcast, Download download) {
        //Not needed
    }

    @Override
    public void onVideoSelected(Video video) {
        if (isAdded() && mListener != null) {
            mListener.setVideoDetailsFrag(video);
        }
    }
}
