package zapsolutions.zap.transactionHistory.transactionDetails;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.github.lightningnetwork.lnd.lnrpc.Transaction;
import com.google.android.material.bottomsheet.BottomSheetDialogFragment;
import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;

import zapsolutions.zap.R;
import zapsolutions.zap.util.BlockExplorer;
import zapsolutions.zap.util.ClipBoardUtil;
import zapsolutions.zap.util.MonetaryUtil;
import zapsolutions.zap.util.TimeFormatUtil;
import zapsolutions.zap.util.Wallet;
import zapsolutions.zap.util.ZapLog;

public class OnChainTransactionDetailBSDFragment extends BottomSheetDialogFragment {

    public static final String TAG = OnChainTransactionDetailBSDFragment.class.getName();
    public static final String ARGS_TRANSACTION = "TRANSACTION";

    private Transaction mTransaction;
    private TextView mTransactionDescription;
    private TextView mChannelLabel;
    private TextView mChannel;
    private TextView mEventLabel;
    private TextView mEvent;
    private TextView mAmountLabel;
    private TextView mAmount;
    private TextView mFeeLabel;
    private TextView mFee;
    private TextView mDateLabel;
    private TextView mDate;
    private TextView mTransactionIDLabel;
    private TextView mTransactionID;
    private ImageView mTransactionIDCopyButton;
    private TextView mAddressLabel;
    private TextView mAddress;
    private ImageView mAddressCopyButton;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.bsd_on_chain_transaction_detail, container);

        mTransactionDescription = view.findViewById(R.id.transactionDescription);

        mChannelLabel = view.findViewById(R.id.channelLabel);
        mChannel = view.findViewById(R.id.channel);
        mEventLabel = view.findViewById(R.id.eventLabel);
        mEvent = view.findViewById(R.id.event);
        mAmountLabel = view.findViewById(R.id.amountLabel);
        mAmount = view.findViewById(R.id.amount);
        mFeeLabel = view.findViewById(R.id.feeLabel);
        mFee = view.findViewById(R.id.fee);
        mDateLabel = view.findViewById(R.id.dateLabel);
        mDate = view.findViewById(R.id.date);
        mTransactionIDLabel = view.findViewById(R.id.transactionIDLabel);
        mTransactionID = view.findViewById(R.id.transactionID);
        mTransactionIDCopyButton = view.findViewById(R.id.txIDCopyIcon);
        mAddressLabel = view.findViewById(R.id.addressLabel);
        mAddress = view.findViewById(R.id.address);
        mAddressCopyButton = view.findViewById(R.id.addressCopyIcon);

        ImageButton closeButton = view.findViewById(R.id.closeButton);
        closeButton.setOnClickListener(view1 -> dismiss());

        if (getArguments() != null) {
            ByteString transactionString = (ByteString) getArguments().getSerializable(ARGS_TRANSACTION);

            try {
                bindOnChainTransaction(transactionString);

            } catch (InvalidProtocolBufferException | NullPointerException exception) {
                ZapLog.debug(TAG, "Failed to parse transaction.");
                dismiss();
            }
        }

        return view;
    }


    private void bindOnChainTransaction(ByteString transactionString) throws InvalidProtocolBufferException {
        mTransaction = Transaction.parseFrom(transactionString);

        String channelLabel = getString(R.string.channel) + ":";
        mChannelLabel.setText(channelLabel);
        String eventLabel = getString(R.string.event) + ":";
        mEventLabel.setText(eventLabel);
        String amountLabel = getString(R.string.amount) + ":";
        mAmountLabel.setText(amountLabel);
        String feeLabel = getString(R.string.fee) + ":";
        mFeeLabel.setText(feeLabel);
        String dateLabel = getString(R.string.date) + ":";
        mDateLabel.setText(dateLabel);
        String transactionIDLabel = getString(R.string.transactionID) + ":";
        mTransactionIDLabel.setText(transactionIDLabel);
        String addressLabel = getString(R.string.address) + ":";
        mAddressLabel.setText(addressLabel);

        mDate.setText(TimeFormatUtil.formatTimeAndDateLong(mTransaction.getTimeStamp(), getActivity()));

        mAddress.setText(mTransaction.getDestAddresses(0));
        mTransactionID.setText(mTransaction.getTxHash());

        mTransactionID.setOnClickListener(view -> new BlockExplorer().showTransaction(mTransaction.getTxHash(), getActivity()));
        mAddress.setOnClickListener(view -> new BlockExplorer().showAddress(mTransaction.getDestAddresses(0), getActivity()));
        mTransactionIDCopyButton.setOnClickListener(view -> ClipBoardUtil.copyToClipboard(getContext(), "TransactionID", mTransaction.getTxHash()));
        mAddressCopyButton.setOnClickListener(view -> ClipBoardUtil.copyToClipboard(getContext(), "Address", mTransaction.getDestAddresses(0)));

        // is internal?
        if (Wallet.getInstance().isTransactionInternal(mTransaction)) {
            bindInternal();
        } else {
            bindNormalTransaction();
        }
    }

    @Override
    public int getTheme() {
        return R.style.ZapBottomSheetDialogTheme;
    }

    private void bindInternal() {
        mTransactionDescription.setText(R.string.channel_event);
        Long amount = mTransaction.getAmount();

        mAddress.setVisibility(View.GONE);
        mAddressLabel.setVisibility(View.GONE);
        mAddressCopyButton.setVisibility(View.GONE);
        mAmount.setVisibility(View.GONE);
        mAmountLabel.setVisibility(View.GONE);

        if (mTransaction.getTotalFees() > 0) {
            mFee.setText(MonetaryUtil.getInstance().getPrimaryDisplayAmountAndUnit(mTransaction.getTotalFees()));
        } else {
            mFee.setVisibility(View.GONE);
            mFeeLabel.setVisibility(View.GONE);
        }

        String alias = Wallet.getInstance().getNodeAliasFromChannelTransaction(mTransaction, getActivity());
        mChannel.setText(alias);

        switch (amount.compareTo(0L)) {
            case 0:
                // amount = 0
                mEvent.setText(R.string.force_closed_channel);
                break;
            case 1:
                // amount > 0 (Channel closed)
                mEvent.setText(R.string.closed_channel);
                break;
            case -1:
                // amount < 0 (Channel opened)
                mEvent.setText(R.string.opened_channel);
                break;
        }
    }

    private void bindNormalTransaction() {
        mTransactionDescription.setText(R.string.transaction_detail);
        mChannel.setVisibility(View.GONE);
        mChannelLabel.setVisibility(View.GONE);
        mEvent.setVisibility(View.GONE);
        mEventLabel.setVisibility(View.GONE);
        mAmount.setText(MonetaryUtil.getInstance().getPrimaryDisplayAmountAndUnit(mTransaction.getAmount()).replace("-", "- "));

        Long amount = mTransaction.getAmount();

        switch (amount.compareTo(0L)) {
            case 0:
                // amount = 0 (should actually not happen)
                mFee.setText(MonetaryUtil.getInstance().getPrimaryDisplayAmountAndUnit(mTransaction.getTotalFees()));
                break;
            case 1:
                // amount > 0 (received on-chain)
                mFee.setVisibility(View.GONE);
                mFeeLabel.setVisibility(View.GONE);
                break;
            case -1:
                // amount < 0 (sent on-chain)
                mFee.setText(MonetaryUtil.getInstance().getPrimaryDisplayAmountAndUnit(mTransaction.getTotalFees()));
                break;
        }
    }
}