package com.narutohuo.xindazhou.ble.util

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.ScanFilter
import android.bluetooth.le.ScanResult
import android.bluetooth.le.ScanSettings
import android.content.Context
import android.os.Handler
import android.os.Looper
import com.narutohuo.xindazhou.core.log.ILog

/**
 * BLE扫描器
 * 
 * 负责 BLE 设备的扫描，返回符合过滤条件的 BluetoothDevice 列表
 * 使用 Android 12+ 推荐的 BluetoothLeScanner API
 */
class BleScanner(
    private val context: Context,
    private val onDeviceFound: (BluetoothDevice) -> Unit,
    private val onScanFinished: () -> Unit,
    private val filterDeviceName: String? = null,
    private val filterDeviceAddress: String? = null
) {
    
    private val tag = "BleScanner"
    
    private val bluetoothAdapter: BluetoothAdapter by lazy {
        val manager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        manager.adapter
    }
    
    private var scanner: BluetoothLeScanner? = null
    private var scanning = false
    
    private val scanCallback = object : ScanCallback() {
        override fun onScanResult(callbackType: Int, result: ScanResult) {
            val device = result.device
            if (device != null) {
                ILog.d(tag, "========== 发现设备 ==========")
                ILog.d(tag, "设备名称: ${device.name ?: "未知"}")
                ILog.d(tag, "设备地址: ${device.address}")
                ILog.d(tag, "RSSI: ${result.rssi}")
                ILog.d(tag, "扫描类型: $callbackType (1=CALLBACK_TYPE_ALL_MATCHES, 2=BATCH)")
                ILog.d(tag, "====================================")
                
                // 设备过滤（OR逻辑：名称匹配或地址匹配）
                val nameMatches = filterDeviceName?.let { 
                    device.name?.equals(it, ignoreCase = true) == true 
                } ?: false
                
                val addressMatches = filterDeviceAddress?.let { 
                    device.address.equals(it, ignoreCase = true) 
                } ?: false
                
                val shouldConnect = if (filterDeviceName != null || filterDeviceAddress != null) {
                    // 如果设置了过滤条件，则必须匹配（OR逻辑）
                    nameMatches || addressMatches
                } else {
                    // 如果没有设置过滤条件，则连接所有设备
                    true
                }
                
                if (shouldConnect) {
                    ILog.d(tag, "✅ 设备匹配过滤条件（名称匹配=$nameMatches, 地址匹配=$addressMatches），准备连接")
                    onDeviceFound(device)
                    stopScan()
                } else {
                    ILog.d(tag, "⏭️ 设备不匹配过滤条件，跳过")
                }
            }
        }
        
        override fun onBatchScanResults(results: List<ScanResult>) {
            ILog.d(tag, "批量扫描结果: ${results.size} 个设备")
            results.forEach {
                it.device?.let { device ->
                    ILog.d(tag, "发现设备: ${device.name ?: "未知"}, 地址: ${device.address}, RSSI: ${it.rssi}")
                    onDeviceFound(device)
                    stopScan()
                }
            }
        }
        
        override fun onScanFailed(errorCode: Int) {
            ILog.e(tag, "========== 扫描失败 ==========")
            ILog.e(tag, "错误码: $errorCode")
            ILog.e(tag, "1=SCAN_FAILED_ALREADY_STARTED, 2=SCAN_FAILED_APPLICATION_REGISTRATION_FAILED, 3=SCAN_FAILED_INTERNAL_ERROR, 4=SCAN_FAILED_FEATURE_UNSUPPORTED, 5=SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES")
            ILog.e(tag, "====================================")
            stopScan()
        }
    }
    
    /**
     * 开始扫描（默认 10 秒后自动停止）
     */
    @android.annotation.SuppressLint("MissingPermission")
    fun startScan(filterNamePrefix: String? = null, timeoutMs: Long = 10_000L) {
        ILog.d(tag, "========== 开始扫描 ==========")
        ILog.d(tag, "过滤前缀: ${filterNamePrefix ?: "无"}")
        ILog.d(tag, "超时时间: ${timeoutMs}ms")
        ILog.d(tag, "蓝牙适配器状态: ${if (bluetoothAdapter.isEnabled) "已开启" else "已关闭"}")
        ILog.d(tag, "====================================")
        
        if (scanning) {
            ILog.w(tag, "⚠️ 扫描已在进行中，忽略重复请求")
            return
        }
        
        if (!bluetoothAdapter.isEnabled) {
            ILog.e(tag, "❌ 蓝牙未开启，无法扫描")
            return
        }
        
        scanner = bluetoothAdapter.bluetoothLeScanner
        if (scanner == null) {
            ILog.e(tag, "❌ BluetoothLeScanner 为 null")
            return
        }
        
        val settings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .build()
        
        val filters = mutableListOf<ScanFilter>()
        filterNamePrefix?.let {
            filters.add(ScanFilter.Builder().setDeviceName(it).build())
            ILog.d(tag, "已设置设备名称过滤: $it")
        }
        
        try {
            scanner?.startScan(filters, settings, scanCallback)
            scanning = true
            ILog.d(tag, "✅ 扫描已启动，等待设备发现...")
            
            // 超时自动停止
            Handler(Looper.getMainLooper()).postDelayed({
                if (scanning) {
                    ILog.w(tag, "⏰ 扫描超时 (${timeoutMs}ms)，自动停止")
                    stopScan()
                }
            }, timeoutMs)
        } catch (e: SecurityException) {
            ILog.e(tag, "❌ 扫描权限不足", e)
            scanning = false
        } catch (e: Exception) {
            ILog.e(tag, "❌ 启动扫描失败", e)
            scanning = false
        }
    }
    
    /**
     * 停止扫描
     */
    @android.annotation.SuppressLint("MissingPermission")
    fun stopScan() {
        if (!scanning) {
            ILog.d(tag, "stopScan() 被调用，但未在扫描中")
            return
        }
        
        ILog.d(tag, "停止扫描...")
        
        try {
            scanner?.stopScan(scanCallback)
            scanning = false
            ILog.d(tag, "停止扫描")
            onScanFinished()
        } catch (e: SecurityException) {
            ILog.e(tag, "停止扫描权限不足", e)
        } catch (e: Exception) {
            ILog.e(tag, "停止扫描失败", e)
        }
    }
}

