package com.example.godeye.utils

import android.content.Context
import android.content.SharedPreferences
import android.net.wifi.WifiManager
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import java.net.NetworkInterface
import java.net.InetAddress
import java.util.*
import java.text.SimpleDateFormat

fun Context.getPreferences(): SharedPreferences {
    return getSharedPreferences("godeye_prefs", Context.MODE_PRIVATE)
}

fun generateDeviceId(): String {
    return "android_${UUID.randomUUID().toString().take(8)}"
}

/**
 * НОВОЕ: Получение реального IP-адреса устройства с обновленными API
 */
fun Context.getLocalIpAddress(): String {
    try {
        // Метод 1: Через WiFi Manager (для WiFi соединений) - обновленный API
        val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager
        wifiManager?.let { wifi ->
            if (wifi.isWifiEnabled) {
                // ИСПРАВЛЕНИЕ: Используем современный API для получения WiFi информации
                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                    // Для Android 10+ используем ConnectivityManager
                    val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
                    connectivityManager?.let { cm ->
                        val activeNetwork = cm.activeNetwork
                        val linkProperties = cm.getLinkProperties(activeNetwork)
                        linkProperties?.linkAddresses?.forEach { linkAddress ->
                            val address = linkAddress.address
                            if (address is java.net.Inet4Address && !address.isLoopbackAddress) {
                                val ip = address.hostAddress
                                if (ip != null && !ip.startsWith("127.")) {
                                    Logger.step("IP_DETECTION", "Modern API IP detected: $ip")
                                    return ip
                                }
                            }
                        }
                    }
                } else {
                    // Для старых версий Android используем deprecated API с обработкой
                    @Suppress("DEPRECATION")
                    val wifiInfo = wifi.connectionInfo
                    @Suppress("DEPRECATION")
                    val ipInt = wifiInfo.ipAddress
                    if (ipInt != 0) {
                        val ip = String.format(
                            "%d.%d.%d.%d",
                            ipInt and 0xff,
                            ipInt shr 8 and 0xff,
                            ipInt shr 16 and 0xff,
                            ipInt shr 24 and 0xff
                        )
                        Logger.step("IP_DETECTION", "Legacy WiFi IP detected: $ip")
                        return ip
                    }
                }
            }
        }

        // Метод 2: Через NetworkInterface (универсальный метод)
        val interfaces = NetworkInterface.getNetworkInterfaces()
        for (networkInterface in interfaces) {
            // Пропускаем loopback и неактивные интерфейсы
            if (networkInterface.isLoopback || !networkInterface.isUp) continue

            val addresses = networkInterface.inetAddresses
            for (address in addresses) {
                // Пропускаем IPv6 и loopback адреса
                if (!address.isLoopbackAddress && address is java.net.Inet4Address) {
                    val ip = address.hostAddress
                    if (ip != null && !ip.startsWith("127.")) {
                        Logger.step("IP_DETECTION", "Network interface IP detected: $ip on ${networkInterface.name}")
                        return ip
                    }
                }
            }
        }

        // Метод 3: Через ConnectivityManager (Android 6+)
        val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager
        connectivityManager?.let { cm ->
            val activeNetwork = cm.activeNetwork
            val networkCapabilities = cm.getNetworkCapabilities(activeNetwork)
            if (networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true) {
                Logger.step("IP_DETECTION", "Active network detected but couldn't extract IP")
            }
        }

    } catch (e: Exception) {
        Logger.error("IP_DETECTION_ERROR", "Failed to detect local IP", e)
    }

    // Fallback: возвращаем IP по умолчанию для вашей подсети
    val fallbackIP = "192.168.219.108" // ИСПРАВЛЕНИЕ: Изменено на ваш сервер
    Logger.step("IP_DETECTION_FALLBACK", "Using fallback IP: $fallbackIP")
    return fallbackIP
}

/**
 * НОВОЕ: Получение IP сервера из URL
 */
fun extractServerIP(serverUrl: String): String {
    return try {
        val regex = """://([^:/]+)""".toRegex()
        val match = regex.find(serverUrl)
        match?.groupValues?.get(1) ?: "192.168.219.1" // Fallback на ваш роутер
    } catch (e: Exception) {
        Logger.error("SERVER_IP_EXTRACTION_ERROR", "Failed to extract server IP from URL: $serverUrl", e)
        "192.168.219.1"
    }
}

/**
 * НОВОЕ: Автоматическое определение подсети
 */
fun Context.detectNetworkSubnet(): String {
    val localIP = getLocalIpAddress()
    return try {
        val parts = localIP.split(".")
        if (parts.size >= 3) {
            "${parts[0]}.${parts[1]}.${parts[2]}.0/24"
        } else {
            "192.168.219.0/24" // Fallback на вашу подсеть
        }
    } catch (e: Exception) {
        Logger.error("SUBNET_DETECTION_ERROR", "Failed to detect subnet", e)
        "192.168.219.0/24"
    }
}

/**
 * НОВОЕ: Проверка, находится ли IP в локальной сети
 */
fun isLocalNetworkIP(ip: String): Boolean {
    return try {
        val parts = ip.split(".").map { it.toInt() }
        when {
            // 192.168.x.x
            parts[0] == 192 && parts[1] == 168 -> true
            // 10.x.x.x
            parts[0] == 10 -> true
            // 172.16.x.x - 172.31.x.x
            parts[0] == 172 && parts[1] in 16..31 -> true
            else -> false
        }
    } catch (e: Exception) {
        false
    }
}
