package com.a2i.forwarder.core

import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.telephony.SmsManager
import androidx.core.content.ContextCompat
import com.a2i.forwarder.A2iApp
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch

/**
 * 运营商短信余额查询：
 * - refresh()：向运营商服务号发免费查询短信（若运营商支持），回执由 NotificationProcessor 解析。
 * - 手动模式：递减 smsManualQuota 作为余额。
 * - parseReply()：从运营商回执短信正文中提取剩余短信条数，供 NotificationProcessor 调用。
 */
class CarrierBalanceQuery(private val context: Context) {
    private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)

    private val settings get() = A2iApp.instance.settings

    /** 触发一次余额查询（自动模式发短信，手动模式递减额度）。 */
    suspend fun refresh() {
        val carrier = currentCarrier()
        // 自动模式：发查询短信到运营商（免费，不走限频）
        if (carrier.serviceNumber != null && carrier.queryCmd != null) {
            sendSms(carrier.serviceNumber, carrier.queryCmd)
            return
        }
        // 手动模式：余额 = 手动额度，不额外查询
    }

    /** 转发成功后扣减余额（手动模式 / 自动解析失败时）。 */
    suspend fun decrementManual() {
        val q = settings.smsManualQuota.value
        if (q > 0) {
            val newQ = q - 1
            settings.setSmsManualQuota(newQ)
            settings.setSmsBalance(newQ)
            checkSuspend(newQ)
        }
    }

    /** 解析运营商回执，提取剩余短信条数。返回 null 表示解析失败。供 NotificationProcessor 调用。 */
    fun parseReply(text: String): Int? {
        // 匹配 "短信剩余XX条" / "短信：XX条" / "短信余量XX条" 等
        val patterns = listOf(
            Regex("""短信[^0-9]*(\d+)\s*条"""),
            Regex("""短信余[额度][^0-9]*(\d+)"""),
        )
        for (p in patterns) {
            val m = p.find(text) ?: continue
            val n = m.groupValues.getOrNull(1)?.toIntOrNull() ?: continue
            if (n in 0..9999) return n
        }
        return null
    }

    /** 回执解析成功后更新余额并检查是否需要挂起。 */
    suspend fun applyParsedBalance(count: Int) {
        settings.setSmsBalance(count)
        checkSuspend(count)
    }

    private suspend fun checkSuspend(balance: Int) {
        if (balance in 0..5 && !settings.smsSuspended.value) {
            settings.setSmsSuspended(true)
        }
    }

    fun currentCarrier(): CarrierDetector.Carrier {
        val stored = settings.smsCarrier.value
        return if (stored == "auto") CarrierDetector.detect(context)
        else CarrierDetector.Carrier.fromName(stored)
    }

    private fun sendSms(dest: String, body: String) {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS)
            != PackageManager.PERMISSION_GRANTED
        ) return
        scope.launch {
            runCatching {
                SmsManager.getDefault().sendTextMessage(dest, null, body, null, null)
            }
        }
    }
}
