package com.agentui.desktop

import android.content.Context
import android.util.Log
import org.json.JSONObject
import java.io.File

object ServerConfig {
    private const val TAG = "ServerConfig"
    private const val PREFS_NAME = "agent_ui_config"
    private const val KEY_SERVER_URL = "server_url"

    fun getServerUrl(context: Context): String? {
        val stored = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
            .getString(KEY_SERVER_URL, null)
        if (!stored.isNullOrEmpty()) {
            Log.d(TAG, "Found serverUrl in SharedPreferences: $stored")
            return stored
        }

        // Fallback: search for Tauri store file in multiple possible locations
        return readFromTauriStore(context)
    }

    fun setServerUrl(context: Context, url: String) {
        val normalized = url.trimEnd('/')
        context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
            .edit()
            .putString(KEY_SERVER_URL, normalized)
            .apply()
        Log.d(TAG, "Saved serverUrl to SharedPreferences: $normalized")
    }

    /**
     * Searches for serverUrl in the Tauri plugin-store settings.json.
     * Tries multiple possible file locations since the Tauri store path
     * can vary by plugin version and platform.
     */
    private fun readFromTauriStore(context: Context): String? {
        Log.d(TAG, "SharedPreferences empty, searching Tauri store files...")

        // Try multiple possible paths where Tauri plugin-store may save settings.json
        val possiblePaths = listOf(
            File(context.filesDir, "app_tauri-plugin-store/settings.json"),
            File(context.filesDir, "settings.json"),
            File(context.dataDir, "app_tauri-plugin-store/settings.json"),
            File(context.dataDir, "settings.json"),
            File(context.filesDir, ".tauri/settings.json"),
            File(context.filesDir, "tauri-plugin-store/settings.json")
        )

        for (file in possiblePaths) {
            Log.d(TAG, "  Checking: ${file.absolutePath} exists=${file.exists()}")
            if (file.exists()) {
                try {
                    val content = file.readText()
                    Log.d(TAG, "  Found store file! Content: ${content.take(200)}")
                    val url = extractServerUrl(content)
                    if (url != null) {
                        setServerUrl(context, url)
                        Log.d(TAG, "  Extracted and cached serverUrl: $url")
                        return url
                    }
                } catch (e: Exception) {
                    Log.w(TAG, "  Failed to parse: ${file.absolutePath}", e)
                }
            }
        }

        // Also search recursively for any settings.json in the data directory
        val found = findFile(context.filesDir, "settings.json")
        if (found != null) {
            Log.d(TAG, "  Found via recursive search: ${found.absolutePath}")
            try {
                val content = found.readText()
                Log.d(TAG, "  Content: ${content.take(200)}")
                val url = extractServerUrl(content)
                if (url != null) {
                    setServerUrl(context, url)
                    return url
                }
            } catch (e: Exception) {
                Log.w(TAG, "  Failed to parse found file", e)
            }
        }

        // Debug: dump directory tree so we can see where files actually are
        Log.w(TAG, "  Could not find settings.json. Directory tree of filesDir:")
        dumpTree(context.filesDir, "    ")
        Log.w(TAG, "  Directory tree of dataDir:")
        dumpTree(context.dataDir, "    ")

        return null
    }

    /**
     * Extracts serverUrl from JSON content.
     * Handles both flat format {"serverUrl":"..."} and
     * possible wrapped formats.
     */
    private fun extractServerUrl(content: String): String? {
        try {
            val json = JSONObject(content)

            // Direct key
            val direct = json.optString("serverUrl", "")
            if (direct.isNotEmpty()) return direct.trimEnd('/')

            // Maybe nested under a "store" or "data" key
            for (key in json.keys()) {
                val inner = json.optJSONObject(key)
                if (inner != null) {
                    val nested = inner.optString("serverUrl", "")
                    if (nested.isNotEmpty()) return nested.trimEnd('/')
                }
            }
        } catch (e: Exception) {
            Log.w(TAG, "extractServerUrl parse error", e)
        }
        return null
    }

    /** Recursively find a file by name */
    private fun findFile(dir: File, name: String): File? {
        val files = dir.listFiles() ?: return null
        for (file in files) {
            if (file.isFile && file.name == name) return file
            if (file.isDirectory) {
                val found = findFile(file, name)
                if (found != null) return found
            }
        }
        return null
    }

    /** Dump directory tree for debugging */
    private fun dumpTree(dir: File, indent: String) {
        val files = dir.listFiles() ?: return
        for (file in files) {
            if (file.isDirectory) {
                Log.d(TAG, "$indent${file.name}/")
                dumpTree(file, "$indent  ")
            } else {
                Log.d(TAG, "$indent${file.name} (${file.length()} bytes)")
            }
        }
    }

    /** e.g. "http://192.168.1.10:4103" */
    fun terminalBaseUrl(context: Context): String? {
        val base = getServerUrl(context) ?: return null
        val uri = android.net.Uri.parse(base)
        val host = uri.host ?: return null
        return "${uri.scheme}://$host:4103"
    }

    /** e.g. "ws://192.168.1.10:4103" */
    fun terminalWsUrl(context: Context): String? {
        val base = terminalBaseUrl(context) ?: return null
        return base.replace("http://", "ws://").replace("https://", "wss://")
    }

    /** e.g. "http://192.168.1.10:4100/api" */
    fun apiBaseUrl(context: Context): String? {
        val base = getServerUrl(context) ?: return null
        return "${base.trimEnd('/')}/api"
    }
}
