package com.njcn.gather.detection.util.socket.cilent;

import cn.hutool.core.util.StrUtil;
import com.njcn.gather.detection.handler.SocketFreqConverterService;
import com.njcn.gather.detection.util.socket.FormalTestManager;
import com.njcn.gather.detection.util.socket.SocketManager;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

/**
 * 变频器Netty客户端处理器
 */
@Slf4j
public class NettyFreqConverterClientHandler extends SimpleChannelInboundHandler<String> {

    /**
     * 变频器Channel唯一标识符
     */
    private final String converterChannelTag;


    /**
     * 变频器Socket响应服务
     */
    private final SocketFreqConverterService socketFreqConverterService;

    /**
     * 重连次数
     */
    private int reconnectAttempts = 0;

    /**
     * 最大重连次数
     */
    private static final int MAX_RECONNECT_ATTEMPTS = 3;

    /**
     * 重连间隔（毫秒）
     */
    private static final long RECONNECT_INTERVAL_MS = 5000;

    /**
     * 是否正在重连
     */
    private volatile boolean isReconnecting = false;

    /**
     * 构造方法
     *
     * @param converterChannelTag        变频器Chanel唯一标识符
     * @param socketFreqConverterService 变频器Socket响应服务
     */
    public NettyFreqConverterClientHandler(String converterChannelTag, SocketFreqConverterService socketFreqConverterService) {
        this.converterChannelTag = converterChannelTag;
        this.socketFreqConverterService = socketFreqConverterService;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("变频器连接已建立，converterChannelTag={},  channelId={}", converterChannelTag, ctx.channel().id());

        // 注册Channel到SocketManager
        SocketManager.addUser(converterChannelTag, ctx.channel());

        if (reconnectAttempts > 0) {
            log.info("变频器重连成功，converterChannelTag={}, 重连次数={}", converterChannelTag, reconnectAttempts);
            reconnectAttempts = 0;
            isReconnecting = false;
            socketFreqConverterService.onReconnectSuccess(converterChannelTag);
        }

        super.channelActive(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        if (StrUtil.isBlank(msg)) {
            log.debug("收到空消息，忽略，converterChannelTag={}", converterChannelTag);
            return;
        }

        log.info("收到变频器消息，converterChannelTag={}, msg={}", converterChannelTag, msg);

        // 处理状态数据
        socketFreqConverterService.handleRead(converterChannelTag, msg);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.warn("变频器连接已断开，converterChannelTag={}", converterChannelTag);

        socketFreqConverterService.cleanup(converterChannelTag);

        if (!isReconnecting && reconnectAttempts < MAX_RECONNECT_ATTEMPTS && !FormalTestManager.isRemoveSocket) {
            attemptReconnect(ctx);
        } else if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
            log.error("变频器重连失败，已达到最大重连次数{}次，converterChannelTag={}", MAX_RECONNECT_ATTEMPTS, converterChannelTag);
        }

        super.channelInactive(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("变频器连接发生异常，converterChannelTag={}, error={}", converterChannelTag, cause.getMessage(), cause);
        ctx.close();
    }

    @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("变频器连接读空闲，converterChannelTag={}", converterChannelTag);
                // 可以选择发送心跳或关闭连接
            }
        }
        super.userEventTriggered(ctx, evt);
    }

    private void attemptReconnect(ChannelHandlerContext ctx) {
        isReconnecting = true;
        reconnectAttempts++;

        log.info("准备重连变频器，converterChannelTag={}, 第{}/{}次重连，{}秒后开始",
                converterChannelTag, reconnectAttempts, MAX_RECONNECT_ATTEMPTS, RECONNECT_INTERVAL_MS / 1000);

        ctx.executor().schedule(() -> {
            try {
                log.info("开始执行变频器重连，converterChannelTag={}", converterChannelTag);
                socketFreqConverterService.reconnect(converterChannelTag);
            } catch (Exception e) {
                log.error("变频器重连触发失败，converterChannelTag={}, error={}", converterChannelTag, e.getMessage(), e);
                isReconnecting = false;

                if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
                    log.warn("将在{}秒后进行下一次重试", RECONNECT_INTERVAL_MS / 1000);
                    ctx.executor().schedule(() -> attemptReconnect(ctx), RECONNECT_INTERVAL_MS, java.util.concurrent.TimeUnit.MILLISECONDS);
                }
            }
        }, RECONNECT_INTERVAL_MS, java.util.concurrent.TimeUnit.MILLISECONDS);
    }
}

