/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.weex.ui.module;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.text.TextUtils;
import android.view.Gravity;
import android.widget.EditText;
import android.widget.Toast;
import com.alibaba.fastjson.JSONObject;
import org.apache.weex.annotation.JSMethod;
import org.apache.weex.bridge.JSCallback;
import org.apache.weex.utils.WXLogUtils;
import java.util.HashMap;
import java.util.Map;
import org.apache.weex.WXSDKEngine.DestroyableModule;


/**
 * WXModalUIModule module provide toast、alert、confirm、prompt to display the message.
 * for example(weex JS):
 * this.$call('modal','toast',{'message':'test toast','duration': 2.0});
 */
public class WXModalUIModule extends DestroyableModule {

  public static final String OK = "OK";
  public static final String CANCEL = "Cancel";
  public static final String RESULT = "result";
  public static final String DATA = "data";
  public static final String MESSAGE = "message";
  public static final String DURATION = "duration";
  public static final String OK_TITLE = "okTitle";
  public static final String CANCEL_TITLE = "cancelTitle";
  public static final String DEFAULT = "default";
  private Toast toast;
  private Dialog activeDialog;

  @SuppressLint("ShowToast")
  @JSMethod(uiThread = true)
  public void toast(JSONObject jsObj) {
    if(mWXSDKInstance.getContext() == null){
      return;
    }
    String message = "";
    int duration = Toast.LENGTH_SHORT;
    if (jsObj != null) {
      try {
        message = jsObj.getString(MESSAGE);
        if(jsObj.containsKey(DURATION)) {
          duration = jsObj.getInteger(DURATION);
        }
      } catch (Exception e) {
        WXLogUtils.e("[WXModalUIModule] alert param parse error ", e);
      }
    }
    if (TextUtils.isEmpty(message)) {
      WXLogUtils.e("[WXModalUIModule] toast param parse is null ");
      return;
    }

    if (duration > 3) {
      duration = Toast.LENGTH_LONG;
    } else {
      duration = Toast.LENGTH_SHORT;
    }
    if (toast == null) {
      toast = Toast.makeText(mWXSDKInstance.getContext(), message, duration);
    } else {
      toast.setDuration(duration);
      toast.setText(message);
    }
    toast.setGravity(Gravity.CENTER, 0, 0);
    toast.show();
  }

  @JSMethod(uiThread = true)
  public void alert(JSONObject jsObj, final JSCallback callback) {

    if (mWXSDKInstance.getContext() instanceof Activity) {

      String message = "";
      String okTitle = OK;
      if (jsObj != null) {
        try {
          message = jsObj.getString(MESSAGE);
          okTitle = jsObj.getString(OK_TITLE);
        } catch (Exception e) {
          WXLogUtils.e("[WXModalUIModule] alert param parse error ", e);
        }
      }
      if (TextUtils.isEmpty(message)) {
        message = "";
      }
      AlertDialog.Builder builder = new AlertDialog.Builder(mWXSDKInstance.getContext());
      builder.setMessage(message);

      final String okTitle_f = TextUtils.isEmpty(okTitle) ? OK : okTitle;
      builder.setPositiveButton(okTitle_f, new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          if (callback != null) {
            callback.invoke(okTitle_f);
          }
        }
      });
      AlertDialog alertDialog = builder.create();
      alertDialog.setCanceledOnTouchOutside(false);
      alertDialog.show();
      tracking(alertDialog);
    } else {
      WXLogUtils.e("[WXModalUIModule] when call alert mWXSDKInstance.getContext() must instanceof Activity");
    }
  }

  @JSMethod(uiThread = true)
  public void confirm(JSONObject jsObj, final JSCallback callback) {

    if (mWXSDKInstance.getContext() instanceof Activity) {
      String message = "";
      String okTitle = OK;
      String cancelTitle = CANCEL;

      if (jsObj != null) {
        try {
          message = jsObj.getString(MESSAGE);
          okTitle = jsObj.getString(OK_TITLE);
          cancelTitle = jsObj.getString(CANCEL_TITLE);
        } catch (Exception e) {
          WXLogUtils.e("[WXModalUIModule] confirm param parse error ", e);
        }
      }
      if (TextUtils.isEmpty(message)) {
        message = "";
      }
      AlertDialog.Builder builder = new AlertDialog.Builder(mWXSDKInstance.getContext());
      builder.setMessage(message);

      final String okTitleFinal = TextUtils.isEmpty(okTitle) ? OK : okTitle;
      final String cancelTitleFinal = TextUtils.isEmpty(cancelTitle) ? CANCEL : cancelTitle;

      builder.setPositiveButton(okTitleFinal, new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          if (callback != null) {
            callback.invoke(okTitleFinal);
          }
        }
      });
      builder.setNegativeButton(cancelTitleFinal, new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          if (callback != null) {
            callback.invoke(cancelTitleFinal);
          }
        }
      });
      AlertDialog alertDialog = builder.create();
      alertDialog.setCanceledOnTouchOutside(false);
      alertDialog.show();
      tracking(alertDialog);
    } else {
      WXLogUtils.e("[WXModalUIModule] when call confirm mWXSDKInstance.getContext() must instanceof Activity");
    }
  }

  @JSMethod(uiThread = true)
  public void prompt(JSONObject jsObj, final JSCallback callback) {
    if (mWXSDKInstance.getContext() instanceof Activity) {
      String message = "";
      String defaultValue = "";
      String okTitle = OK;
      String cancelTitle = CANCEL;

      if (jsObj != null) {
        try {
          message = jsObj.getString(MESSAGE);
          okTitle = jsObj.getString(OK_TITLE);
          cancelTitle = jsObj.getString(CANCEL_TITLE);
          defaultValue = jsObj.getString(DEFAULT);
        } catch (Exception e) {
          WXLogUtils.e("[WXModalUIModule] confirm param parse error ", e);
        }
      }

      if (TextUtils.isEmpty(message)) {
        message = "";
      }
      AlertDialog.Builder builder = new AlertDialog.Builder(mWXSDKInstance.getContext());
      builder.setMessage(message);

      final EditText editText = new EditText(mWXSDKInstance.getContext());
      editText.setText(defaultValue);
      builder.setView(editText);
      final String okTitleFinal = TextUtils.isEmpty(okTitle) ? OK : okTitle;
      final String cancelTitleFinal = TextUtils.isEmpty(cancelTitle) ? CANCEL : cancelTitle;
      builder.setPositiveButton(okTitleFinal, new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          if (callback != null) {
            Map<String, Object> result = new HashMap<String, Object>();
            result.put(RESULT, okTitleFinal);
            result.put(DATA, editText.getText().toString());
            callback.invoke(result);
          }
        }
      }).setNegativeButton(cancelTitleFinal, new OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
          if (callback != null) {
            Map<String, Object> result = new HashMap<String, Object>();
            result.put(RESULT, cancelTitleFinal);
            result.put(DATA, editText.getText().toString());
            callback.invoke(result);
          }

        }
      });
      AlertDialog alertDialog = builder.create();
      alertDialog.setCanceledOnTouchOutside(false);
      alertDialog.show();
      tracking(alertDialog);
    } else {
      WXLogUtils.e("when call prompt mWXSDKInstance.getContext() must instanceof Activity");
    }
  }

  private void tracking(Dialog dialog) {
    activeDialog = dialog;
    dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
      @Override
      public void onDismiss(DialogInterface dialog) {
        activeDialog = null;
      }
    });
  }

  @Override
  public void destroy() {
    if (activeDialog != null && activeDialog.isShowing()) {
      activeDialog.dismiss();
    }
  }
}
