package com.atmob.keyboard_android.util.bridge

import com.atmob.keyboard_android.constant.PluginConfig
import com.atmob.keyboard_android.enums.FlutterMethod
import com.atmob.keyboard_android.util.LaunchUtil
import com.atmob.keyboard_android.util.bridge.model.base.EmptyResp
import com.atmob.keyboard_android.util.bridge.model.req.SuperReplyReq
import com.atmob.keyboard_android.util.bridge.model.req.SuperSpeakReq
import com.atmob.keyboard_android.util.bridge.model.resp.CharacterListResp
import com.atmob.keyboard_android.util.bridge.model.resp.CurrentKeyboardIdResp
import com.atmob.keyboard_android.util.bridge.model.resp.KeyboardListResp
import com.atmob.keyboard_android.util.bridge.model.resp.PrologueListResp
import com.atmob.keyboard_android.util.bridge.model.resp.PrologueResp
import com.atmob.keyboard_android.util.bridge.model.resp.SuperReplyResp
import com.atmob.keyboard_android.util.bridge.model.resp.SuperSpeakResp
import com.atmob.keyboard_android.util.bridge.util.FlutterMethodCaller
import com.atmob.keyboard_android.util.bridge.util.NativeMethodRegistry
import io.flutter.embedding.engine.FlutterEngineCache

/**
 * 交互管理器，封装原生端和Flutter端的交互方法
 */
object FlutterBridgeManager : IBridgeApi {
    /**
     * 原生调Flutter
     */
    private val mFlutterMethodCaller = FlutterMethodCaller()

    /**
     * 暴露原生方法给Flutter调用
     */
    private val mNativeMethodRegistry = NativeMethodRegistry()

    init {
        val flutterEngine = FlutterEngineCache.getInstance().get(PluginConfig.FLUTTER_ENGINE_ID)
        if (flutterEngine == null) {
            throw IllegalArgumentException("FlutterEngine 未找到，MethodChannel 无法初始化")
        }
        mFlutterMethodCaller.init(flutterEngine)
        mNativeMethodRegistry.init(flutterEngine)
    }

    override fun isLogin(onSuccess: (Boolean) -> Unit, onFail: (String) -> Unit) {
        mFlutterMethodCaller.callMethod<Boolean>(
            FlutterMethod.IS_LOGIN.methodName,
            isReturnJson = false,
            modelClazz = Boolean::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun isMember(onSuccess: (Boolean) -> Unit, onFail: (String) -> Unit) {
        mFlutterMethodCaller.callMethod<Boolean>(
            FlutterMethod.IS_MEMBER.methodName,
            isReturnJson = false,
            modelClazz = Boolean::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun jump2CustomCharacterPage() {
        LaunchUtil.startLaunchActivity()
    }

    override fun jump2CharacterMarketPage() {
        LaunchUtil.startLaunchActivity()
    }

    override fun jump2VipStore() {
        LaunchUtil.startLaunchActivity()
    }

    override fun getKeyboardList(
        onSuccess: (resultObj: KeyboardListResp) -> Unit,
        onFail: (msg: String) -> Unit
    ) {
        mFlutterMethodCaller.callMethod<KeyboardListResp>(
            FlutterMethod.GET_KEYBOARD_LIST.methodName,
            modelClazz = KeyboardListResp::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun selectedKeyboard(
        keyboardId: String,
        onSuccess: (EmptyResp) -> Unit,
        onFail: (String) -> Unit
    ) {
        mFlutterMethodCaller.callMethod<EmptyResp>(
            FlutterMethod.SELECTED_KEY_BOARD.methodName,
            // 传递参数
            args = mapOf("keyboardId" to keyboardId),
            modelClazz = EmptyResp::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun getCurrentKeyboardId(
        onSuccess: (CurrentKeyboardIdResp) -> Unit,
        onFail: (String) -> Unit
    ) {
        mFlutterMethodCaller.callMethod<CurrentKeyboardIdResp>(
            FlutterMethod.GET_CURRENT_KEYBOARD_ID.methodName,
            modelClazz = CurrentKeyboardIdResp::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun getCharacterList(
        keyboardId: String,
        onSuccess: (CharacterListResp) -> Unit,
        onFail: (String) -> Unit
    ) {
        mFlutterMethodCaller.callMethod<CharacterListResp>(
            FlutterMethod.GET_CHARACTER_LIST.methodName,
            args = mapOf("keyboardId" to keyboardId),
            modelClazz = CharacterListResp::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun getPrologueList(
        onSuccess: (PrologueListResp) -> Unit,
        onFail: (String) -> Unit
    ) {
        mFlutterMethodCaller.callMethod<PrologueListResp>(
            FlutterMethod.GET_PROLOGUE_LIST.methodName,
            modelClazz = PrologueListResp::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun superReply(
        req: SuperReplyReq,
        onSuccess: (SuperReplyResp) -> Unit,
        onFail: (String) -> Unit
    ) {
        mFlutterMethodCaller.callMethod<SuperReplyResp>(
            FlutterMethod.SUPER_REPLY.methodName,
            args = mapOf(
                "keyboardId" to req.keyboardId,
                "characterId" to req.characterId,
                "content" to req.content,
            ),
            modelClazz = SuperReplyResp::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun superSpeak(
        req: SuperSpeakReq,
        onSuccess: (SuperSpeakResp) -> Unit,
        onFail: (String) -> Unit
    ) {
        mFlutterMethodCaller.callMethod<SuperSpeakResp>(
            FlutterMethod.SUPER_SPEAK.methodName,
            args = mapOf(
                "keyboardId" to req.keyboardId,
                "characterId" to req.characterId,
                "content" to req.content,
            ),
            modelClazz = SuperSpeakResp::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }

    override fun prologue(
        name: String,
        onSuccess: (PrologueResp) -> Unit,
        onFail: (String) -> Unit
    ) {
        mFlutterMethodCaller.callMethod<PrologueResp>(
            FlutterMethod.PROLOGUE.methodName,
            args = mapOf(
                "name" to name,
            ),
            modelClazz = PrologueResp::class.java,
            onSuccess = onSuccess,
            onFail = onFail
        )
    }
}