package com.inzy.wsmock


import io.netty.channel.Channel
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame
import io.netty.util.AttributeKey
import org.springframework.stereotype.Component
import java.util.concurrent.ConcurrentHashMap

/**
 * Channel 全局管理类（单例）
 * 统一管理在线客户端Channel，提供增删查、分组等操作
 */
class ChannelManager private constructor() {
    // 存储在线客户端Channel（线程安全）
    private val onlineChannels = ConcurrentHashMap<String, Channel>()

    /**
     * 添加Channel（客户端连接时调用）
     */
    fun addChannel(channel: Channel) {
        val clientId = channel.id().asShortText()
        onlineChannels[clientId] = channel
        println("Channel添加成功：$clientId，当前在线数：${onlineChannels.size}")
    }

    /**
     * 移除Channel（客户端断开/异常时调用）
     */
    fun removeChannel(channel: Channel) {
        val clientId = channel.id().asShortText()
        onlineChannels.remove(clientId)
//        println("Channel移除成功：$clientId，当前在线数：${onlineChannels.size}")
    }

    /**
     * 根据客户端ID获取Channel
     */
    fun getChannel(clientId: String): Channel? {
        return onlineChannels[clientId]
    }

    /**
     * 获取所有在线Channel
     */
    fun getAllChannels(): ConcurrentHashMap<String, Channel> {
        return onlineChannels // 返回原对象（ConcurrentHashMap线程安全），或返回副本：ConcurrentHashMap(onlineChannels)
    }

    /**
     * 根据Channel的attr属性（CLIENT_TYPE_KEY）分组
     */
    fun groupChannelByType(typeKey: AttributeKey<String>): Map<String, List<Channel>> {
        val groupMap = mutableMapOf<String, MutableList<Channel>>()
        onlineChannels.forEach { (_, channel) ->
            // 获取Channel的type属性，默认值为"default"
            val type = channel.attr(typeKey).get() ?: "default"
            if (!groupMap.containsKey(type)) {
                groupMap[type] = mutableListOf()
            }
            // 仅保留活跃的Channel
            if (channel.isActive) {
                groupMap[type]?.add(channel)
            }
        }
        return groupMap
    }


    /***发送过滤好的通道**/
    fun sendMsgFromType(typeChannels: Map<String, Channel>, msg: String) {
        if (typeChannels.isEmpty()) {
//            println("无在线客户端，跳过推送")
            return
        }
        typeChannels.forEach { (clientId, channel) ->
            if (channel.isActive) {
                val frame = TextWebSocketFrame(msg)
                channel.writeAndFlush(frame)
                    .addListener { future ->
                        if (!future.isSuccess) {
                            println("推送消息给客户端[$clientId]失败：${future.cause()?.message}")
                            removeChannel(channel) // 推送失败移除失效Channel
                        }
                    }
            } else {
                removeChannel(channel) // 移除非活跃Channel
            }
        }
    }


    /**
     * 广播消息给所有在线客户端
     */
    /*   fun broadcastMsg(msg: String) {
           if (onlineChannels.isEmpty()) {
               println("无在线客户端，跳过推送")
               return
           }
           val frame = TextWebSocketFrame(msg)
           onlineChannels.forEach { (clientId, channel) ->
               if (channel.isActive) {
                   channel.writeAndFlush(frame)
                       .addListener { future ->
                           if (!future.isSuccess) {
                               println("推送消息给客户端[$clientId]失败：${future.cause()?.message}")
                               removeChannel(channel) // 推送失败移除失效Channel
                           }
                       }
               } else {
                   removeChannel(channel) // 移除非活跃Channel
               }
           }
           println("已向${onlineChannels.size}个客户端推送消息：$msg")
       }*/


    /**
     * 单例模式（饿汉式）
     */
    companion object {
        val instance: ChannelManager = ChannelManager()
//        val instance: ChannelManager by lazy { ChannelManager() }
    }
}