package com.braintree.customersupportbackoffice.widgets.order.voidorder;

import com.braintree.exceptions.BraintreeErrorException;
import com.braintree.facade.backoffice.BraintreeBackofficeVoidFacade;
import com.hybris.cockpitng.engine.WidgetInstanceManager;
import de.hybris.bootstrap.annotations.UnitTest;
import de.hybris.platform.core.model.c2l.CurrencyModel;
import de.hybris.platform.core.model.order.OrderModel;
import de.hybris.platform.payment.model.PaymentTransactionEntryModel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.Messagebox;

import java.math.BigDecimal;
import java.util.List;

import static com.braintree.customersupportbackoffice.constants.BraintreecustomersupportbackofficeConstants.BraintreeVoidAction.WIDGET_VOID_TRANSACTION_TITLE;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@UnitTest
@RunWith(MockitoJUnitRunner.class)
public class BraintreeVoidControllerTest {
    private static final String TEST_REQUEST_ID = "TEST_REQUEST_ID";
    private static final String CURRENCY_SYMBOL = "CURRENCY_SYMBOL";
    private static final String TRANSACTION_SUCCESSFULLY_VOIDED_MSG = "Transaction was successfully voided";
    private static final String WIDGET_VOID_TRANSACTION_TITLE_LABEL = "WIDGET_VOID_TRANSACTION_TITLE_LABEL";
    private static final String VOID_ERR_MSG = "Error during void process";
    private static final int CURRENCY_DIGITS = 2;
    private static final BigDecimal TRANSACTION_AMOUNT = new BigDecimal("5.556");
    @Mock
    private Combobox transactions;
    @Mock
    private BraintreeBackofficeVoidFacade braintreeBackofficeOrderFacade;
    @Mock
    private WidgetInstanceManager widgetInstanceManager;
    @Mock
    private OrderModel mockedOrder;
    @Mock
    private PaymentTransactionEntryModel paymentTransactionEntryModel;
    @Mock
    private CurrencyModel currencyModel;
    @Mock
    private Comboitem comboitem;
    @Spy
    @InjectMocks
    private BraintreeVoidController unit;

    @Test
    public void shouldInitVoidRequestForm() {
        when(braintreeBackofficeOrderFacade.getVoidableTransactions(any())).thenReturn(List.of(paymentTransactionEntryModel));
        doReturn(comboitem).when(unit).createComboItem(any());
        unit.initVoidRequestForm(mockedOrder);
        verify(unit).createComboItem(paymentTransactionEntryModel);
        verify(braintreeBackofficeOrderFacade).getVoidableTransactions(mockedOrder);
        assertEquals(mockedOrder, unit.getOrder());
    }

    @Test
    public void shouldSubmitted() throws Exception {
        when(transactions.getSelectedItem()).thenReturn(comboitem);
        when(comboitem.getValue()).thenReturn(paymentTransactionEntryModel);
        when(widgetInstanceManager.getLabel(WIDGET_VOID_TRANSACTION_TITLE)).thenReturn(WIDGET_VOID_TRANSACTION_TITLE_LABEL);
        doNothing().when(unit).showMsg(any(), any(), anyInt(), any());
        unit.submitted();
        verify(braintreeBackofficeOrderFacade).executeVoid(paymentTransactionEntryModel);
        verify(unit).showMsg(TRANSACTION_SUCCESSFULLY_VOIDED_MSG, WIDGET_VOID_TRANSACTION_TITLE_LABEL, Messagebox.OK, Messagebox.INFORMATION);
    }

    @Test
    public void shouldSubmittedWhenThrownBraintreeErrorException() throws Exception {
        when(transactions.getSelectedItem()).thenReturn(comboitem);
        when(comboitem.getValue()).thenReturn(paymentTransactionEntryModel);
        when(braintreeBackofficeOrderFacade.executeVoid(any())).thenThrow(new BraintreeErrorException(VOID_ERR_MSG));
        when(widgetInstanceManager.getLabel(WIDGET_VOID_TRANSACTION_TITLE)).thenReturn(WIDGET_VOID_TRANSACTION_TITLE_LABEL);
        doNothing().when(unit).showMsg(any(), any(), anyInt(), any());
        unit.submitted();
        verify(braintreeBackofficeOrderFacade).executeVoid(paymentTransactionEntryModel);
        verify(unit).showMsg(VOID_ERR_MSG, WIDGET_VOID_TRANSACTION_TITLE_LABEL, Messagebox.OK, Messagebox.ERROR);
    }

}
