package com.xcodetemplateproject

import android.widget.Toast


import androidx.annotation.NonNull
import androidx.annotation.Nullable
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.Callback
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.WritableMap
import com.facebook.react.uimanager.IllegalViewOperationException
import java.util.Map

class XcodeTemplateProjectModule(val reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {

    override fun getName(): String {
        return "XcodeTemplateProject"
    }

    // Example method
    // See https://facebook.github.io/react-native/docs/native-modules-android
    @ReactMethod
    fun multiply(a: Int, b: Int, promise: Promise) {

      promise.resolve(a * b)

    }

  /**
   * 直接调用原生方法
   */
  @ReactMethod
  fun nativeNormalMethod() {
    Toast.makeText(reactContext, "调用了Native方法", Toast.LENGTH_SHORT).show()
  }

  /**
   * 传递参数到Native原生方法
   * 可传递的JS与Android参数对应的类型
   * Boolean -> Bool
   * Integer -> Number
   * Double -> Number
   * Float -> Number
   * String -> String
   * Callback -> function
   * ReadableMap -> Object
   * ReadableArray -> Array
   *
   * @param numA
   * @param numB
   */
  @ReactMethod
  fun nativeMethodWithParams(numA: Int, numB: Int) {
    val result = numA + numB
    Toast.makeText(reactContext, "JS传递参数到Native方法结果为$result", Toast.LENGTH_SHORT).show()
  }

  /**
   * 原生方法包含回调函数。提供函数Callback来把返回值传回给 JavaScript
   *
   * @param numA
   * @param numB
   * @param successCallback
   * @param errorCallback
   */
  @ReactMethod
  fun nativeMethodWithCallback(numA: Int, numB: Int, successCallback: Callback, errorCallback: Callback) {
    try {
      val result = numA + numB
      successCallback.invoke(result)
    } catch (e: IllegalViewOperationException) {
      errorCallback.invoke(e)
    }
  }

  /**
   * 原生方法通过Promise返回给JS端， JS调用的时候实际只要传递numA，numB两个参数
   *
   * @param numA
   * @param numB
   * @param promise
   */
  @ReactMethod
  fun nativeMethodWithPromise(numA: Int, numB: Int, promise: Promise) {
    try {
      val result = numA + numB
      val map: WritableMap = Arguments.createMap()
      map.putInt("numA", numA)
      map.putInt("numB", numB)
      map.putInt("result", result)
      promise.resolve(map)
    } catch (e: IllegalViewOperationException) {
      promise.reject("Error", e)
    }
  }


  /**
   * 这里是为了方便调用，所以直接写了一个Bridge方法用来执行发送事件给JS
   * 本质上JSEvent.getInstance().sendMsg()是可以在Android所有地方调用，
   * 不需要在@ReactMedhod标记的方法中调用，也不需要在Module中调用
  //   */
  @ReactMethod
  fun nativeSendCustomEvent() {
    JSEvents.getInstance().sendMsg(reactContext)
  }

}
