package com.lxh.battery_health

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.net.Uri
import android.os.BatteryManager
import android.os.Build
import android.os.Bundle
import android.provider.DocumentsContract
import android.provider.OpenableColumns
import androidx.activity.ComponentActivity
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.EventChannel
import io.flutter.plugin.common.MethodChannel
import java.io.BufferedReader
import java.io.InputStreamReader

class MainActivity : FlutterActivity() {
    private val CHARGE_CHANNEL = "com.lxh.battery_health/charge"
    private val EVENT_CHANNEL = "com.lxh.battery_health/charge_events"
    private var eventSink: EventChannel.EventSink? = null

    private val SAF_CHANNEL = "com.lxh.battery_health/saf"
    private var safResult: MethodChannel.Result? = null
    private var safUri: Uri? = null
    private val FOLDER_PICKER_REQUEST = 1001
    private val PREF_NAME = "battery_health_prefs"
    private val KEY_SAF_URI = "saf_uri"

    private val chargeReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            intent ?: return
            when (intent.action) {
                Intent.ACTION_POWER_CONNECTED -> sendChargeState(true)
                Intent.ACTION_POWER_DISCONNECTED -> sendChargeState(false)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        android.util.Log.d("BatteryHealth", "onCreate 开始")

        try {
            val prefs: SharedPreferences = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
            val uriString = prefs.getString(KEY_SAF_URI, null)
            android.util.Log.d("BatteryHealth", "SharedPreferences URI: $uriString")
            if (uriString != null) {
                safUri = Uri.parse(uriString)
                android.util.Log.d("BatteryHealth", "恢复 SAF URI 成功: $safUri")
            }
        } catch (e: Exception) {
            android.util.Log.e("BatteryHealth", "恢复 URI 异常: ${e.message}")
        }
        android.util.Log.d("BatteryHealth", "onCreate 结束，safUri = $safUri")
    }

    private fun saveUri(uri: Uri) {
        try {
            val prefs: SharedPreferences = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
            prefs.edit().putString(KEY_SAF_URI, uri.toString()).apply()
            android.util.Log.d("BatteryHealth", "保存 SAF URI: $uri")
        } catch (e: Exception) {
            android.util.Log.e("BatteryHealth", "保存 URI 失败: ${e.message}")
        }
    }

    private fun restoreUri(uriString: String) {
        try {
            safUri = Uri.parse(uriString)
            android.util.Log.d("BatteryHealth", "通过 MethodChannel 恢复 URI: $safUri")
            // 同时保存到 SharedPreferences
            val prefs: SharedPreferences = getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
            prefs.edit().putString(KEY_SAF_URI, uriString).apply()
        } catch (e: Exception) {
            android.util.Log.e("BatteryHealth", "restoreUri 失败: ${e.message}")
        }
    }

    private fun sendChargeState(isCharging: Boolean) {
        val chargeType = if (isCharging) {
            val batteryIntent = registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
            val plug = batteryIntent?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
            android.util.Log.d("BatteryHealth", "plug value: $plug, isCharging: $isCharging")
            when (plug) {
                BatteryManager.BATTERY_PLUGGED_AC -> "AC"
                BatteryManager.BATTERY_PLUGGED_USB -> "USB"
                BatteryManager.BATTERY_PLUGGED_WIRELESS -> "WIRELESS"
                else -> "UNKNOWN"
            }
        } else {
            "NONE"
        }
        eventSink?.success(mapOf("isCharging" to isCharging, "chargeType" to chargeType))
    }

    private fun getBatteryStatus(): Boolean {
        val batteryIntent = registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
        val status = batteryIntent?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
        return status == BatteryManager.BATTERY_STATUS_CHARGING ||
                status == BatteryManager.BATTERY_STATUS_FULL
    }

    private fun openFolderPicker() {
        try {
            val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    try {
                        val downloadsUri = DocumentsContract.buildDocumentUri(
                            "com.android.externalstorage.documents",
                            "primary:Downloads"
                        )
                        putExtra(DocumentsContract.EXTRA_INITIAL_URI, downloadsUri)
                    } catch (e: Exception) {
                        // 忽略
                    }
                }
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
            }
            startActivityForResult(intent, FOLDER_PICKER_REQUEST)
        } catch (e: Exception) {
            android.util.Log.e("BatteryHealth", "打开文件夹选择器失败: ${e.message}")
            safResult?.error("SELECT_FOLDER_FAILED", e.message, null)
            safResult = null
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == FOLDER_PICKER_REQUEST && resultCode == ComponentActivity.RESULT_OK) {
            val uri = data?.data
            if (uri != null) {
                try {
                    val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                    contentResolver.takePersistableUriPermission(uri, takeFlags)
                    safUri = uri
                    saveUri(uri)
                    android.util.Log.d("BatteryHealth", "SAF 授权成功 URI: $uri")
                    safResult?.success(uri.toString())
                } catch (e: Exception) {
                    android.util.Log.e("BatteryHealth", "SAF 授权失败: ${e.message}")
                    safResult?.error("SAF_FAILED", e.message, null)
                }
            } else {
                safResult?.success(null)
            }
            safResult = null
        }
    }

    private fun getTreeDocId(): String? {
        return safUri?.let { DocumentsContract.getTreeDocumentId(it) }
    }

    private fun listFiles(): List<String> {
        android.util.Log.d("BatteryHealth", "listFiles 被调用，safUri = $safUri")
        val result = mutableListOf<String>()
        val docId = getTreeDocId()
        if (docId == null || docId.isEmpty()) {
            android.util.Log.e("BatteryHealth", "docId 为空")
            return result
        }

        try {
            val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(safUri!!, docId)
            contentResolver.query(childrenUri, null, null, null, null)?.use { cursor ->
                val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
                while (cursor.moveToNext()) {
                    val name = cursor.getString(nameIndex)
                    if (name != null) {
                        result.add(name)
                    }
                }
            }
        } catch (e: Exception) {
            android.util.Log.e("BatteryHealth", "列出文件失败: ${e.message}", e)
        }
        return result
    }

    private fun getFileUri(fileName: String): Uri? {
        val docId = getTreeDocId() ?: return null
        try {
            val childrenUri = DocumentsContract.buildChildDocumentsUriUsingTree(safUri!!, docId)
            contentResolver.query(childrenUri, null, null, null, null)?.use { cursor ->
                val nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)
                val idIndex = cursor.getColumnIndex(DocumentsContract.Document.COLUMN_DOCUMENT_ID)
                while (cursor.moveToNext()) {
                    val name = cursor.getString(nameIndex)
                    if (name == fileName) {
                        val fileDocId = cursor.getString(idIndex)
                        return DocumentsContract.buildDocumentUriUsingTree(safUri!!, fileDocId)
                    }
                }
            }
        } catch (e: Exception) {
            android.util.Log.e("BatteryHealth", "获取文件URI失败: ${e.message}")
        }
        return null
    }

    private fun readFile(uri: Uri): String? {
        return try {
            contentResolver.openInputStream(uri)?.use { inputStream ->
                BufferedReader(InputStreamReader(inputStream)).use { reader ->
                    reader.readText()
                }
            }
        } catch (e: Exception) {
            android.util.Log.e("BatteryHealth", "读取文件失败: ${e.message}")
            null
        }
    }

    private fun readLogFile(fileName: String): String? {
        val fileUri = getFileUri(fileName)
        return fileUri?.let { readFile(it) }
    }

    override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHARGE_CHANNEL)
            .setMethodCallHandler { call, result ->
                if (call.method == "getChargeState") {
                    val isCharging = getBatteryStatus()
                    val chargeType = if (isCharging) {
                        val batteryIntent = registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
                        val plug = batteryIntent?.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) ?: -1
                        when (plug) {
                            BatteryManager.BATTERY_PLUGGED_AC -> "AC"
                            BatteryManager.BATTERY_PLUGGED_USB -> "USB"
                            BatteryManager.BATTERY_PLUGGED_WIRELESS -> "WIRELESS"
                            else -> "UNKNOWN"
                        }
                    } else {
                        "NONE"
                    }
                    result.success(mapOf("isCharging" to isCharging, "chargeType" to chargeType))
                } else {
                    result.notImplemented()
                }
            }

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, SAF_CHANNEL)
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "restoreUri" -> {
                        val uriString = call.argument<String>("uri")
                        if (uriString != null) {
                            restoreUri(uriString)
                            result.success(true)
                        } else {
                            result.error("INVALID_ARGUMENT", "uri is required", null)
                        }
                    }
                    "selectFolder" -> {
                        safResult = result
                        openFolderPicker()
                    }
                    "readLogFile" -> {
                        val fileName = call.argument<String>("fileName")
                        if (fileName != null) {
                            val content = readLogFile(fileName)
                            result.success(content)
                        } else {
                            result.error("INVALID_ARGUMENT", "fileName is required", null)
                        }
                    }
                    "listFiles" -> {
                        val files = listFiles()
                        result.success(files)
                    }
                    "getUri" -> {
                        result.success(safUri?.toString())
                    }
                    else -> result.notImplemented()
                }
            }

        EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENT_CHANNEL)
            .setStreamHandler(
                object : EventChannel.StreamHandler {
                    override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
                        eventSink = events
                        val filter = IntentFilter().apply {
                            addAction(Intent.ACTION_POWER_CONNECTED)
                            addAction(Intent.ACTION_POWER_DISCONNECTED)
                        }
                        registerReceiver(chargeReceiver, filter)
                    }

                    override fun onCancel(arguments: Any?) {
                        eventSink = null
                        unregisterReceiver(chargeReceiver)
                    }
                }
            )
    }
}