package com.pangolin.pangolin_vpn

import android.app.Activity
import android.content.Intent
import android.net.VpnService
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import android.util.Log
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodChannel

/**
 * MainActivity — Flutter ↔ 原生通道注册
 *
 * 通道契约（见 lib/bridge/vpn_bridge.dart 头部注释）：
 *   MethodChannel  : pangolin/vpn
 *   EventChannel   : pangolin/vpn/status
 *   EventChannel   : pangolin/vpn/stats
 *
 * ## VPN 权限流程（Android 要求）
 *   1. [VpnService.prepare] 返回非 null Intent → 需要用户授权
 *   2. 启动授权 Activity，result code 存 [pendingConfigJson]
 *   3. [onActivityResult] 回调 RESULT_OK → 正式启动 [PangolinVpnService]
 *      RESULT_CANCELED → 推送 error 状态到 Flutter
 *
 * ## 电池优化
 *   首次连接时引导用户豁免电池优化，确保后台 30 分钟不被杀。
 */
class MainActivity : FlutterActivity() {

    companion object {
        private const val TAG = "PangolinMainActivity"
        private const val VPN_CHANNEL    = "pangolin/vpn"
        private const val STATUS_CHANNEL = "pangolin/vpn/status"
        private const val STATS_CHANNEL  = "pangolin/vpn/stats"

        private const val VPN_PERMISSION_REQUEST_CODE = 100
    }

    /** 等待 VPN 授权时缓存的 configJson，授权完成后使用 */
    private var pendingConfigJson: String? = null

    private var statusEventSink: EventChannel.EventSink? = null
    private var statsEventSink: EventChannel.EventSink? = null

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        val messenger = flutterEngine.dartExecutor.binaryMessenger

        // ── MethodChannel ────────────────────────────────────────
        MethodChannel(messenger, VPN_CHANNEL).setMethodCallHandler { call, result ->
            Log.d(TAG, "MethodChannel: ${call.method}")
            when (call.method) {
                "start" -> {
                    val configJson = call.arguments as? String ?: "{}"
                    handleStartCall(configJson, result)
                }
                "stop" -> {
                    PangolinVpnService.stopVpn(this)
                    result.success(null)
                }
                "getStatus" -> {
                    result.success(VpnEventBus.currentStatus)
                }
                "selectOutbound" -> {
                    val tag = call.arguments as? String ?: "auto"
                    Log.d(TAG, "selectOutbound: tag=$tag (stub — 11G)")
                    // TODO(11G): 通过 libbox CommandClient 切换出口
                    result.success(null)
                }
                "getActiveOutbound" -> {
                    Log.d(TAG, "getActiveOutbound (stub — 11G)")
                    // TODO(11G): 从 libbox CommandClient 查询当前出口 tag
                    result.success("auto")
                }
                "setKillSwitch" -> {
                    val on = call.arguments as? Boolean ?: false
                    Log.d(TAG, "setKillSwitch: on=$on (stub — 11G)")
                    // TODO(11G): 配置 VPN allowedApplications / blockingMode
                    result.success(null)
                }
                else -> result.notImplemented()
            }
        }

        // ── EventChannel: status ─────────────────────────────────
        EventChannel(messenger, STATUS_CHANNEL).setStreamHandler(
            object : EventChannel.StreamHandler {
                override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
                    Log.d(TAG, "status channel: onListen")
                    statusEventSink = events
                    VpnEventBus.setStatusListener(object : VpnEventBus.StatusListener {
                        override fun onStatus(status: String) {
                            statusEventSink?.success(status)
                        }
                    })
                    // 立即推送当前状态（订阅时的初始值）
                    events.success(VpnEventBus.currentStatus)
                }
                override fun onCancel(arguments: Any?) {
                    Log.d(TAG, "status channel: onCancel")
                    statusEventSink = null
                    VpnEventBus.setStatusListener(null)
                }
            }
        )

        // ── EventChannel: stats ──────────────────────────────────
        EventChannel(messenger, STATS_CHANNEL).setStreamHandler(
            object : EventChannel.StreamHandler {
                override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
                    Log.d(TAG, "stats channel: onListen")
                    statsEventSink = events
                    VpnEventBus.setStatsListener(object : VpnEventBus.StatsListener {
                        override fun onStats(stats: Map<String, Any>) {
                            statsEventSink?.success(stats)
                        }
                    })
                }
                override fun onCancel(arguments: Any?) {
                    Log.d(TAG, "stats channel: onCancel")
                    statsEventSink = null
                    VpnEventBus.setStatsListener(null)
                }
            }
        )
    }

    // ── VPN 权限 + 电池优化 ───────────────────────────────────────

    /**
     * start() MethodChannel 调用入口：
     *   - 若 VpnService.prepare() 需要用户授权，先弹授权 Activity（result 异步回调）
     *   - 若已授权，直接启动服务
     */
    private fun handleStartCall(configJson: String, result: MethodChannel.Result) {
        // 同步检查：是否需要 VPN 授权弹窗
        val prepareIntent = VpnService.prepare(this)
        if (prepareIntent != null) {
            Log.i(TAG, "VPN permission not granted, launching prepare intent")
            pendingConfigJson = configJson
            @Suppress("DEPRECATION")
            startActivityForResult(prepareIntent, VPN_PERMISSION_REQUEST_CODE)
            // 先返回 null 给 Dart，实际连接状态由 EventChannel 驱动
            result.success(null)
        } else {
            // 已授权，直接启动
            requestBatteryOptimizationExemptionIfNeeded()
            PangolinVpnService.startVpn(this, configJson)
            result.success(null)
        }
    }

    @Deprecated("Deprecated in Java")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == VPN_PERMISSION_REQUEST_CODE) {
            val config = pendingConfigJson
            pendingConfigJson = null
            if (resultCode == Activity.RESULT_OK && config != null) {
                Log.i(TAG, "VPN permission granted, starting service")
                requestBatteryOptimizationExemptionIfNeeded()
                PangolinVpnService.startVpn(this, config)
            } else {
                Log.w(TAG, "VPN permission denied (resultCode=$resultCode)")
                VpnEventBus.postStatus("error")
            }
        }
        @Suppress("DEPRECATION")
        super.onActivityResult(requestCode, resultCode, data)
    }

    /**
     * 引导用户豁免电池优化（首次连接时弹一次）。
     * 豁免后后台 30 分钟内系统不会主动杀服务。
     *
     * 注：BATTERY_OPTIMIZATION_EXEMPTED 不影响应用核心功能，
     *   用户可在设置内随时撤销——VPN 仍可运行，但有被杀风险。
     */
    private fun requestBatteryOptimizationExemptionIfNeeded() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val pm = getSystemService(PowerManager::class.java)
            if (!pm.isIgnoringBatteryOptimizations(packageName)) {
                try {
                    startActivity(Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS).apply {
                        data = Uri.parse("package:$packageName")
                    })
                } catch (e: Exception) {
                    Log.w(TAG, "Cannot launch battery optimization settings: $e")
                }
            }
        }
    }

    // ── 清理 ─────────────────────────────────────────────────────

    override fun onDestroy() {
        statusEventSink = null
        statsEventSink = null
        VpnEventBus.setStatusListener(null)
        VpnEventBus.setStatsListener(null)
        super.onDestroy()
    }
}
