package com.ruoyi.web.core.nfid;

import com.ruoyi.app.model.NFIDReader;
import com.ruoyi.app.service.INFIDReaderService;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.HexUtil;
import com.ruoyi.common.utils.spring.SpringUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class ClientHandler extends ChannelInboundHandlerAdapter {


    private INFIDReaderService NFIDReaderService = SpringUtils.getBean(INFIDReaderService.class);

    private final AtomicInteger responseIndex = new AtomicInteger(1);

    private MultiReaderNFIDProcessor processor = SpringUtils.getBean(MultiReaderNFIDProcessor.class);

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        System.out.println("Client connected: " + ctx.channel().remoteAddress());

        // 识别器连接后发送读取识别器设备信息指令
        ByteBuf handshake = Unpooled.wrappedBuffer(HexUtil.hexToBytes("5A000101000000DCE5"));
        //识别器连接后发送读取标签指令
        sendReadResponseFrame(ctx);
        ctx.writeAndFlush(handshake);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            ByteBuf byteBuf = (ByteBuf) msg;
            byte[] bytes = new byte[byteBuf.readableBytes()];
            byteBuf.readBytes(bytes);

            // 解析帧
            List<NFIDFrameParser.NFIDFrame> frames = NFIDFrameParser.parseFrames(bytes);

            if (!frames.isEmpty()) {
                // 处理帧
                processFrames(ctx, frames,bytes);
            }
        } finally {
            ReferenceCountUtil.release(msg); // 释放ByteBuf
        }
    }

    private void processFrames(ChannelHandlerContext ctx, List<NFIDFrameParser.NFIDFrame> frames,byte[] bytes) {
        for (NFIDFrameParser.NFIDFrame frame : frames) {
            // 记录接收到的帧
           //System.out.println("Received frame: " + frame);

//            // 检查是否可以发送读取
//            if (NFIDFrameParser.isReadResponseRequiredFrame(frame)) {
//                //发送读取指令
//                sendReadResponseFrame(ctx);
//            }
            // 检查是否需要发送连接状态确认的响应
            if (NFIDFrameParser.isStatusResponseRequiredFrame(frame)) {
                //发送响应指令
                sendStatusResponseFrame(ctx,bytes);
            }

            // 检查是否读写器信息帧
            if (NFIDFrameParser.isDeviceInfoFrame(frame)) {
                // 首次连接时注册设备
                //if(!DeviceSessionManager.contains(ctx.channel())) {
                    //读取设备序列号
                    List<NFIDFrameParser.Parameter> params = frame.getParameters();
                    if (params != null && params.size() > 0) {
                        //字节转换成ascii
                        String DeviceId = new String(params.get(0).getValue(), StandardCharsets.US_ASCII);
                        DeviceSessionManager.registerDevice(ctx.channel(), DeviceId);
                        //更新识别器状态
                        updateNFIDReader(ctx,NFIDReader.STATUS_INLINE);
                    }
                //}
            }
            //检查是否为标签数据
            if (NFIDFrameParser.isTagInfoFrame(frame)) {
                List<NFIDFrameParser.Parameter> params = frame.getParameters();
                String tag = HexUtil.bytesToHex(params.get(0).getValue());
                //System.out.println("Tag: " + tag);
                if (params != null && params.size() > 0) {
                    String reader =  DeviceSessionManager.getDeviceId(ctx.channel());
                    if (reader !=null && !reader.equals("")) {
//                        System.out.println("天线："+ctx.channel().id().asLongText());
                        processor.receiveTag(tag, reader);
                    }
                }
            }
        }

        // 通知帧处理器
       // frameHandler.handleFrames(frames, ctx);
    }

    //向读写器发送读取指令
    private void sendReadResponseFrame(ChannelHandlerContext ctx) {
        int index = responseIndex.getAndUpdate(i -> i < 4 ? i + 1 : 1);
        byte[] response = NFIDFrameParser.generateReadResponseFrame(index);
        ctx.writeAndFlush(Unpooled.wrappedBuffer(response));
        System.out.println("Sent read response frame with index: " + index);
    }

    //向读写器发送状态确认指令
    private void sendStatusResponseFrame(ChannelHandlerContext ctx,byte[] bytes) {
        ctx.writeAndFlush(Unpooled.wrappedBuffer(bytes));
       // System.out.println("Sent status confirm response frame" );
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("Client disconnected: " + ctx.channel().remoteAddress());

        //更新识别器状态
        updateNFIDReader(ctx,NFIDReader.STATUS_OFFLINE);

        //断开则取消注册
        DeviceSessionManager.unregister(ctx.channel());
        ctx.fireChannelInactive();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.err.println("Error in client handler: " + cause.getMessage());

        //更新识别器状态
        updateNFIDReader(ctx,NFIDReader.STATUS_ERROR);

        ctx.close();
    }

    //更新识别器
    private int updateNFIDReader(ChannelHandlerContext ctx, String status){
        NFIDReader NFIDReader = new NFIDReader();
        String deviceId = DeviceSessionManager.getDeviceId(ctx.channel());
        if(deviceId == null || deviceId.isEmpty()){
            return 0;
        }
        NFIDReader.setDeviceSerial(deviceId);
        NFIDReader.setLastActiveTime(DateUtils.getNowDate());
        NFIDReader.setStatus(status);
        return NFIDReaderService.updateNFIDReaderBySerial(NFIDReader);
    }

}
