package com.tsmobile.app

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.net.Uri
import android.net.wifi.WifiManager
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.core.app.NotificationCompat
import androidx.core.app.ServiceCompat
import androidx.lifecycle.LifecycleService

/**
 * 前台服务：保活 TeamSpeak 连接。
 *
 * 三层保活策略：
 *   1. 前台服务通知 → 防止 Android 杀死进程
 *   2. WakeLock (PARTIAL) → 防止 CPU 休眠导致 UDP socket 无法收发包
 *   3. WiFi Lock → 防止 WiFi 进入低功耗模式断连
 *
 * 连接成功时启动，断开/被踢时停止。
 */
class ConnectionService : LifecycleService() {

    companion object {
        private const val TAG = "ConnectionService"
        private const val CHANNEL_ID = "connection_channel"
        private const val NOTIFICATION_ID = 1
        const val EXTRA_SERVER_NAME = "server_name"

        /** WakeLock tag */
        private const val WAKELOCK_TAG = "tsmobile:connection"

        /**
         * 启动前台服务。
         */
        fun start(context: Context, serverName: String) {
            android.util.Log.i(TAG, "Starting connection service for $serverName")
            requestBatteryExemptionIfNeeded(context)
            val intent = Intent(context, ConnectionService::class.java).apply {
                putExtra(EXTRA_SERVER_NAME, serverName)
            }
            context.startService(intent)
        }

        /**
         * 停止前台服务。
         */
        fun stop(context: Context) {
            android.util.Log.i(TAG, "Stopping connection service")
            context.stopService(Intent(context, ConnectionService::class.java))
        }

        /**
         * 检查电池优化豁免状态，若未豁免则引导用户设置。
         * 仅在首次调用时弹窗（系统设置页面），用户设置后不再提示。
         */
        fun requestBatteryExemptionIfNeeded(context: Context) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return

            val pm = context.getSystemService(POWER_SERVICE) as PowerManager
            if (pm.isIgnoringBatteryOptimizations(context.packageName)) {
                android.util.Log.d(TAG, "Already exempt from battery optimization")
                return
            }

            android.util.Log.i(TAG, "Requesting battery optimization exemption")
            try {
                val intent = Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
                    data = Uri.parse("package:${context.packageName}")
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                }
                context.startActivity(intent)
            } catch (e: Exception) {
                android.util.Log.w(TAG, "Failed to open battery optimization settings", e)
            }
        }
    }

    private var wakeLock: PowerManager.WakeLock? = null
    private var wifiLock: WifiManager.WifiLock? = null

    override fun onCreate() {
        super.onCreate()
        acquireWakeLock()
        acquireWifiLock()
        ensureChannel()
        android.util.Log.i(TAG, "Service created, locks acquired")
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        super.onStartCommand(intent, flags, startId)

        val serverName = intent?.getStringExtra(EXTRA_SERVER_NAME) ?: ""

        // 启动前台服务
        val serviceType = if (Build.VERSION.SDK_INT >= 34) {
            ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
        } else {
            0
        }
        ServiceCompat.startForeground(this, NOTIFICATION_ID, buildNotification(serverName), serviceType)

        android.util.Log.i(TAG, "Foreground service started for $serverName")
        return Service.START_NOT_STICKY
    }

    override fun onDestroy() {
        releaseLocks()
        super.onDestroy()
        android.util.Log.i(TAG, "Connection service destroyed, locks released")
    }

    // ── WakeLock ───────────────────────────────────────────────

    @Suppress("DEPRECATION")
    private fun acquireWakeLock() {
        val pm = getSystemService(POWER_SERVICE) as PowerManager
        wakeLock = pm.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            WAKELOCK_TAG,
        ).apply {
            acquire()
        }
        android.util.Log.i(TAG, "WakeLock acquired (PARTIAL)")
    }

    private fun releaseLocks() {
        wakeLock?.let {
            if (it.isHeld) {
                it.release()
                android.util.Log.i(TAG, "WakeLock released")
            }
        }
        wakeLock = null

        wifiLock?.let {
            if (it.isHeld) {
                it.release()
                android.util.Log.i(TAG, "WiFi lock released")
            }
        }
        wifiLock = null
    }

    // ── WiFi Lock ──────────────────────────────────────────────

    private fun acquireWifiLock() {
        val wm = applicationContext.getSystemService(WIFI_SERVICE) as? WifiManager ?: return
        wifiLock = wm.createWifiLock(
            WifiManager.WIFI_MODE_FULL_HIGH_PERF,
            "tsmobile:wifi",
        ).apply {
            acquire()
        }
        android.util.Log.i(TAG, "WiFi lock acquired")
    }

    // ── 通知频道 ───────────────────────────────────────────────

    private fun ensureChannel() {
        val nm = getSystemService(NotificationManager::class.java) ?: return
        if (nm.getNotificationChannel(CHANNEL_ID) != null) return

        val channel = NotificationChannel(
            CHANNEL_ID,
            "服务器连接",
            NotificationManager.IMPORTANCE_LOW,
        ).apply {
            description = "保持与 TeamSpeak 服务器的连接"
            setShowBadge(false)
        }
        nm.createNotificationChannel(channel)
    }

    private fun buildNotification(serverName: String): Notification {
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            Intent(this, MainActivity::class.java).apply {
                flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
            },
            PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT,
        )

        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setSmallIcon(android.R.drawable.ic_dialog_info)
            .setContentTitle("已连接到 TeamSpeak")
            .setContentText(serverName)
            .setPriority(NotificationCompat.PRIORITY_LOW)
            .setOngoing(true)
            .setShowWhen(false)
            .setContentIntent(pendingIntent)
            .build()
    }
}
