package com.tsmobile.app

import android.app.Application
import android.app.NotificationChannel
import android.app.NotificationManager
import android.util.Log
import java.io.File

/**
 * Application 类。
 *
 * 对应 docs/implementation/12_主题与收尾.md 12.2 全局异常捕获。
 */
class App : Application() {

    companion object {
        private const val TAG = "App"
        private const val CONNECTION_CHANNEL_ID = "connection_channel"
        const val POKE_CHANNEL_ID = "poke_channel"
    }

    override fun onCreate() {
        super.onCreate()

        // 创建通知频道（前台服务需要）
        createConnectionNotificationChannel()

        // 创建 Poke 通知频道（高优先级，弹横幅）
        createPokeNotificationChannel()

        // 全局未捕获异常处理
        val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
        Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
            Log.e(TAG, "Uncaught exception in ${thread.name}", throwable)

            // 写入崩溃日志文件
            writeCrashLog(throwable)

            // 交给默认处理器（系统弹窗）
            defaultHandler?.uncaughtException(thread, throwable)
        }
    }

    /**
     * 创建前台服务通知频道。
     * Android 8.0+（API 26+）必须先创建频道才能发送通知。
     */
    private fun createConnectionNotificationChannel() {
        val channel = NotificationChannel(
            CONNECTION_CHANNEL_ID,
            "服务器连接",
            NotificationManager.IMPORTANCE_LOW,
        ).apply {
            description = "保持与 TeamSpeak 服务器的连接"
            setShowBadge(false)
        }
        val nm = getSystemService(NotificationManager::class.java)
        nm.createNotificationChannel(channel)
    }

    /**
     * 创建 Poke 通知频道。
     * IMPORTANCE_HIGH：弹出横幅、发出声音、锁屏可见。
     */
    private fun createPokeNotificationChannel() {
        val channel = NotificationChannel(
            POKE_CHANNEL_ID,
            "戳一戳 通知",
            NotificationManager.IMPORTANCE_HIGH,
        ).apply {
            description = "收到其他用户的 戳一戳 通知"
            setShowBadge(true)
        }
        val nm = getSystemService(NotificationManager::class.java)
        nm.createNotificationChannel(channel)
    }

    private fun writeCrashLog(throwable: Throwable) {
        try {
            val file = File(getExternalFilesDir(null), "crash.log")
            file.appendText(
                buildString {
                    appendLine("=== ${java.util.Date()} ===")
                    appendLine(throwable.stackTraceToString())
                    appendLine()
                }
            )
        } catch (e: Exception) {
            Log.e(TAG, "Failed to write crash log", e)
        }
    }
}
