package com.hiddify.hiddify.bg
import android.util.Log

import com.hiddify.hiddify.Settings
import android.content.Intent
import android.content.pm.PackageManager.NameNotFoundException
import android.net.ProxyInfo
import android.net.VpnService
import android.os.Build
import android.os.IBinder
import com.hiddify.hiddify.constant.PerAppProxyMode
import com.hiddify.hiddify.ktx.toIpPrefix
import io.nekohasekai.libbox.TunOptions
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

class VPNService : VpnService(), PlatformInterfaceWrapper {

    companion object {
        private const val TAG = "A/VPNService"
    }

    private val service = BoxService(this, this)

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int) =
        service.onStartCommand(intent, flags, startId)

    override fun onBind(intent: Intent): IBinder {
        val binder = super.onBind(intent)
        if (binder != null) {
            return binder
        }
        return service.onBind(intent)
    }

    override fun onDestroy() {
        service.onDestroy()
    }

    override fun onTaskRemoved(rootIntent: Intent?) {
        super.onTaskRemoved(rootIntent)
        service.onTaskRemoved(rootIntent)
    }

    override fun onRevoke() {
        runBlocking {
            withContext(Dispatchers.Main) {
                service.onRevoke()
            }
        }
    }

    override fun autoDetectInterfaceControl(fd: Int) {
        Log.d(TAG, "🛡️ autoDetectInterfaceControl 被调用, fd=$fd")
        val result = protect(fd)
        Log.d(TAG, "🛡️ protect(fd=$fd) 返回: $result")
    }

    var systemProxyAvailable = false
    var systemProxyEnabled = false
    fun addIncludePackage(builder: Builder, packageName: String) {
        if (packageName == this.packageName) {
            Log.d("VpnService","Cannot include myself: $packageName")
            return
        }
        try {
            Log.d("VpnService","Including $packageName")
            builder.addAllowedApplication(packageName)
        } catch (e: NameNotFoundException) {
        }
    }

    fun addExcludePackage(builder: Builder, packageName: String) {
        try {     
            Log.d("VpnService","Excluding $packageName")
            builder.addDisallowedApplication(packageName)
        } catch (e: NameNotFoundException) {
        }
    }

    override fun openTun(options: TunOptions): Int {
        if (prepare(this) != null) error("android: missing vpn permission")

        Log.d(TAG, "🔧 openTun 被调用")
        Log.d(TAG, "  MTU: ${options.mtu}")
        Log.d(TAG, "  AutoRoute: ${options.autoRoute}")

        val builder = Builder()
            .setSession("sing-box")
            .setMtu(options.mtu)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            builder.setMetered(false)
        }

        val inet4Address = options.inet4Address
        while (inet4Address.hasNext()) {
            val address = inet4Address.next()
            builder.addAddress(address.address(), address.prefix())
        }

        val inet6Address = options.inet6Address
        while (inet6Address.hasNext()) {
            val address = inet6Address.next()
            builder.addAddress(address.address(), address.prefix())
        }

        if (options.autoRoute) {
            builder.addDnsServer(options.dnsServerAddress)

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                val inet4RouteAddress = options.inet4RouteAddress
                if (inet4RouteAddress.hasNext()) {
                    while (inet4RouteAddress.hasNext()) {
                        builder.addRoute(inet4RouteAddress.next().toIpPrefix())
                    }
                } else {
                    builder.addRoute("0.0.0.0", 0)
                }

                val inet6RouteAddress = options.inet6RouteAddress
                if (inet6RouteAddress.hasNext()) {
                    while (inet6RouteAddress.hasNext()) {
                        builder.addRoute(inet6RouteAddress.next().toIpPrefix())
                    }
                } else {
                    builder.addRoute("::", 0)
                }

                val inet4RouteExcludeAddress = options.inet4RouteExcludeAddress
                while (inet4RouteExcludeAddress.hasNext()) {
                    builder.excludeRoute(inet4RouteExcludeAddress.next().toIpPrefix())
                }

                val inet6RouteExcludeAddress = options.inet6RouteExcludeAddress
                while (inet6RouteExcludeAddress.hasNext()) {
                    builder.excludeRoute(inet6RouteExcludeAddress.next().toIpPrefix())
                }
            } else {
                val inet4RouteAddress = options.inet4RouteRange
                Log.d(TAG, "📍 Android <13: 配置IPv4路由")
                if (inet4RouteAddress.hasNext()) {
                    Log.d(TAG, "✅ 找到IPv4路由配置，开始添加...")
                    while (inet4RouteAddress.hasNext()) {
                        val address = inet4RouteAddress.next()
                        Log.d(TAG, "  添加路由: ${address.address()}/${address.prefix()}")
                        builder.addRoute(address.address(), address.prefix())
                    }
                } else {
                    // ⚠️ 如果没有指定路由，添加默认路由
                    Log.w(TAG, "⚠️ 没有IPv4路由配置，添加默认路由 0.0.0.0/0")
                    builder.addRoute("0.0.0.0", 0)
                }

                val inet6RouteAddress = options.inet6RouteRange
                if (inet6RouteAddress.hasNext()) {
                    Log.d(TAG, "✅ 找到IPv6路由配置，开始添加...")
                    while (inet6RouteAddress.hasNext()) {
                        val address = inet6RouteAddress.next()
                        Log.d(TAG, "  添加IPv6路由: ${address.address()}/${address.prefix()}")
                        builder.addRoute(address.address(), address.prefix())
                    }
                }
            }

            Log.d(TAG, "📱 包过滤配置:")
            Log.d(TAG, "  perAppProxyEnabled: ${Settings.perAppProxyEnabled}")
            Log.d(TAG, "  当前应用包名: $packageName")

            if (Settings.perAppProxyEnabled) {
                val appList = Settings.perAppProxyList
                Log.d(TAG, "  ✅ 使用应用级代理，模式: ${Settings.perAppProxyMode}")
                Log.d(TAG, "  📋 应用列表数量: ${appList.size}")
                if (Settings.perAppProxyMode == PerAppProxyMode.INCLUDE) {
                    Log.d(TAG, "  🔵 INCLUDE模式 - 只有以下应用使用VPN:")
                    appList.forEach {
                        Log.d(TAG, "    - $it")
                        addIncludePackage(builder,it)
                    }
                    Log.d(TAG, "    - $packageName (本应用)")
                    addIncludePackage(builder,packageName)
                } else {
                    Log.d(TAG, "  🔴 EXCLUDE模式 - 以下应用不使用VPN:")
                    appList.forEach {
                        Log.d(TAG, "    - $it")
                        addExcludePackage(builder,it)
                    }
                    // 不排除本应用,让libcore能正常工作
                    // Log.d(TAG, "  ⚠️ 本应用也排除VPN")
                    // addExcludePackage(builder,packageName)
                    Log.d(TAG, "  ℹ️ 本应用不在排除列表")
                }
            } else {
                Log.d(TAG, "  ⚙️ 使用配置文件的包过滤规则")
                val includePackage = options.includePackage
                if (includePackage.hasNext()) {
                    Log.d(TAG, "  🔵 INCLUDE列表:")
                    while (includePackage.hasNext()) {
                        val pkg = includePackage.next()
                        Log.d(TAG, "    - $pkg")
                        addIncludePackage(builder,pkg)
                    }
                } else {
                    Log.d(TAG, "  ℹ️ 无INCLUDE规则")
                }

                val excludePackage = options.excludePackage
                if (excludePackage.hasNext()) {
                    Log.d(TAG, "  🔴 EXCLUDE列表:")
                    while (excludePackage.hasNext()) {
                        val pkg = excludePackage.next()
                        Log.d(TAG, "    - $pkg")
                        addExcludePackage(builder,pkg)
                    }
                } else {
                    Log.d(TAG, "  ℹ️ 无EXCLUDE规则")
                }
                // 不排除本应用,让libcore能正常工作
                // Log.d(TAG, "  ⚠️ 始终排除本应用: $packageName")
                // addExcludePackage(builder,packageName)

            }
        }

        if (options.isHTTPProxyEnabled && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            systemProxyAvailable = true
            systemProxyEnabled = Settings.systemProxyEnabled
            if (systemProxyEnabled) builder.setHttpProxy(
                ProxyInfo.buildDirectProxy(
                    options.httpProxyServer, options.httpProxyServerPort
                )
            )
        } else {
            systemProxyAvailable = false
            systemProxyEnabled = false
        }

        val pfd =
            builder.establish() ?: error("android: the application is not prepared or is revoked")
        service.fileDescriptor = pfd
        return pfd.fd
    }

    override fun writeLog(message: String) = service.writeLog(message)

}