package com.mobify.astro.dialogs;


import android.app.Activity;
import android.app.AlertDialog;
import android.app.DialogFragment;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.test.runner.AndroidJUnit4;
import android.view.View;
import android.widget.EditText;

import com.mobify.astro.AstroActivity;
import com.mobify.astro.messaging.AddressableObject;
import com.mobify.astro.messaging.MessageSender;
import com.mobify.astro.messaging.RpcResponse;
import com.mobify.astro.plugins.ListSelectPlugin;
import com.mobify.astro.plugins.PromptViewPlugin;

import org.json.JSONException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

@RunWith(AndroidJUnit4.class)

public class DialogManagerTest {

    DialogManager dialogManager;
    AstroActivity mockDialogActivity;

    private AddressableObject sender = new AddressableObject() {
        @Override
        public String getInstanceAddress() {
            return String.format("%s:%d", this.getClass().getName(), this.hashCode());
        }
    };

    @Before
    public void setUp() throws Exception {
        mockDialogActivity = mock(AstroActivity.class);
        MessageSender mockMessageSender = mock(MessageSender.class);
        dialogManager = spy(new DialogManager(mockDialogActivity, mockMessageSender));

    }

    @Test
    public void showModalCallsActivity() {
        final int dialogId = 7;
        final View testView = mock(View.class);
        final boolean animated = false;

        dialogManager.showModal(testView, dialogId, animated);
        verify(mockDialogActivity).displayViewFragment(eq(testView), eq(dialogId), eq(animated));
    }

    @Test
    public void removeModalCallsActivity() {
        final int dialogId = 7;

        dialogManager.removeModal(dialogId);
        verify(mockDialogActivity).hide(eq(dialogId));
    }

    @Test
    public void updateViewCallsActivity() {
        final int dialogId = 7;
        final View testView = mock(View.class);

        dialogManager.updateView(dialogId, testView);
        verify(mockDialogActivity).setViewForFragment(eq(dialogId), eq(testView));
    }

    @Test
    public void showPromptViewCreatesBuilderAndPassesToActivity() throws JSONException {
        String prompt = "Prompt";
        String submitButton = "Submit Label";
        String cancelButton = "Cancel Label";

        Bundle bundle = new Bundle();
        bundle.putString(PromptViewPlugin.KEY_PROMPT, prompt);
        bundle.putString(PromptViewPlugin.KEY_PLACEHOLDER, "Placeholder");
        bundle.putString(PromptViewPlugin.KEY_SUBMIT_BUTTON, submitButton);
        bundle.putString(PromptViewPlugin.KEY_CANCEL_BUTTON, cancelButton);
        RpcResponse testResponse = new RpcResponse("TestAddress", sender, "1");
        final int dialogId = 10;

        AlertDialog.Builder mockBuilder = mock(AlertDialog.Builder.class);
        doReturn(mockBuilder).when(dialogManager).createBuilder(any(Activity.class));

        doReturn(mock(EditText.class)).when(dialogManager).createPromptView(any(Activity.class), any(String.class));

        dialogManager.showPromptView(bundle, mockDialogActivity, testResponse, dialogId);

        verify(mockBuilder).setTitle(eq(prompt));
        verify(mockBuilder).setView(any(EditText.class));
        verify(mockBuilder).setNegativeButton(eq(cancelButton), any(DialogInterface.OnClickListener.class));
        verify(mockBuilder).setPositiveButton(eq(submitButton), any(DialogInterface.OnClickListener.class));

        verify(mockDialogActivity).displayDialogFragment(any(DialogFragment.class), eq(dialogId));
    }

    @Test
    public void showListSelectCreatesBuilderAndPassesToActivityNoCancel() throws JSONException {
        String title = "Title";
        String cancelButton = "Cancel Label";

        Bundle bundle = new Bundle();
        bundle.putString(ListSelectPlugin.KEY_TITLE, title);
        bundle.putBoolean(ListSelectPlugin.KEY_CANCELABLE, false);
        bundle.putString(ListSelectPlugin.KEY_CANCEL_BUTTON, cancelButton);
        RpcResponse testResponse = new RpcResponse("TestAddress", sender, "1");
        final int dialogId = 10;

        ArrayList<ListSelectPlugin.ListItem> list = new ArrayList<>();
        list.add(new ListSelectPlugin.ListItem("1", "Some Label"));

        AlertDialog.Builder mockBuilder = mock(AlertDialog.Builder.class);
        doReturn(mockBuilder).when(dialogManager).createBuilder(any(Activity.class));

        dialogManager.showListSelect(bundle, list, mockDialogActivity, testResponse, dialogId);

        verify(mockBuilder).setTitle(eq(title));
        verify(mockBuilder, never()).setNegativeButton(eq(cancelButton), any(DialogInterface.OnClickListener.class));
        verify(mockBuilder).setItems(any(CharSequence[].class), any(DialogInterface.OnClickListener.class));

        verify(mockDialogActivity).displayDialogFragment(any(DialogFragment.class), eq(dialogId));
    }

    @Test
    public void showListSelectCreatesBuilderAndPassesToActivityWithCancel() throws JSONException {
        String title = "Title";
        String cancelButton = "Cancel Label";

        Bundle bundle = new Bundle();
        bundle.putString(ListSelectPlugin.KEY_TITLE, title);
        bundle.putBoolean(ListSelectPlugin.KEY_CANCELABLE, true);
        bundle.putString(ListSelectPlugin.KEY_CANCEL_BUTTON, cancelButton);
        RpcResponse testResponse = new RpcResponse("TestAddress", sender, "1");
        final int dialogId = 10;

        ArrayList<ListSelectPlugin.ListItem> list = new ArrayList<>();
        list.add(new ListSelectPlugin.ListItem("1", "Some Label"));

        AlertDialog.Builder mockBuilder = mock(AlertDialog.Builder.class);
        doReturn(mockBuilder).when(dialogManager).createBuilder(any(Activity.class));

        dialogManager.showListSelect(bundle, list, mockDialogActivity, testResponse, dialogId);

        verify(mockBuilder).setTitle(eq(title));
        verify(mockBuilder).setNegativeButton(eq(cancelButton), any(DialogInterface.OnClickListener.class));
        verify(mockBuilder).setItems(any(CharSequence[].class), any(DialogInterface.OnClickListener.class));

        verify(mockDialogActivity).displayDialogFragment(any(DialogFragment.class), eq(dialogId));
    }

    @Test
    public void showAlertDialogCreatesBuilderAndPassesToActivityWithButtons() throws JSONException {
        String title = "Title";
        String message = "Message";
        String okButton = "Ok Label";
        String cancelButton = "Cancel Label";

        Bundle bundle = new Bundle();
        bundle.putString("dialog_title", title);
        bundle.putString("dialog_message", message);
        bundle.putString("dialog_okButton", okButton);
        bundle.putString("dialog_cancelButton", cancelButton);
        RpcResponse testResponse = new RpcResponse("TestAddress", sender, "1");
        final int dialogId = 10;

        AlertDialog.Builder mockBuilder = mock(AlertDialog.Builder.class);
        doReturn(mockBuilder).when(dialogManager).createBuilder(any(Activity.class));

        dialogManager.showAlertDialog(bundle, mockDialogActivity, testResponse, dialogId);

        verify(mockBuilder).setTitle(eq(title));
        verify(mockBuilder).setMessage(eq(message));
        verify(mockBuilder).setNegativeButton(eq(cancelButton), any(DialogInterface.OnClickListener.class));
        verify(mockBuilder).setPositiveButton(eq(okButton), any(DialogInterface.OnClickListener.class));

        verify(mockDialogActivity).displayDialogFragment(any(DialogFragment.class), eq(dialogId));
    }

    @Test
    public void showAlertDialogCreatesBuilderAndPassesToActivityNoButtons() throws JSONException {
        String title = "Title";
        String message = "Message";

        Bundle bundle = new Bundle();
        bundle.putString("dialog_title", title);
        bundle.putString("dialog_message", message);

        RpcResponse testResponse = new RpcResponse("TestAddress", sender, "1");
        final int dialogId = 10;

        AlertDialog.Builder mockBuilder = mock(AlertDialog.Builder.class);
        doReturn(mockBuilder).when(dialogManager).createBuilder(any(Activity.class));

        dialogManager.showAlertDialog(bundle, mockDialogActivity, testResponse, dialogId);

        verify(mockBuilder).setTitle(eq(title));
        verify(mockBuilder).setMessage(eq(message));
        verify(mockBuilder, never()).setNegativeButton(any(String.class), any(DialogInterface.OnClickListener.class));
        verify(mockBuilder, never()).setPositiveButton(any(String.class), any(DialogInterface.OnClickListener.class));

        verify(mockDialogActivity).displayDialogFragment(any(DialogFragment.class), eq(dialogId));
    }
}
