package com.ariacockpit

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import android.telephony.PhoneStateListener
import android.telephony.TelephonyCallback
import android.telephony.TelephonyManager
import android.util.Log
import androidx.core.content.ContextCompat
import com.facebook.react.bridge.Arguments
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.modules.core.DeviceEventManagerModule
import java.util.concurrent.Executors

/**
 * Lauscht auf Anruf-Statusaenderungen — wenn das Telefon klingelt oder ein
 * Anruf laeuft, sendet das Modul ein "PhoneCallStateChanged"-Event an JS.
 *
 * JS-Side stoppt dann die TTS-Wiedergabe damit ARIA nicht mitten ins Gespraech
 * weiterredet. Ohne READ_PHONE_STATE-Permission failt start() leise — der Rest
 * der App funktioniert wie bisher.
 *
 * State-Strings: "idle" | "ringing" | "offhook"
 */
class PhoneCallModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
    override fun getName() = "PhoneCall"

    companion object { private const val TAG = "PhoneCall" }

    private var telephonyManager: TelephonyManager? = null
    private var legacyListener: PhoneStateListener? = null
    private var modernCallback: Any? = null  // TelephonyCallback ab API 31
    private var lastState: Int = TelephonyManager.CALL_STATE_IDLE
    // Eigener Single-Thread-Executor statt mainExecutor — der wird bei
    // pausierter Activity verzoegert oder gar nicht abgearbeitet, der eigene
    // Thread laeuft unabhaengig solange der App-Prozess lebt (was er ja tut,
    // wir haben einen Foreground-Service der das garantiert).
    private val callbackExecutor = Executors.newSingleThreadExecutor()

    @ReactMethod
    fun start(promise: Promise) {
        try {
            val perm = ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.READ_PHONE_STATE)
            if (perm != PackageManager.PERMISSION_GRANTED) {
                Log.w(TAG, "READ_PHONE_STATE Permission fehlt — Anruf-Erkennung inaktiv")
                promise.resolve(false)
                return
            }
            val tm = reactApplicationContext.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager
            if (tm == null) {
                Log.w(TAG, "TelephonyManager nicht verfuegbar")
                promise.resolve(false)
                return
            }
            telephonyManager = tm

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                val cb = object : TelephonyCallback(), TelephonyCallback.CallStateListener {
                    override fun onCallStateChanged(state: Int) {
                        handleStateChange(state)
                    }
                }
                tm.registerTelephonyCallback(callbackExecutor, cb)
                modernCallback = cb
            } else {
                @Suppress("DEPRECATION")
                val l = object : PhoneStateListener() {
                    override fun onCallStateChanged(state: Int, phoneNumber: String?) {
                        handleStateChange(state)
                    }
                }
                @Suppress("DEPRECATION")
                tm.listen(l, PhoneStateListener.LISTEN_CALL_STATE)
                legacyListener = l
            }
            Log.i(TAG, "PhoneCall-Listener aktiv")
            promise.resolve(true)
        } catch (e: Exception) {
            Log.e(TAG, "start fehlgeschlagen", e)
            promise.reject("START_FAILED", e.message ?: "Unbekannter Fehler", e)
        }
    }

    @ReactMethod
    fun stop(promise: Promise) {
        try {
            val tm = telephonyManager
            if (tm != null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                    (modernCallback as? TelephonyCallback)?.let { tm.unregisterTelephonyCallback(it) }
                    modernCallback = null
                } else {
                    @Suppress("DEPRECATION")
                    legacyListener?.let { tm.listen(it, PhoneStateListener.LISTEN_NONE) }
                    legacyListener = null
                }
            }
            telephonyManager = null
            lastState = TelephonyManager.CALL_STATE_IDLE
            promise.resolve(true)
        } catch (e: Exception) {
            promise.reject("STOP_FAILED", e.message ?: "")
        }
    }

    private fun handleStateChange(state: Int) {
        if (state == lastState) return
        lastState = state
        val name = when (state) {
            TelephonyManager.CALL_STATE_RINGING -> "ringing"
            TelephonyManager.CALL_STATE_OFFHOOK -> "offhook"
            TelephonyManager.CALL_STATE_IDLE -> "idle"
            else -> return
        }
        Log.i(TAG, "Telefon-State: $name")
        val params = Arguments.createMap().apply { putString("state", name) }
        try {
            reactApplicationContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
                .emit("PhoneCallStateChanged", params)
        } catch (e: Exception) {
            Log.w(TAG, "Event-emit fehlgeschlagen: ${e.message}")
        }
    }

    @ReactMethod fun addListener(eventName: String) {}
    @ReactMethod fun removeListeners(count: Int) {}
}
