package com.xyzshell.andinfo.libs

import android.Manifest
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothManager
import android.bluetooth.le.BluetoothLeScanner
import android.bluetooth.le.ScanCallback
import android.bluetooth.le.ScanResult
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.app.ActivityCompat

/**
 * 蓝牙信息工具类
 * 提供蓝牙适配器信息、已配对设备、附近设备扫描、蓝牙特性检测等功能
 */
class BluetoothInfo(private val context: Context) {

    /**
     * 蓝牙管理器
     */
    private val bluetoothManager: BluetoothManager? = context.getSystemService(
        BluetoothManager::class.java
    )

    /**
     * 蓝牙适配器
     */
    @get:SuppressLint("MissingPermission")
    val bluetoothAdapter by lazy { bluetoothManager?.adapter }

    /**
     * 蓝牙设备信息数据类
     */
    data class DeviceInfo(
        val name: String?,           // 设备名称
        val address: String,         // MAC地址
        val bondState: Int,          // 配对状态
        val bondStateText: String,   // 配对状态文本
        val deviceClass: Int?,       // 设备类型
        val deviceType: Int?,        // 设备类型（LE/Classic/Dual）
        val rssi: Int? = null,       // 信号强度（仅扫描设备）
        val uuids: List<String>? = null // 支持的服务UUID
    )

    /**
     * 蓝牙特性信息数据类
     */
    data class BluetoothFeatures(
        val version: String,                    // 蓝牙版本
        val bluetoothLe: Boolean,               // 是否支持BLE
        val bluetooth: Boolean,                 // 是否支持经典蓝牙

        // Bluetooth 4.x 特性
        val le2MbPhy: Boolean,                  // 2Mbps PHY
        val leCodedPhy: Boolean,                // Coded PHY
        val leExtendedAdvertising: Boolean,     // 扩展广播
        val lePeriodicAdvertising: Boolean,     // 周期性广播

        // Bluetooth 5.x 特性
        val bluetooth5Support: Boolean,         // Bluetooth 5支持
        val leAudioSupport: Boolean,            // LE Audio支持
        val leAudioBroadcast: Boolean,          // LE Audio广播
        val leAudioUnicast: Boolean,            // LE Audio单播

        // 其他特性
        val offloadedFiltering: Boolean,        // 硬件过滤
        val offloadedScanBatching: Boolean,     // 批量扫描
        val multipleAdvertisement: Boolean,     // 多广播
        val lowEnergyExtended: Boolean          // 扩展LE
    )

    // ==================== 基本信息 ====================

    /**
     * 获取蓝牙适配器名称
     * 需要权限: BLUETOOTH_CONNECT (Android 12+)
     */
    @get:SuppressLint("MissingPermission")
    val adapterName: String?
        get() = if (checkBluetoothConnectPermission()) {
            bluetoothAdapter?.name
        } else null

    /**
     * 获取蓝牙适配器MAC地址
     * 需要权限: BLUETOOTH_CONNECT (Android 12+)
     * 注意: Android 6.0+ 返回固定地址 02:00:00:00:00:00
     */
    @get:SuppressLint("HardwareIds", "MissingPermission")
    val adapterMacAddress: String?
        get() = if (checkBluetoothConnectPermission()) {
            bluetoothAdapter?.address
        } else null

    /**
     * 蓝牙是否已启用
     */
    val isEnabled: Boolean
        get() = bluetoothAdapter?.isEnabled == true

    /**
     * 蓝牙适配器状态
     */
    val state: Int
        get() = bluetoothAdapter?.state ?: BluetoothAdapter.STATE_OFF

    /**
     * 蓝牙适配器状态文本
     */
    val stateText: String
        get() = when (state) {
            BluetoothAdapter.STATE_OFF -> "关闭"
            BluetoothAdapter.STATE_TURNING_ON -> "正在开启"
            BluetoothAdapter.STATE_ON -> "已开启"
            BluetoothAdapter.STATE_TURNING_OFF -> "正在关闭"
            else -> "未知"
        }

    /**
     * 是否支持低功耗蓝牙（BLE）
     */
    val isBluetoothLeSupported: Boolean
        get() = context.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)

    /**
     * 是否正在扫描设备
     */
    @get:SuppressLint("MissingPermission")
    val isDiscovering: Boolean
        get() = if (checkBluetoothScanPermission()) {
            bluetoothAdapter?.isDiscovering == true
        } else false

    // ==================== 已配对设备 ====================

    /**
     * 获取已配对设备列表（简化版本，兼容旧代码）
     * 需要权限: BLUETOOTH_CONNECT (Android 12+)
     */
    @get:SuppressLint("MissingPermission")
    val bondedDevices: List<Pair<String?, String>>
        get() = if (checkBluetoothConnectPermission()) {
            bluetoothAdapter?.bondedDevices?.map {
                Pair(it.name, it.address)
            } ?: emptyList()
        } else emptyList()

    /**
     * 获取已配对设备详细信息列表
     * 需要权限: BLUETOOTH_CONNECT (Android 12+)
     */
    @SuppressLint("MissingPermission")
    fun getBondedDevicesInfo(): List<DeviceInfo> {
        if (!checkBluetoothConnectPermission()) return emptyList()

        return try {
            bluetoothAdapter?.bondedDevices?.map { device ->
                DeviceInfo(
                    name = device.name,
                    address = device.address,
                    bondState = device.bondState,
                    bondStateText = getBondStateText(device.bondState),
                    deviceClass = device.bluetoothClass?.deviceClass,
                    deviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                        device.type
                    } else null,
                    uuids = device.uuids?.map { it.toString() }
                )
            } ?: emptyList()
        } catch (e: SecurityException) {
            emptyList()
        }
    }

    // ==================== 附近设备扫描 ====================

    /**
     * 扫描附近的经典蓝牙设备
     * 需要权限: BLUETOOTH_SCAN, ACCESS_FINE_LOCATION (Android 12+)
     * @param onDeviceFound 发现设备回调
     * @param onScanFinished 扫描完成回调
     */
    @SuppressLint("MissingPermission")
    fun scanNearbyDevices(
        onDeviceFound: (DeviceInfo) -> Unit,
        onScanFinished: () -> Unit
    ) {
        if (!checkBluetoothScanPermission() || !checkLocationPermission()) {
            onScanFinished()
            return
        }

        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                when (intent.action) {
                    BluetoothDevice.ACTION_FOUND -> {
                        val device: BluetoothDevice? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java)
                        } else {
                            @Suppress("DEPRECATION")
                            intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                        }
                        val rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE).toInt()

                        device?.let {
                            onDeviceFound(
                                DeviceInfo(
                                    name = it.name,
                                    address = it.address,
                                    bondState = it.bondState,
                                    bondStateText = getBondStateText(it.bondState),
                                    deviceClass = it.bluetoothClass?.deviceClass,
                                    deviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                                        it.type
                                    } else null,
                                    rssi = rssi,
                                    uuids = it.uuids?.map { uuid -> uuid.toString() }
                                )
                            )
                        }
                    }
                    BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
                        context.unregisterReceiver(this)
                        onScanFinished()
                    }
                }
            }
        }

        val filter = IntentFilter().apply {
            addAction(BluetoothDevice.ACTION_FOUND)
            addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
        }
        context.registerReceiver(receiver, filter)
        bluetoothAdapter?.startDiscovery()
    }

    /**
     * 扫描附近的BLE设备
     * 需要权限: BLUETOOTH_SCAN, ACCESS_FINE_LOCATION (Android 12+)
     * @param onDeviceFound 发现设备回调
     * @param durationMillis 扫描时长（毫秒）
     */
    @SuppressLint("MissingPermission")
    fun scanLeDevices(
        onDeviceFound: (DeviceInfo) -> Unit,
        durationMillis: Long = 10000
    ) {
        if (!checkBluetoothScanPermission() || !checkLocationPermission()) {
            return
        }

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) return

        val leScanner: BluetoothLeScanner? = bluetoothAdapter?.bluetoothLeScanner
        val scanCallback = object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                val device = result.device
                onDeviceFound(
                    DeviceInfo(
                        name = device.name,
                        address = device.address,
                        bondState = device.bondState,
                        bondStateText = getBondStateText(device.bondState),
                        deviceClass = device.bluetoothClass?.deviceClass,
                        deviceType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                            device.type
                        } else null,
                        rssi = result.rssi,
                        uuids = result.scanRecord?.serviceUuids?.map { it.toString() }
                    )
                )
            }
        }

        leScanner?.startScan(scanCallback)

        // 定时停止扫描
        android.os.Handler(android.os.Looper.getMainLooper()).postDelayed({
            leScanner?.stopScan(scanCallback)
        }, durationMillis)
    }

    /**
     * 停止设备扫描
     */
    @SuppressLint("MissingPermission")
    fun stopScan() {
        if (checkBluetoothScanPermission()) {
            bluetoothAdapter?.cancelDiscovery()
        }
    }

    // ==================== 蓝牙特性检测 ====================

    /**
     * 获取蓝牙特性信息
     */
    fun getBluetoothFeatures(): BluetoothFeatures {
        val adapter = bluetoothAdapter

        return BluetoothFeatures(
            version = getBluetoothVersion(),
            bluetoothLe = isBluetoothLeSupported,
            bluetooth = context.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH),

            // Bluetooth 4.x 特性
            le2MbPhy = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                adapter?.isLe2MPhySupported == true
            } else false,

            leCodedPhy = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                adapter?.isLeCodedPhySupported == true
            } else false,

            leExtendedAdvertising = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                adapter?.isLeExtendedAdvertisingSupported == true
            } else false,

            lePeriodicAdvertising = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                adapter?.isLePeriodicAdvertisingSupported == true
            } else false,

            // Bluetooth 5.x 特性
            bluetooth5Support = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                adapter?.isLe2MPhySupported == true ||
                adapter?.isLeCodedPhySupported == true ||
                adapter?.isLeExtendedAdvertisingSupported == true
            } else false,

            leAudioSupport = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                context.packageManager.hasSystemFeature("android.hardware.bluetooth.le.audio")
            } else false,

            leAudioBroadcast = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                context.packageManager.hasSystemFeature("android.hardware.bluetooth.le.audio.broadcast_source")
            } else false,

            leAudioUnicast = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
                context.packageManager.hasSystemFeature("android.hardware.bluetooth.le.audio.unicast_client")
            } else false,

            // 其他特性
            offloadedFiltering = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                adapter?.isOffloadedFilteringSupported == true
            } else false,

            offloadedScanBatching = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                adapter?.isOffloadedScanBatchingSupported == true
            } else false,

            multipleAdvertisement = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                adapter?.isMultipleAdvertisementSupported == true
            } else false,

            lowEnergyExtended = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                adapter?.isLeExtendedAdvertisingSupported == true
            } else false
        )
    }


    /**
     * 获取蓝牙版本（根据支持的特性推断）
     *
     * 版本判断依据：
     * - Bluetooth 5.4: Android 14+ 支持 LE Audio with LC3plus
     * - Bluetooth 5.3: Android 13+ 支持 LE Audio
     * - Bluetooth 5.2: Android 13+ 支持 LE Audio 基础功能
     * - Bluetooth 5.1: Android 10+ 支持方向查找
     * - Bluetooth 5.0: Android 8+ 支持 2Mbps PHY 或 Coded PHY
     * - Bluetooth 4.2: Android 6+ 支持 BLE
     * - Bluetooth 4.0: 支持 BLE
     * - Bluetooth 3.0 或更低: 仅支持经典蓝牙
     *
     * @return 蓝牙版本字符串
     */
    fun getBluetoothVersion(): String {
        val adapter = bluetoothAdapter ?: return "未知"

        return when {
            // Bluetooth 5.4+ (Android 14+, 支持 LC3plus 编解码器)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
                context.packageManager.hasSystemFeature("android.hardware.bluetooth.le.audio") ->
                "5.4"

            // Bluetooth 5.3 (Android 13+, 支持 LE Audio)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
                context.packageManager.hasSystemFeature("android.hardware.bluetooth.le.audio") ->
                "5.3"

            // Bluetooth 5.2 (Android 12+, 支持 LE Audio 基础功能)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
                context.packageManager.hasSystemFeature("android.hardware.bluetooth.le.audio") ->
                "5.2"

            // Bluetooth 5.1 (Android 10+, 支持方向查找)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q &&
                (adapter.isLe2MPhySupported || adapter.isLeCodedPhySupported ||
                 adapter.isLeExtendedAdvertisingSupported) ->
                "5.1"

            // Bluetooth 5.0 (Android 8+, 支持 2Mbps PHY 或 Coded PHY)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
                (adapter.isLe2MPhySupported || adapter.isLeCodedPhySupported) ->
                "5.0"

            // Bluetooth 4.2 (Android 6+, 支持增强的 BLE)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isBluetoothLeSupported ->
                "4.2"

            // Bluetooth 4.1 (Android 5+, 支持 BLE)
            Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && isBluetoothLeSupported ->
                "4.1"

            // Bluetooth 4.0 (Android 4.3+, 首次支持 BLE)
            isBluetoothLeSupported ->
                "4.0"

            // Bluetooth 3.0 或更低（仅经典蓝牙）
            else ->
                "3.0 或更低"
        }
    }

    /**
     * 获取详细的蓝牙版本信息（包含版本号和特性说明）
     *
     * @return 包含版本号和特性的详细字符串
     */
    fun getBluetoothVersionDetails(): String {
        val version = getBluetoothVersion()
        val features = getBluetoothFeatures()

        val details = buildString {
            append("蓝牙 $version")

            when {
                version.startsWith("5.4") || version.startsWith("5.3") -> {
                    append(" (")
                    append("LE Audio")
                    if (features.leAudioBroadcast) append(", 广播")
                    if (features.leAudioUnicast) append(", 单播")
                    if (features.le2MbPhy) append(", 2Mbps PHY")
                    if (features.leCodedPhy) append(", Coded PHY")
                    append(")")
                }
                version.startsWith("5.2") -> {
                    append(" (LE Audio, LE Power Control)")
                }
                version.startsWith("5.1") -> {
                    append(" (方向查找, GATT 缓存)")
                }
                version.startsWith("5.0") -> {
                    append(" (")
                    val bt5Features = mutableListOf<String>()
                    if (features.le2MbPhy) bt5Features.add("2Mbps PHY")
                    if (features.leCodedPhy) bt5Features.add("Coded PHY")
                    if (features.leExtendedAdvertising) bt5Features.add("扩展广播")
                    if (features.lePeriodicAdvertising) bt5Features.add("周期性广播")
                    append(bt5Features.joinToString(", "))
                    append(")")
                }
                version.startsWith("4") -> {
                    append(" (低功耗蓝牙)")
                }
            }
        }

        return details
    }

    /**
     * 获取蓝牙版本的数字格式
     *
     * @return 版本号（如 5.3, 5.0, 4.2 等），如果无法确定则返回 0.0
     */
    fun getBluetoothVersionNumber(): Double {
        val versionString = getBluetoothVersion()
        return when {
            versionString.startsWith("5.4") -> 5.4
            versionString.startsWith("5.3") -> 5.3
            versionString.startsWith("5.2") -> 5.2
            versionString.startsWith("5.1") -> 5.1
            versionString.startsWith("5.0") -> 5.0
            versionString.startsWith("4.2") -> 4.2
            versionString.startsWith("4.1") -> 4.1
            versionString.startsWith("4.0") -> 4.0
            versionString.startsWith("3") -> 3.0
            else -> 0.0
        }
    }

    // ==================== 权限检查 ====================

    /**
     * 所需权限列表
     */
    val requiredPermissions: Array<String>
        get() = buildList {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                add(Manifest.permission.BLUETOOTH_CONNECT)
                add(Manifest.permission.BLUETOOTH_SCAN)
            } else {
                add(Manifest.permission.BLUETOOTH)
                add(Manifest.permission.BLUETOOTH_ADMIN)
            }
            add(Manifest.permission.ACCESS_FINE_LOCATION)
        }.toTypedArray()

    /**
     * 检查蓝牙连接权限
     */
    private fun checkBluetoothConnectPermission(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.BLUETOOTH_CONNECT
            ) == PackageManager.PERMISSION_GRANTED
        } else {
            ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.BLUETOOTH
            ) == PackageManager.PERMISSION_GRANTED
        }
    }

    /**
     * 检查蓝牙扫描权限
     */
    private fun checkBluetoothScanPermission(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.BLUETOOTH_SCAN
            ) == PackageManager.PERMISSION_GRANTED
        } else {
            ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.BLUETOOTH_ADMIN
            ) == PackageManager.PERMISSION_GRANTED
        }
    }

    /**
     * 检查位置权限
     */
    private fun checkLocationPermission(): Boolean {
        return ActivityCompat.checkSelfPermission(
            context,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    }

    // ==================== 辅助方法 ====================

    /**
     * 获取配对状态文本
     */
    private fun getBondStateText(state: Int): String = when (state) {
        BluetoothDevice.BOND_NONE -> "未配对"
        BluetoothDevice.BOND_BONDING -> "正在配对"
        BluetoothDevice.BOND_BONDED -> "已配对"
        else -> "未知"
    }

    /**
     * 获取设备类型文本
     */
    fun getDeviceTypeText(type: Int?): String = when (type) {
        BluetoothDevice.DEVICE_TYPE_CLASSIC -> "经典蓝牙"
        BluetoothDevice.DEVICE_TYPE_LE -> "低功耗蓝牙"
        BluetoothDevice.DEVICE_TYPE_DUAL -> "双模蓝牙"
        else -> "未知"
    }

    /**
     * 获取文本格式的蓝牙信息摘要
     */
    fun text(): String {
        val sb = StringBuilder()

        // 基本信息
        sb.append("=== 蓝牙基本信息 ===\n")
        sb.append("适配器名称: ${adapterName ?: "未知"}\n")
        sb.append("MAC地址: ${adapterMacAddress ?: "未知"}\n")
        sb.append("状态: $stateText\n")
        sb.append("是否启用: ${if (isEnabled) "是" else "否"}\n")

        // 蓝牙特性
        val features = getBluetoothFeatures()
        sb.append("\n=== 蓝牙特性 ===\n")
        sb.append("蓝牙版本: ${features.version}\n")
        sb.append("经典蓝牙: ${if (features.bluetooth) "支持" else "不支持"}\n")
        sb.append("低功耗蓝牙: ${if (features.bluetoothLe) "支持" else "不支持"}\n")
        sb.append("Bluetooth 5: ${if (features.bluetooth5Support) "支持" else "不支持"}\n")
        sb.append("LE Audio: ${if (features.leAudioSupport) "支持" else "不支持"}\n")
        sb.append("2Mbps PHY: ${if (features.le2MbPhy) "支持" else "不支持"}\n")
        sb.append("Coded PHY: ${if (features.leCodedPhy) "支持" else "不支持"}\n")
        sb.append("扩展广播: ${if (features.leExtendedAdvertising) "支持" else "不支持"}\n")
        sb.append("周期性广播: ${if (features.lePeriodicAdvertising) "支持" else "不支持"}\n")

        // 已配对设备
        val bonded = getBondedDevicesInfo()
        sb.append("\n=== 已配对设备 (${bonded.size}) ===\n")
        bonded.forEach { device ->
            sb.append("设备: ${device.name ?: "未知"}\n")
            sb.append("  地址: ${device.address}\n")
            sb.append("  状态: ${device.bondStateText}\n")
            device.deviceType?.let {
                sb.append("  类型: ${getDeviceTypeText(it)}\n")
            }
        }

        return sb.toString()
    }
}
