package com.optix.android.tools.network

import com.optix.android.domain.model.OsintResult
import com.optix.android.domain.model.ParamType
import com.optix.android.domain.model.ToolCategory
import com.optix.android.domain.model.ToolEvent
import com.optix.android.domain.model.ToolMetadata
import com.optix.android.domain.model.ToolParam
import com.optix.android.tools.registry.BaseTool
import android.content.Context
import android.net.wifi.WifiManager
/**
 * WiFi Scanner — requires ACCESS_FINE_LOCATION.
 * Uses system WifiManager to read scanResults.
 */
class WifiScannerTool(private val context: Context) : BaseTool() {

    override val metadata = ToolMetadata(
        name = "wifi_scanner",
        displayName = "WiFi Scanner",
        description = "Scan for nearby WiFi networks (SSID, BSSID, signal, security)",
        category = ToolCategory.NETWORK_SCANNING,
        requiresNetwork = false,
        parameters = listOf(
            ToolParam("include_hidden", ParamType.BOOLEAN, "Include hidden networks", required = false, defaultValue = "false"),
        ),
    )

    override suspend fun execute(params: Map<String, Any>, emit: suspend (ToolEvent) -> Unit) {
        val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager
        if (wifiManager == null) {
            emit(ToolEvent.Error("WifiManager not available on this device."))
            emit(ToolEvent.Done)
            return
        }

        val results = try {
            @Suppress("DEPRECATION")
            wifiManager.scanResults
        } catch (e: SecurityException) {
            emit(ToolEvent.Error("Missing ACCESS_FINE_LOCATION permission to read WiFi scans."))
            emit(ToolEvent.Done)
            return
        }

        if (results.isEmpty()) {
            emit(ToolEvent.Log("No networks found or permission restricted."))
        }

        val includeHidden = paramBool(params, "include_hidden", false)

        results.forEach { ap ->
            @Suppress("DEPRECATION")
            val ssid = ap.SSID.takeIf { it.isNotEmpty() } ?: "Hidden"
            if (ssid == "Hidden" && !includeHidden) return@forEach

            @Suppress("DEPRECATION")
            emit(ToolEvent.Result(OsintResult(
                field = ssid,
                value = "BSSID=${ap.BSSID}  Signal=${ap.level}dBm  Sec=${ap.capabilities}",
                source = "WifiManager",
            )))
        }
        emit(ToolEvent.Log("Found ${results.size} networks."))
        emit(ToolEvent.ChainSuggestion("evil_twin", mapOf(
            "ssid" to (results.firstOrNull()?.let { if (it.SSID.isNotEmpty()) it.SSID else "Target_AP" } ?: "Target_AP"),
            "bssid" to (results.firstOrNull()?.BSSID ?: "00:00:00:00:00:00"),
        )))
        emit(ToolEvent.Done)
    }
}
