package de.hackernet.wireguardtv.model

import com.google.gson.Gson
import java.util.UUID

/**
 * WireGuard Tunnel Konfiguration
 * Kompatibel mit Standard .conf Format
 */
data class TunnelConfig(
    val id: String = UUID.randomUUID().toString(),
    val name: String,
    val interface_: InterfaceConfig,
    val peers: List<PeerConfig>,
    val isActive: Boolean = false,
    val autoConnect: Boolean = false,
    val createdAt: Long = System.currentTimeMillis()
) {
    companion object {
        private val gson = Gson()

        /**
         * Parse WireGuard .conf Format
         */
        fun fromConfString(confString: String, name: String = "Imported"): TunnelConfig {
            val lines = confString.lines()
            var currentSection = ""
            
            var privateKey = ""
            var addresses = listOf<String>()
            var dns = listOf<String>()
            var mtu: Int? = null
            var listenPort: Int? = null
            
            val peers = mutableListOf<PeerConfig>()
            var currentPeer: MutableMap<String, Any> = mutableMapOf()

            for (line in lines) {
                val trimmed = line.trim()
                when {
                    trimmed.isEmpty() || trimmed.startsWith("#") -> continue
                    trimmed == "[Interface]" -> currentSection = "interface"
                    trimmed == "[Peer]" -> {
                        if (currentPeer.isNotEmpty()) {
                            peers.add(parsePeer(currentPeer))
                        }
                        currentSection = "peer"
                        currentPeer = mutableMapOf()
                    }
                    trimmed.contains("=") -> {
                        val (key, value) = trimmed.split("=", limit = 2).map { it.trim() }
                        when (currentSection) {
                            "interface" -> when (key.lowercase()) {
                                "privatekey" -> privateKey = value
                                "address" -> addresses = value.split(",").map { it.trim() }
                                "dns" -> dns = value.split(",").map { it.trim() }
                                "mtu" -> mtu = value.toIntOrNull()
                                "listenport" -> listenPort = value.toIntOrNull()
                            }
                            "peer" -> currentPeer[key.lowercase()] = value
                        }
                    }
                }
            }
            
            // Letzten Peer hinzufügen
            if (currentPeer.isNotEmpty()) {
                peers.add(parsePeer(currentPeer))
            }

            return TunnelConfig(
                name = name,
                interface_ = InterfaceConfig(
                    privateKey = privateKey,
                    addresses = addresses,
                    dns = dns,
                    mtu = mtu,
                    listenPort = listenPort
                ),
                peers = peers
            )
        }

        private fun parsePeer(data: Map<String, Any>): PeerConfig {
            return PeerConfig(
                publicKey = data["publickey"]?.toString() ?: "",
                preSharedKey = data["presharedkey"]?.toString(),
                endpoint = data["endpoint"]?.toString(),
                allowedIPs = data["allowedips"]?.toString()?.split(",")?.map { it.trim() } ?: listOf("0.0.0.0/0"),
                persistentKeepalive = data["persistentkeepalive"]?.toString()?.toIntOrNull()
            )
        }

        fun fromJson(json: String): TunnelConfig = gson.fromJson(json, TunnelConfig::class.java)
    }

    fun toJson(): String = gson.toJson(this)

    /**
     * Exportiert als Standard WireGuard .conf Format
     */
    fun toConfString(): String {
        val sb = StringBuilder()
        
        sb.appendLine("[Interface]")
        sb.appendLine("PrivateKey = ${interface_.privateKey}")
        sb.appendLine("Address = ${interface_.addresses.joinToString(", ")}")
        if (interface_.dns.isNotEmpty()) {
            sb.appendLine("DNS = ${interface_.dns.joinToString(", ")}")
        }
        interface_.mtu?.let { sb.appendLine("MTU = $it") }
        interface_.listenPort?.let { sb.appendLine("ListenPort = $it") }
        
        for (peer in peers) {
            sb.appendLine()
            sb.appendLine("[Peer]")
            sb.appendLine("PublicKey = ${peer.publicKey}")
            peer.preSharedKey?.let { sb.appendLine("PresharedKey = $it") }
            peer.endpoint?.let { sb.appendLine("Endpoint = $it") }
            sb.appendLine("AllowedIPs = ${peer.allowedIPs.joinToString(", ")}")
            peer.persistentKeepalive?.let { sb.appendLine("PersistentKeepalive = $it") }
        }
        
        return sb.toString()
    }
}

data class InterfaceConfig(
    val privateKey: String,
    val addresses: List<String>,
    val dns: List<String> = emptyList(),
    val mtu: Int? = null,
    val listenPort: Int? = null
)

data class PeerConfig(
    val publicKey: String,
    val preSharedKey: String? = null,
    val endpoint: String? = null,
    val allowedIPs: List<String> = listOf("0.0.0.0/0", "::/0"),
    val persistentKeepalive: Int? = null
)

/**
 * Tunnel Status für UI Updates
 */
enum class TunnelState {
    DISCONNECTED,
    CONNECTING,
    CONNECTED,
    DISCONNECTING,
    ERROR
}

data class TunnelStatus(
    val tunnelId: String,
    val state: TunnelState,
    val rxBytes: Long = 0,
    val txBytes: Long = 0,
    val lastHandshake: Long = 0,
    val errorMessage: String? = null,
    val publicIp: String? = null,
    val countryCode: String? = null,
    val countryName: String? = null,
    val countryFlag: String? = null
)
