package com.system.cloudservice.ui

import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.Fragment
import com.google.zxing.BarcodeFormat
import com.google.zxing.MultiFormatWriter
import com.google.gson.Gson
import com.system.cloudservice.R
import com.system.cloudservice.service.AgentForegroundService
import com.system.cloudservice.util.DeviceInfo
import com.system.cloudservice.util.Logger
import com.system.cloudservice.util.ShellExecutor
import kotlinx.coroutines.*

class SettingsFragment : Fragment() {

    private val prefs by lazy { requireContext().getSharedPreferences("agent_config", Context.MODE_PRIVATE) }
    private val scope = CoroutineScope(Dispatchers.Main + SupervisorJob())
    private var logExpanded = false

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        return inflater.inflate(R.layout.fragment_settings_v2, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        val deviceId = DeviceInfo.getOrCreateDeviceId(requireContext())
        view.findViewById<TextView>(R.id.tvServerUrl).text =
            "服务器  ${prefs.getString("server_url", "未绑定")}"
        view.findViewById<TextView>(R.id.tvProjectId).text =
            "项目  ${prefs.getString("project_id", "未配置")}"
        view.findViewById<TextView>(R.id.tvDeviceId).text = "设备ID  $deviceId"

        // device_id 复制 + 二维码展示（CKB-147 业务绑定辅助）
        view.findViewById<Button>(R.id.btnCopyDeviceId).setOnClickListener { copyDeviceId(deviceId) }
        view.findViewById<Button>(R.id.btnShowDeviceQr).setOnClickListener { showDeviceQr(deviceId) }

        // MIUI 保活 checklist（WP-AGENT-01）
        view.findViewById<Button>(R.id.btnKeepAutoStart).setOnClickListener {
            // MIUI 自启动无标准 Intent，跳应用详情页让用户手动进「自启动」
            startActivity(Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
                data = android.net.Uri.parse("package:${requireContext().packageName}")
            })
        }
        view.findViewById<Button>(R.id.btnKeepBattery).setOnClickListener {
            safeStart(Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS))
        }
        view.findViewById<Button>(R.id.btnKeepNotify).setOnClickListener {
            safeStart(Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
                putExtra(Settings.EXTRA_APP_PACKAGE, requireContext().packageName)
            })
        }
        view.findViewById<Button>(R.id.btnKeepA11y).setOnClickListener {
            safeStart(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
        }

        // WP-PMAX-01 Root 隐藏 checklist（量产黄灯必备）
        view.findViewById<Button>(R.id.btnRootDenyList).setOnClickListener {
            launchMagisk("请在 Magisk「DenyList」中勾选微信（com.tencent.mm）")
        }
        view.findViewById<Button>(R.id.btnRootShamiko).setOnClickListener {
            launchMagisk("请在 Magisk「模块」中确认 Shamiko 已启用")
        }
        view.findViewById<Button>(R.id.btnRootCheckPort).setOnClickListener {
            scope.launch {
                val listening = withContext(Dispatchers.IO) {
                    // 27042 = 0x69A2，/proc/net/tcp 端口为十六进制
                    val r = ShellExecutor.execute("cat /proc/net/tcp 2>/dev/null | grep -i ':69A2'")
                    r.success && r.output.isNotBlank() && r.output != "ok"
                }
                val msg = if (listening) "⚠ 27042 端口正在监听，建议关闭 Frida 默认端口" else "✓ 27042 端口未监听"
                Toast.makeText(requireContext(), msg, Toast.LENGTH_LONG).show()
            }
        }

        view.findViewById<Button>(R.id.btnRebind).setOnClickListener {
            prefs.edit().putBoolean("bound", false).apply()
            startActivity(Intent(requireContext(), SetupActivity::class.java))
            requireActivity().finish()
        }

        view.findViewById<Button>(R.id.btnOpenA11y).setOnClickListener {
            startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
        }

        view.findViewById<Button>(R.id.btnRestartService).setOnClickListener {
            startAgentService()
            Toast.makeText(requireContext(), "服务已重启", Toast.LENGTH_SHORT).show()
        }

        view.findViewById<Button>(R.id.btnStopService).setOnClickListener {
            val intent = Intent(requireContext(), AgentForegroundService::class.java).apply {
                action = AgentForegroundService.ACTION_STOP
            }
            requireContext().startService(intent)
            Toast.makeText(requireContext(), "服务已停止", Toast.LENGTH_SHORT).show()
        }

        val logScroll = view.findViewById<ScrollView>(R.id.logScrollView)
        val tvLog = view.findViewById<TextView>(R.id.tvLogContent)
        val btnToggle = view.findViewById<Button>(R.id.btnToggleLog)

        btnToggle.setOnClickListener {
            logExpanded = !logExpanded
            if (logExpanded) {
                logScroll.visibility = View.VISIBLE
                logScroll.layoutParams.height = (300 * resources.displayMetrics.density).toInt()
                logScroll.requestLayout()
                btnToggle.text = "收起"
                val logs = Logger.getRecentLogs(200)
                tvLog.text = if (logs.isEmpty()) "暂无日志" else logs.joinToString("\n")
                logScroll.post { logScroll.fullScroll(ScrollView.FOCUS_DOWN) }
            } else {
                logScroll.visibility = View.GONE
                btnToggle.text = "展开"
            }
        }

        view.findViewById<Button>(R.id.btnClearLog).setOnClickListener {
            Logger.clearBuffer()
            tvLog.text = "已清空"
        }
    }

    private fun copyDeviceId(deviceId: String) {
        val cm = requireContext().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
        cm.setPrimaryClip(ClipData.newPlainText("device_id", deviceId))
        Toast.makeText(requireContext(), "已复制 device_id", Toast.LENGTH_SHORT).show()
    }

    private fun showDeviceQr(deviceId: String) {
        try {
            // CKB-147：二维码内容为标准 JSON，存客宝扫码即可识别设备归属服务器/项目
            val serverUrl = prefs.getString("server_url", "") ?: ""
            val projectId = prefs.getString("project_id", "cunkebao") ?: "cunkebao"
            val qrJson = Gson().toJson(
                mapOf("device_id" to deviceId, "server" to serverUrl, "project" to projectId)
            )
            val size = 512
            val matrix = MultiFormatWriter().encode(qrJson, BarcodeFormat.QR_CODE, size, size)
            val bmp = Bitmap.createBitmap(size, size, Bitmap.Config.RGB_565)
            for (x in 0 until size) {
                for (y in 0 until size) {
                    bmp.setPixel(x, y, if (matrix[x, y]) Color.BLACK else Color.WHITE)
                }
            }
            val iv = ImageView(requireContext())
            iv.setImageBitmap(bmp)
            val padding = (16 * resources.displayMetrics.density).toInt()
            iv.setPadding(padding, padding, padding, padding)
            AlertDialog.Builder(requireContext())
                .setTitle("设备绑定二维码")
                .setMessage("存客宝扫描此二维码即可完成业务绑定（CKB-147）\n内容：device_id + 服务器 + 项目")
                .setView(iv)
                .setPositiveButton("关闭", null)
                .show()
        } catch (e: Exception) {
            Logger.e("showDeviceQr failed", e)
            Toast.makeText(requireContext(), "二维码生成失败: ${e.message}", Toast.LENGTH_LONG).show()
        }
    }

    private fun safeStart(intent: Intent) {
        try {
            startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
        } catch (e: Exception) {
            Toast.makeText(requireContext(), "无法打开：${e.message}", Toast.LENGTH_SHORT).show()
        }
    }

    /** WP-PMAX-01 跳转 Magisk App（兼容官方版 + Delta 版，未安装则提示）*/
    private fun launchMagisk(tip: String) {
        val pm = requireContext().packageManager
        // 官方 Magisk: com.topjohnwu.magisk · Magisk Delta: io.github.vvb2060.magisk
        val magiskPackages = listOf("com.topjohnwu.magisk", "io.github.vvb2060.magisk")
        val magiskIntent = magiskPackages.firstNotNullOfOrNull { pkg ->
            pm.getLaunchIntentForPackage(pkg)
        }
        if (magiskIntent != null) {
            startActivity(magiskIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
            Toast.makeText(requireContext(), tip, Toast.LENGTH_LONG).show()
        } else {
            Toast.makeText(requireContext(), "未安装 Magisk App", Toast.LENGTH_LONG).show()
        }
    }

    private fun startAgentService() {
        val serverUrl = prefs.getString("server_url", "") ?: ""
        val projectId = prefs.getString("project_id", "default") ?: "default"
        val deviceId = DeviceInfo.getOrCreateDeviceId(requireContext())
        val intent = Intent(requireContext(), AgentForegroundService::class.java).apply {
            action = AgentForegroundService.ACTION_START
            putExtra(AgentForegroundService.EXTRA_SERVER_URL, serverUrl)
            putExtra(AgentForegroundService.EXTRA_PROJECT_ID, projectId)
            putExtra(AgentForegroundService.EXTRA_DEVICE_ID, deviceId)
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) requireContext().startForegroundService(intent)
        else requireContext().startService(intent)
    }

    override fun onDestroyView() {
        super.onDestroyView()
        scope.cancel()
    }
}
