package com.guarda.ethereum.views.adapters;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.Intent;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.TextView;

import com.guarda.ethereum.GuardaApp;
import com.guarda.ethereum.R;
import com.guarda.ethereum.managers.Callback;
import com.guarda.ethereum.managers.CallistoExplorerHelper;
import com.guarda.ethereum.managers.EthereumNetworkManager;
import com.guarda.ethereum.managers.TransactionsManager;
import com.guarda.ethereum.managers.WalletManager;
import com.guarda.ethereum.models.constants.Extras;
import com.guarda.ethereum.models.items.TransactionResponse;
import com.guarda.ethereum.models.items.TransactionsListResponse;
import com.guarda.ethereum.rest.ApiMethods;
import com.guarda.ethereum.utils.CalendarHelper;
import com.guarda.ethereum.utils.RepeatHandler;
import com.guarda.ethereum.views.activity.SendingCurrencyActivity;

import org.web3j.utils.Convert;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.inject.Inject;

import autodagger.AutoInjector;
import butterknife.BindView;
import butterknife.ButterKnife;

import static com.guarda.ethereum.models.constants.Common.ETH_SHOW_PATTERN;

@AutoInjector(GuardaApp.class)
public class TransHistoryAdapter extends RecyclerView.Adapter<TransHistoryAdapter.TransHistoryItemHolder> {

    public interface OnItemClickListener {
        void OnItemClick(int position);
    }

    public static final int MIN_CONFIRMATIONS = 3;
    private static final int REPEAT_INTERVAL_MILLISECONDS = 6000;
    @Inject
    WalletManager walletManager;

    @Inject
    TransactionsManager transactionsManager;

    @Inject
    Context context;

    @Inject
    EthereumNetworkManager networkManager;

    private ObjectAnimator loaderAnimation;
    private OnItemClickListener listener;

    private List<TransactionResponse> transList;
    private List<TransactionResponse> pendingList;
    private View view;
    private RepeatHandler repeatHandler;
    private Runnable onDataChangedCallback = null;
    private BigInteger blockHeight;

    public TransHistoryAdapter(BigInteger blockHeight) {
        GuardaApp.getAppComponent().inject(this);
        this.transList = transactionsManager.getTransactionsList();
        transactionsManager.clearDuplicateTransactions();
        this.pendingList = transactionsManager.getPendingTransactions();
        this.blockHeight = blockHeight;
    }

    public void setOnDataChanged(Runnable callback) {
        onDataChangedCallback = callback;
    }

    private void fireOnDataCallback() {
        if (onDataChangedCallback != null)
            onDataChangedCallback.run();
    }

    private void startUpdateTask() {
        repeatHandler = new RepeatHandler(new Runnable() {
            @Override
            public void run() {
                CallistoExplorerHelper.getTransactions(walletManager.getWalletFriendlyAddress(), new ApiMethods.RequestListener() {
                    @Override
                    public void onSuccess(Object response) {
                        TransactionsListResponse txsresp = (TransactionsListResponse) response;
                        List<TransactionResponse> transactionsList = transactionsManager.mapTxsFromArray(txsresp.getData());
                        transactionsManager.setTransactionsList(transactionsList);
                        transList = transactionsList;
                        if (pendingList.isEmpty()) {
                            notifyDataSetChanged();
                            fireOnDataCallback();
                            repeatHandler.interrupt();
                        }
                    }

                    @Override
                    public void onFailure(String msg) {
                    }
                });
            }
        }, REPEAT_INTERVAL_MILLISECONDS);
        repeatHandler.setFirstRunImmediately(true);
        repeatHandler.start();
    }

    private void starCheckTxTask(final String txHash) {
        if (repeatHandler != null) {
            repeatHandler.interrupt();
        }
        repeatHandler = new RepeatHandler(new Runnable() {
            @Override
            public void run() {
                CallistoExplorerHelper.getTransactions(walletManager.getWalletFriendlyAddress(), new ApiMethods.RequestListener() {
                    @Override
                    public void onSuccess(Object response) {
                        TransactionsListResponse txsresp = (TransactionsListResponse) response;
                        List<TransactionResponse> transactionsList = transactionsManager.mapTxsFromArray(txsresp.getData());
                        for (TransactionResponse trans : transactionsList) {
                            if (trans.getHash().equals(txHash)) {
                                if (Integer.parseInt(trans.getConfirmations()) >= MIN_CONFIRMATIONS) {
                                    transactionsManager.setTransactionsList(transactionsList);
                                    transList = transactionsList;
                                    repeatHandler.interrupt();
                                    notifyDataSetChanged();
                                    fireOnDataCallback();
                                }
                            }
                        }
                    }

                    @Override
                    public void onFailure(String msg) {
                    }
                });
            }
        }, REPEAT_INTERVAL_MILLISECONDS);
        repeatHandler.setFirstRunImmediately(true);
        repeatHandler.start();
    }

    public void setItemClickListener(OnItemClickListener listener) {
        this.listener = listener;
    }


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

    @Override
    public void onBindViewHolder(TransHistoryItemHolder holder, final int position) {
        final TransactionResponse item = getTxByPosition(position);

        holder.rootView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) {
                    listener.OnItemClick(position);
                }
            }
        });

        BigInteger sub = new BigInteger("4");
        if (blockHeight != null && item.getConfirmations() != null) {
            sub = blockHeight.subtract(new BigInteger(item.getConfirmations()));
        }

        if (item.getConfirmations() == null) {
//            enableLoader(holder);
            holder.tvTxStatus.setTextColor(view.getContext().getResources().getColor(R.color.txStatusGrey));
            holder.tvTxStatus.setText(R.string.tx_status_node);
            if (repeatHandler == null || repeatHandler.isInterrupted()) {
//                startUpdateTask();
            }
//        } else if (Integer.parseInt(item.getConfirmations()) < MIN_CONFIRMATIONS) {
        } else if (sub.compareTo(new BigInteger(String.valueOf(MIN_CONFIRMATIONS))) <= 0) {
//            starCheckTxTask(item.getHash());
//            enableLoader(holder);
            holder.tvTxStatus.setText(R.string.tx_status_wait);
        } else {
//            disableLoader(holder);
            holder.tvTxStatus.setVisibility(View.GONE);
            holder.viewIndicator.setBackground(view.getContext().getResources().getDrawable(R.drawable.transaction_indicator_green));
            holder.viewIndicator.setVisibility(View.VISIBLE);
        }

        String valueWithoutPrefix = item.getValue();
        if (valueWithoutPrefix != null) {
//        BigInteger value = new BigInteger(valueWithoutPrefix);
            BigDecimal decimal = new BigDecimal(valueWithoutPrefix);
//        BigDecimal formatted = Convert.fromWei(decimal, Convert.Unit.ETHER);
            DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
            symbols.setDecimalSeparator('.');
            DecimalFormat decimalFormat = new DecimalFormat(ETH_SHOW_PATTERN, symbols);
            decimalFormat.setRoundingMode(RoundingMode.DOWN);

            if (walletManager.getWalletFriendlyAddress() == null) {
                holder.tvTransactionSum.setText("...");
            } else {
                String valueStr = (isDebit(walletManager.getWalletFriendlyAddress(), item.getTo()) ? "+" : "-")
                        + " " + decimalFormat.format(decimal);
//                + " " + valueWithoutPrefix;
                holder.tvTransactionSum.setText(valueStr);
            }
        } else {
            holder.tvTransactionSum.setText("...");
        }

        long time;
        try {
            time = Long.parseLong(item.getTimeStamp()) * 1000;
            holder.tvDate.setText(CalendarHelper.parseDateToddMMyyyy(time));
        } catch (NumberFormatException nfe) {
            holder.tvDate.setText("...");
            nfe.printStackTrace();
            Log.d("psd", "parseLong(item.getTimeStamp()) - " + nfe.getMessage());
        }


    }

    private void retryTransaction(TransactionResponse item) {
        String transValue = "";
        BigInteger value = new BigInteger(item.getValue().substring(2));
        BigDecimal decimal = new BigDecimal(value);
        BigDecimal formatted = Convert.fromWei(decimal, Convert.Unit.ETHER);
        DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance();
        symbols.setDecimalSeparator('.');
        DecimalFormat decimalFormat = new DecimalFormat(ETH_SHOW_PATTERN, symbols);
        decimalFormat.setRoundingMode(RoundingMode.DOWN);
        transValue = decimalFormat.format(formatted);

        Intent intent = new Intent(context, SendingCurrencyActivity.class);
        intent.putExtra(Extras.WALLET_NUMBER, item.getTo());
        intent.putExtra(Extras.AMOUNT_TO_SEND, transValue);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    private TransactionResponse getTxByPosition(int position) {
        if (position + 1 <= pendingList.size()) {
            return pendingList.get(position);
        } else {
            return transList.get(position - pendingList.size());
        }
    }

//    private void enableRetryButton(TransHistoryItemHolder holder) {
//        holder.ivLoader.setVisibility(View.INVISIBLE);
//        holder.ivLoaderOuter.setVisibility(View.INVISIBLE);
//        holder.tvDate.setVisibility(View.INVISIBLE);
//        holder.ivRetry.setVisibility(View.VISIBLE);
//    }
//
//
//    private void enableLoader(TransHistoryItemHolder holder) {
//        holder.ivLoader.setVisibility(View.VISIBLE);
//        holder.ivLoaderOuter.setVisibility(View.VISIBLE);
//        holder.tvDate.setVisibility(View.INVISIBLE);
//        holder.ivRetry.setVisibility(View.INVISIBLE);
//        startClockwiseRotation(holder.ivLoader);
//        startCounterclockwiseRotation(holder.ivLoaderOuter);
//    }
//
//    private void disableLoader(TransHistoryItemHolder holder) {
//        holder.ivLoader.setVisibility(View.INVISIBLE);
//        holder.ivLoaderOuter.setVisibility(View.INVISIBLE);
//        holder.tvDate.setVisibility(View.VISIBLE);
//        holder.ivRetry.setVisibility(View.INVISIBLE);
//    }


    private void startClockwiseRotation(ImageView ivLoader) {
        loaderAnimation = ObjectAnimator.ofFloat(ivLoader, "rotation", 0.0f, 360f);
        loaderAnimation.setDuration(1500);
        loaderAnimation.setRepeatCount(ObjectAnimator.INFINITE);
        loaderAnimation.setInterpolator(new LinearInterpolator());
        loaderAnimation.start();
    }

    private void startCounterclockwiseRotation(ImageView ivLoader) {
        loaderAnimation = ObjectAnimator.ofFloat(ivLoader, "rotation", 360f, 0.0f);
        loaderAnimation.setDuration(1500);
        loaderAnimation.setRepeatCount(ObjectAnimator.INFINITE);
        loaderAnimation.setInterpolator(new LinearInterpolator());
        loaderAnimation.start();
    }

    private boolean isDebit(String ourAddress, String toAddress) {
        return ourAddress.equalsIgnoreCase(toAddress);
    }

    @Override
    public int getItemCount() {
        return transList.size() + pendingList.size();
    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        if (repeatHandler != null) {
            repeatHandler.interrupt();
        }
    }

    class TransHistoryItemHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.main_view)
        View rootView;
        @BindView(R.id.indicator)
        View viewIndicator;
        @BindView(R.id.tv_transaction_date)
        TextView tvDate;
        @BindView(R.id.tv_transaction_sum)
        TextView tvTransactionSum;
        @BindView(R.id.tv_tx_status)
        TextView tvTxStatus;
//        @BindView(R.id.iv_loader)
//        ImageView ivLoader;
//        @BindView(R.id.ic_outer_loader)
//        ImageView ivLoaderOuter;
//        @BindView(R.id.iv_retry)
//        ImageView ivRetry;


        TransHistoryItemHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}