package com.a2i.forwarder.core

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.telephony.TelephonyManager
import androidx.core.content.ContextCompat
import com.a2i.forwarder.A2iApp
import com.a2i.forwarder.model.BarkMessage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.util.UUID

/**
 * 通过轮询 TelephonyManager.getCallState() 监听来电状态。
 * MIUI 不会把系统电话通知分发给第三方监听器，TelephonyCallback 也不生效，
 * 所以这里用最原始但最可靠的方式：每 800ms 读一次 call state。
 *
 * getCallState() 只是读内存中的 int，不涉及硬件操作，耗电极低。
 */
class PhoneCallMonitor(private val context: Context) {
    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
    private val json = Json { encodeDefaults = true; ignoreUnknownKeys = true }

    private var lastState = TelephonyManager.CALL_STATE_IDLE
    private var ringing = false
    private var offhook = false
    private var running = false

    /** 上一次推送"来电"的时间，防止重复推送 */
    private var lastRingTime = 0L

    fun start() {
        if (running) return
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE)
            != PackageManager.PERMISSION_GRANTED
        ) return

        running = true
        lastState = TelephonyManager.CALL_STATE_IDLE
        ringing = false
        offhook = false

        scope.launch {
            val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as? TelephonyManager
            if (tm == null) { running = false; return@launch }

            while (isActive && running) {
                val state = tm.callState
                if (state != lastState) {
                    handleTransition(lastState, state)
                    lastState = state
                }
                delay(800)
            }
        }
    }

    fun stop() {
        running = false
    }

    private fun handleTransition(from: Int, to: Int) {
        val app = A2iApp.instance
        val settings = app.settings
        if (!settings.forwardingEnabled.value) return
        val server = settings.currentServer.value ?: return
        if (server.deviceKey.isBlank()) return

        when {
            // IDLE → RINGING：来电
            from == TelephonyManager.CALL_STATE_IDLE && to == TelephonyManager.CALL_STATE_RINGING -> {
                ringing = true
                offhook = false
                val now = System.currentTimeMillis()
                if (now - lastRingTime > 3000) {
                    lastRingTime = now
                    val msg = BarkMessage(
                        deviceKey = server.deviceKey,
                        title = "来电",
                        body = "有电话进来",
                        level = "timeSensitive",
                        group = "phone_call",
                        isArchive = "1",
                    )
                    pushToServer(server, msg, app, "来电")
                }
            }

            // RINGING → OFFHOOK：接听
            from == TelephonyManager.CALL_STATE_RINGING && to == TelephonyManager.CALL_STATE_OFFHOOK -> {
                offhook = true
            }

            // RINGING → IDLE：未接（响了但没接）
            from == TelephonyManager.CALL_STATE_RINGING && to == TelephonyManager.CALL_STATE_IDLE -> {
                if (!offhook && ringing) {
                    val msg = BarkMessage(
                        deviceKey = server.deviceKey,
                        title = "未接来电",
                        body = "未接来电",
                        level = "timeSensitive",
                        group = "phone_call",
                        isArchive = "1",
                    )
                    pushToServer(server, msg, app, "未接来电")
                }
                ringing = false
                offhook = false
            }

            // OFFHOOK → IDLE：正常挂断，不推送
            from == TelephonyManager.CALL_STATE_OFFHOOK && to == TelephonyManager.CALL_STATE_IDLE -> {
                ringing = false
                offhook = false
            }
        }
    }

    private fun pushToServer(
        server: com.a2i.forwarder.model.BarkServer,
        msg: BarkMessage,
        app: A2iApp,
        logBody: String,
    ) {
        scope.launch {
            val result = BarkClient(server).push(msg)
            val now = System.currentTimeMillis()
            if (result.isSuccess) {
                app.logStore.addLog(
                    ForwardLog(now, "phone_call", "电话", msg.title, logBody, "sent", "")
                )
            } else {
                val reason = result.exceptionOrNull()?.message ?: "错误"
                app.logStore.addLog(
                    ForwardLog(now, "phone_call", "电话", msg.title, logBody, "failed", reason)
                )
                app.logStore.addPending(
                    PendingPush(UUID.randomUUID().toString(), now, server.id, json.encodeToString(msg))
                )
            }
        }
    }
}
