package uhf

import (
	"log"
	"wails-app/internal/global"
	"sync"
)

// ConnManager 全局多设备连接管理器（单例）
var ConnManager = &connManager{
	connMap: make(map[string]UHFReaderConn), // key: DeviceCode
}

type connManager struct {
	mu      sync.RWMutex // 读写锁，保证多协程安全
	connMap map[string]UHFReaderConn
	// 消息回调：设备收到数据后触发的处理函数（可自定义）
	recvCallback func(deviceCode string, data []byte)
}

// SetRecvCallback 设置全局消息接收回调
func (m *connManager) SetRecvCallback(callback func(deviceCode string, data []byte)) {
	m.recvCallback = callback
}

// AddConn 添加设备连接（多设备核心：按DeviceCode存储）
func (m *connManager) AddConn(deviceCode string, conn UHFReaderConn) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.connMap[deviceCode] = conn
	// 启动消息监听协程（异步接收设备数据）
	go m.listenDeviceData(deviceCode, conn)
	log.Printf("设备[%s]已加入连接池", deviceCode)
}

// GetConn 获取指定设备连接（多设备核心：按DeviceCode检索）
func (m *connManager) GetConn(deviceCode string) (UHFReaderConn, bool) {
	m.mu.RLock()
	defer m.mu.RUnlock()
	conn, ok := m.connMap[deviceCode]
	return conn, ok
}

// GetAllConns 获取所有设备连接（批量操作）
func (m *connManager) GetAllConns() map[string]UHFReaderConn {
	m.mu.RLock()
	defer m.mu.RUnlock()
	// 返回副本，避免外部修改原map
	copyMap := make(map[string]UHFReaderConn)
	for k, v := range m.connMap {
		copyMap[k] = v
	}
	return copyMap
}

// RemoveConn 移除设备连接
func (m *connManager) RemoveConn(deviceCode string) {
	m.mu.Lock()
	defer m.mu.Unlock()
	delete(m.connMap, deviceCode)
	log.Printf("设备[%s]已移出连接池", deviceCode)
}

// listenDeviceData 异步监听设备数据（多设备消息接收核心）
func (m *connManager) listenDeviceData(deviceCode string, conn UHFReaderConn) {
	for {
		// 检查连接是否有效
		if !conn.IsConnected() {
			log.Printf("设备[%s]连接已断开，停止监听", deviceCode)
			// 更新数据库状态
			//var device dao.UHFReader
			global.GVA_DB.Where("device_code = ?", deviceCode).Update("status", "offline")
			return
		}

		// 阻塞读取设备数据（TCP/串口统一通过ReadData读取）
		data, err := conn.ReadData() // 新增ReadData接口方法
		if err != nil {
			log.Printf("设备[%s]读取数据失败：%v", deviceCode, err)
			continue
		}

		// 空数据跳过
		if len(data) == 0 {
			continue
		}

		log.Printf("设备[%s]收到数据：%x", deviceCode, data)
		// 触发回调处理数据（业务层自定义逻辑）
		if m.recvCallback != nil {
			m.recvCallback(deviceCode, data)
		}
	}
}
