package chat.vojo.proxy.core

import kotlinx.serialization.Serializable
import java.util.UUID

/** Supported upstream proxy protocols. No VLESS/Reality by design. */
@Serializable
enum class ProxyType {
    SHADOWSOCKS,
    SOCKS5,
    HTTP,
    HTTPS;

    val label: String
        get() = when (this) {
            SHADOWSOCKS -> "Shadowsocks"
            SOCKS5 -> "SOCKS5"
            HTTP -> "HTTP"
            HTTPS -> "HTTPS"
        }

    /** Two-letter badge used by the avatar tile in the UI. */
    val badge: String
        get() = when (this) {
            SHADOWSOCKS -> "SS"
            SOCKS5 -> "S5"
            HTTP -> "HT"
            HTTPS -> "HS"
        }
}

/** Shadowsocks AEAD ciphers backed by platform JCA. */
@Serializable
enum class SsCipher(val id: String, val keySize: Int, val saltSize: Int, val tagSize: Int = 16) {
    AES_128_GCM("aes-128-gcm", 16, 16),
    AES_256_GCM("aes-256-gcm", 32, 32),
    CHACHA20_IETF_POLY1305("chacha20-ietf-poly1305", 32, 32);
}

/**
 * A single saved proxy endpoint. One of these is "active" at a time.
 *
 * For HTTP/HTTPS/SOCKS5, [password]/[username] are the proxy credentials (optional).
 * For Shadowsocks, [password] is the SS password and [cipher] the AEAD method.
 */
@Serializable
data class ProxyConfig(
    val id: String = UUID.randomUUID().toString(),
    val name: String,
    val type: ProxyType,
    val host: String,
    val port: Int,
    val username: String = "",
    val password: String = "",
    val cipher: SsCipher = SsCipher.AES_256_GCM,
) {
    /** `host:port` shown in monospace, mirroring the `@user:server` handle in the design. */
    val handle: String get() = "$host:$port"

    fun validationError(): String? = when {
        name.isBlank() -> "Укажите имя"
        host.isBlank() -> "Укажите адрес сервера"
        port !in 1..65535 -> "Порт должен быть 1–65535"
        type == ProxyType.SHADOWSOCKS && password.isEmpty() -> "Укажите пароль Shadowsocks"
        else -> null
    }
}

/** App-wide settings persisted alongside the server list. */
@Serializable
data class AppSettings(
    /** Packages whose traffic is routed through the proxy (whitelist). Empty = all apps routed. */
    val allowedApps: Set<String> = emptySet(),
    val activeConfigId: String? = null,
    val ipv6: Boolean = false,
    /** DNS server queried by routed apps; sent through the tunnel for privacy. */
    val dns: String = "1.1.1.1",
    val mtu: Int = 8500,
)
