package com.mobify.astro.dialogs;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

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

import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;

public class DialogManager {

    public static final String TAG = DialogManager.class.getName();

    protected AstroActivity astroActivity;
    private MessageSender messageSender;

    private static final String KEY_TITLE = "dialog_title";
    private static final String KEY_OK_BUTTON = "dialog_okButton";
    private static final String KEY_CANCEL_BUTTON = "dialog_cancelButton";
    private static final String KEY_MESSAGE = "dialog_message";

    public DialogManager(AstroActivity astroActivity, @NonNull MessageSender messageSender) {
        this.astroActivity = astroActivity;
        this.messageSender = messageSender;
    }

    public void showModal(final View view, final int dialogId, final boolean animated) {
        astroActivity.displayViewFragment(view, dialogId, animated);
    }

    public void removeModal(int dialogId) {
        astroActivity.hide(dialogId);
    }

    public void updateView(int dialogId, View view) {
        astroActivity.setViewForFragment(dialogId, view);
    }

    public void showPromptView(final Bundle bundle, final Activity astroActivity, final RpcResponse response, final int dialogId) {
        AlertDialog.Builder builder = createBuilder(astroActivity);

        String title = bundle.getString(PromptViewPlugin.KEY_PROMPT, "");
        String placeholder = bundle.getString(PromptViewPlugin.KEY_PLACEHOLDER, "");
        String submitButtonLabel = bundle.getString(PromptViewPlugin.KEY_SUBMIT_BUTTON);
        String cancelButtonLabel = bundle.getString(PromptViewPlugin.KEY_CANCEL_BUTTON);

        builder.setTitle(title);

        final EditText textInput = createPromptView(astroActivity, placeholder);
        builder.setView(textInput);

        builder.setNegativeButton(cancelButtonLabel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                sendResult(response, buildPromptResponse(true, ""));
            }
        });

        builder.setPositiveButton(submitButtonLabel, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                String text = textInput.getText().toString();
                sendResult(response, buildPromptResponse(false, text));
            }
        });

        showAlertBuilder(builder, dialogId);
    }

    public void showListSelect(final Bundle bundle, final ArrayList<ListSelectPlugin.ListItem> list, final Activity astroActivity, final RpcResponse response, final int dialogId) {
        AlertDialog.Builder builder = createBuilder(astroActivity);

        String title = bundle.getString(ListSelectPlugin.KEY_TITLE, "Prompt");
        builder.setTitle(title);

        String cancelButton = bundle.getString(ListSelectPlugin.KEY_CANCEL_BUTTON);

        CharSequence labels[] = new CharSequence[list.size()];
        int index = 0;
        for (ListSelectPlugin.ListItem item : list) {
            labels[index++] = item.label;
        }

        builder.setItems(labels, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                sendResult(response, buildListSelectResponse(false, list.get(which).id));
            }
        });

        if (bundle.getBoolean(ListSelectPlugin.KEY_CANCELABLE)) {
            builder.setNegativeButton(cancelButton, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    sendResult(response, buildListSelectResponse(true, null));
                }
            });
        }

        showAlertBuilder(builder, dialogId);
    }

    public void showAlertDialog(final Bundle bundle, final Activity astroActivity, final RpcResponse response, final int dialogId) {
        AlertDialog.Builder builder = createBuilder(astroActivity);

        String title = bundle.getString(DialogManager.KEY_TITLE, "Alert!");
        String message = bundle.getString(DialogManager.KEY_MESSAGE, "");
        String okButton = bundle.getString(DialogManager.KEY_OK_BUTTON);
        String cancelButton = bundle.getString(DialogManager.KEY_CANCEL_BUTTON);

        builder.setTitle(title);
        builder.setMessage(message);

        if (okButton != null) {
            builder.setPositiveButton(okButton, createAlertListener(response, true, dialogId));
        }
        if (cancelButton != null) {
            builder.setNegativeButton(cancelButton, createAlertListener(response, false, dialogId));
        }

        showAlertBuilder(builder, dialogId);
    }

    protected AlertDialog.Builder createBuilder(final Activity activity)  {
        return new AlertDialog.Builder(astroActivity).setCancelable(false);
    }

    protected EditText createPromptView(final Activity activity, final String placeholder) {
        EditText textInput = new EditText(activity);
        textInput.setHint(placeholder);
        return textInput;
    }

    private void sendResult(RpcResponse response, Object result) {
        try {
            messageSender.sendRpcResponseWithResult(response, result);
        } catch (JSONException e) {
            Log.e(TAG, e.getMessage(), e);
        }
    }

    private DialogInterface.OnClickListener createAlertListener(final RpcResponse response, final boolean okPressed, final int dialogId) {
        return new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                sendResult(response, okPressed);
            }
        };
    }

    private JSONObject buildPromptResponse(boolean cancelled, String text) {
        JSONObject result = new JSONObject();
        try {
            result.put("cancelled", cancelled);
            result.put("text", text);
        } catch (JSONException e) {
            Log.e(TAG, "Error building prompt response object", e);
        }
        return result;
    }

    private JSONObject buildListSelectResponse(boolean cancelled, String id) {
        JSONObject res = new JSONObject();
        try {
            res.put("cancelled", cancelled);
            res.put("selected", id);
        } catch (JSONException e) {
            Log.e(TAG, "Error creating list select response object", e);
        }
        return res;
    }

    private void showAlertBuilder(@NonNull AlertDialog.Builder builder, int dialogId) {
        AlertFragment alertFragment = new AlertFragment();
        alertFragment.setAlertBuilder(builder);
        alertFragment.setCancelable(false);
        astroActivity.displayDialogFragment(alertFragment, dialogId);
    }
}
