package com.seer.teach.netty.im.handler.im.business;

import com.seer.teach.common.cache.DeviceMetricsCacheService;
import com.seer.teach.netty.common.proto.MessageProtobuf;
import com.seer.teach.netty.im.handler.im.ImMsgHandler;
import com.seer.teach.netty.im.manager.ImChannelManager;
import com.seer.teach.netty.im.registry.TvImMessageHandlerRegistry;
import com.seer.teach.netty.im.utils.ImUtils;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @Author: Captain
 * @Description:
 * @Date: 2025-05-20 17:29
 */
@Slf4j
@Component
@ChannelHandler.Sharable
@RequiredArgsConstructor
public class TvImBusinessHandler extends SimpleChannelInboundHandler<MessageProtobuf.Msg> {

    private final TvImMessageHandlerRegistry handlerRegistry;

    private final DeviceMetricsCacheService deviceMetricsCacheService;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MessageProtobuf.Msg msg) {
        String device = msg.getHead().getDevice();
        ImMsgHandler handler = handlerRegistry.getHandler(msg.getHead().getMsgType());
        if (handler != null) {
            handler.handleWithLog(ctx, msg);
            ImUtils.sendConfirmationOfAcceptanceMessageToDevice(device, msg);
        } else {
            log.warn("未处理的消息类型: MsgType:{},MsgContentType:{}", msg.getHead().getMsgType(),msg.getHead().getMsgContentType());
        }
    }

    /**
     * Author: Captain
     * Desc:   30秒心跳超时
     * Params: [ctx, evt]
     * Return: void
     * Time: 2025/5/17 17:38
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {
                log.warn("连接超时无心跳，关闭连接：{}", ImChannelManager.getDeviceByChannel(ctx.channel()));
                // 从UV统计中移除该设备
                String device = ImChannelManager.getDeviceByChannel(ctx.channel());
                deviceMetricsCacheService.invalidateMetric(device);
                // 移除管理器中的channel
                ImChannelManager.removeByChannel(ctx.channel());
                // 主动关闭连接
                ctx.close();
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

}
