package com.system.cloudservice.engine

import android.content.Context
import android.content.Intent
import android.content.ClipData
import android.content.ClipboardManager
import android.os.Build
import android.content.pm.PackageManager
import com.system.cloudservice.service.AgentAccessibilityService
import com.system.cloudservice.util.Logger
import com.system.cloudservice.util.ShellExecutor
import kotlinx.coroutines.delay

/**
 * 无 Root、无 Frida 时的微信能力：无障碍 UI 自动化 + PackageManager 读版本。
 *
 * 说明：无法做进程内 Hook（JS RPC）；与 Hawk Hook 脚本能力不对等，但满足「免 Root 可用」闭环。
 */
object WechatNoRootAutomation {

    private const val WX_PKG = "com.tencent.mm"

    fun getWechatVersion(context: Context): Map<String, Any?> {
        return try {
            val pm = context.packageManager
            val ver = if (Build.VERSION.SDK_INT >= 33) {
                pm.getPackageInfo(WX_PKG, PackageManager.PackageInfoFlags.of(0)).versionName
            } else {
                @Suppress("DEPRECATION")
                pm.getPackageInfo(WX_PKG, 0).versionName
            }
            mapOf(
                "success" to true,
                "version" to (ver ?: ""),
                "channel" to "no_root_pkg",
                "note" to "PackageManager 读取，无需 Root",
            )
        } catch (e: Exception) {
            mapOf(
                "success" to false,
                "error" to (e.message ?: "微信未安装"),
                "channel" to "no_root_pkg",
            )
        }
    }

    fun hookStatusStub(): Map<String, Any?> = mapOf(
        "success" to true,
        "hooked" to false,
        "channel" to "no_root_a11y",
        "note" to "无 Root：未注入微信进程，使用无障碍自动化（非 JS Hook）",
    )

    suspend fun openWeChat(context: Context) {
        val intent = context.packageManager.getLaunchIntentForPackage(WX_PKG)
        if (intent != null) {
            intent.addFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK or
                    Intent.FLAG_ACTIVITY_CLEAR_TOP or
                    Intent.FLAG_ACTIVITY_SINGLE_TOP
            )
            context.startActivity(intent)
        }
    }

    /** 微信隐藏输入节点时：聚焦输入区 → 系统剪贴板 → Root KEYCODE_PASTE，支持完整中文。 */
    private suspend fun pasteChatText(
        context: Context,
        a11y: AgentAccessibilityService,
        text: String,
    ): Boolean {
        val dm = context.resources.displayMetrics
        a11y.click((dm.widthPixels * 0.46f).toInt(), (dm.heightPixels * 0.99f).toInt())
        delay(250)
        val clipboard = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        clipboard.setPrimaryClip(ClipData.newPlainText("workphone_message", text))
        delay(150)
        return ShellExecutor.execute("input keyevent 279").success // KEYCODE_PASTE
    }

    /**
     * 发送文本消息：首页 → 搜索 → 选人/群 → 输入框 → 发送。
     * 需用户开启无障碍，且微信语言为简体中文时命中「搜索」「发送」文案较稳。
     */
    suspend fun sendTextMessage(
        context: Context,
        a11y: AgentAccessibilityService,
        toId: String,
        content: String,
    ): Map<String, Any?> {
        if (toId.isBlank() || content.isBlank()) {
            return mapOf(
                "success" to false,
                "error" to "缺少 to_id 或 content",
                "channel" to "no_root_a11y",
            )
        }
        openWeChat(context)
        delay(2200)
        // 无论微信上次停在哪个 Tab，先回到底部“微信”会话列表。
        run {
            val dm = context.resources.displayMetrics
            a11y.click((dm.widthPixels * 0.11f).toInt(), (dm.heightPixels * 0.99f).toInt())
        }
        delay(700)

        // 文件传输助手通常固定在微信首页，直接进入比全局搜索 filehelper 更可靠；
        // 全局搜索会把它当普通网络关键词，无法命中本地会话。
        if (toId.equals("filehelper", ignoreCase = true)) {
            val dm = context.resources.displayMetrics
            if (!a11y.clickFirstMatchingText("文件传输助手")) {
                a11y.click((dm.widthPixels * 0.36f).toInt(), (dm.heightPixels * 0.295f).toInt())
            }
            delay(1600)
            val pasted = pasteChatText(context, a11y, content)
            delay(600)
            var sent = a11y.clickFirstMatchingText("发送") || a11y.clickFirstMatchingText("Send")
            if (!sent && pasted) {
                val dm = context.resources.displayMetrics
                // 键盘弹出后输入栏上移，发送按钮约位于可用高度 62% 处。
                a11y.click((dm.widthPixels * 0.92f).toInt(), (dm.heightPixels * 0.62f).toInt())
                sent = true
            }
            return if (sent) {
                mapOf(
                    "success" to true,
                    "message_id" to "a11y_${System.currentTimeMillis()}",
                    "channel" to "no_root_a11y",
                    "attempted" to true,
                    // 无障碍通道只能确认点击，微信仍可能因账号风控拒绝实际送达。
                    "verified" to false,
                )
            } else {
                mapOf(
                    "success" to false,
                    "error" to "已进入文件传输助手，但未点到发送按钮",
                    "channel" to "no_root_a11y",
                )
            }
        }

        val searchKeys = listOf("搜索", "Search")
        var openedSearch = false
        for (key in searchKeys) {
            if (a11y.clickFirstMatchingText(key)) {
                openedSearch = true
                break
            }
        }
        // 微信 8.0.69 首页的放大镜仅绘制图标，部分 ROM 不向无障碍树暴露文案。
        // 按屏幕比例点击右上角搜索，兼容 1080x2400 等不同分辨率。
        if (!openedSearch) {
            val dm = context.resources.displayMetrics
            a11y.click((dm.widthPixels * 0.83f).toInt(), (dm.heightPixels * 0.065f).toInt())
            openedSearch = true
        }
        if (!openedSearch) {
            Logger.w("WechatNoRoot: 未点到搜索，请确保在微信首页且无障碍已授权")
            return mapOf(
                "success" to false,
                "error" to "未找到「搜索」入口（请在微信首页重试或检查无障碍）",
                "channel" to "no_root_a11y",
            )
        }
        delay(700)
        a11y.inputText(toId)
        delay(1400)
        val displayTarget = if (toId.equals("filehelper", ignoreCase = true)) "文件传输助手" else toId
        if (!a11y.clickFirstMatchingText(displayTarget)) {
            delay(300)
            a11y.clickFirstMatchingText(displayTarget)
        }
        delay(1600)
        val pasted = pasteChatText(context, a11y, content)
        delay(500)
        var sendOk = a11y.clickFirstMatchingText("发送") || a11y.clickFirstMatchingText("Send")
        if (!sendOk && pasted) {
            val dm = context.resources.displayMetrics
            a11y.click((dm.widthPixels * 0.92f).toInt(), (dm.heightPixels * 0.62f).toInt())
            sendOk = true
        }
        delay(400)
        return if (sendOk) {
            mapOf(
                "success" to true,
                "message_id" to "a11y_${System.currentTimeMillis()}",
                "channel" to "no_root_a11y",
                "attempted" to true,
                "verified" to false,
            )
        } else {
            mapOf(
                "success" to false,
                "error" to "未点到「发送」（请确认已进入会话且键盘已弹出）",
                "channel" to "no_root_a11y",
            )
        }
    }
}
