/*
 * Hermes Node Android
 * Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net>
 * SPDX-License-Identifier: GPL-3.0-or-later
 */
package net.nexlab.hermesnodeandroid.capabilities

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.res.Configuration
import android.os.PowerManager
import android.util.DisplayMetrics
import net.nexlab.hermesnodeandroid.AndroidRuntimeGrants
import net.nexlab.hermesnodeandroid.CapabilityResult
import net.nexlab.hermesnodeandroid.HermesAccessibilityService
import org.json.JSONObject

class AndroidDesktopObserve(private val context: Context) {
    private val capture = MediaProjectionCapture(context)

    fun capabilityInfo(): JSONObject = JSONObject()
        .put("available", true)
        .put("screen_info", true)
        .put("active_window_available", HermesAccessibilityService.current() != null)
        .put("active_window_requires_accessibility", HermesAccessibilityService.current() == null)
        .put("screenshot_available", AndroidRuntimeGrants.hasMediaProjection())
        .put("screenshot_requires_media_projection", !AndroidRuntimeGrants.hasMediaProjection())
        .put("clipboard_get", true)

    fun handle(action: String?, params: JSONObject): CapabilityResult = when (action) {
        "screen_info" -> screenInfo()
        "active_window", "get_active_window" -> activeWindow()
        "screenshot", "region_screenshot" -> screenshot(params)
        "clipboard_get" -> clipboardGet()
        "cursor_position", "mouse_position" -> CapabilityResult.ok("x" to 0, "y" to 0, "note" to "Android has touch focus, not a persistent mouse cursor")
        "list_windows" -> activeWindow().let { res ->
            if (!res.success) res else CapabilityResult.ok("windows" to org.json.JSONArray().put(res.data), "count" to 1)
        }
        "window_geometry" -> screenInfo()
        else -> CapabilityResult.unsupported("Unknown desktop_observe action: $action")
    }

    private fun screenInfo(): CapabilityResult {
        val metrics: DisplayMetrics = context.resources.displayMetrics
        val orientation = when (context.resources.configuration.orientation) {
            Configuration.ORIENTATION_LANDSCAPE -> "landscape"
            Configuration.ORIENTATION_PORTRAIT -> "portrait"
            else -> "unknown"
        }
        val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
        return CapabilityResult.ok(
            "width" to metrics.widthPixels,
            "height" to metrics.heightPixels,
            "density" to metrics.density,
            "density_dpi" to metrics.densityDpi,
            "orientation" to orientation,
            "interactive" to pm.isInteractive,
        )
    }

    private fun activeWindow(): CapabilityResult {
        val service = HermesAccessibilityService.current()
            ?: return CapabilityResult.unsupported("active_window requires enabling Hermes Node Accessibility Service")
        return CapabilityResult.ok(*service.activeWindowInfo().map { it.key to it.value }.toTypedArray())
    }

    private fun screenshot(params: JSONObject): CapabilityResult = capture.capture(params)

    private fun clipboardGet(): CapabilityResult {
        val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        val clip: ClipData? = clipboard.primaryClip
        val text = if (clip != null && clip.itemCount > 0) clip.getItemAt(0).coerceToText(context)?.toString() else ""
        return CapabilityResult.ok("text" to (text ?: ""), "available" to (clip != null))
    }
}
