package com.ruoyi.web.v2.server;


import com.ruoyi.web.v2.v1.model.ProtSj;
import com.ruoyi.web.v2.v1.service.IProtSjService;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static ch.qos.logback.core.encoder.ByteArrayUtil.hexStringToByteArray;


/**
 * @Project : huimv.shiwan
 * @Package : com.huimv.biosafety.uface.controller
 * @Description : TODO
 * @Version : 1.0
 * @Author : ZhuoNing
 * @Create : 2020-12-25
 **/
@ChannelHandler.Sharable
@Component
public class EnvInputServerHandler extends ChannelInboundHandlerAdapter {
    private static final Logger log = LoggerFactory.getLogger(EnvInputServerHandler.class);
    private StringBuilder askTextSb = null;

    @Autowired
    private IProtSjService protSjService;

    private Map<String, String> channelMap = new ConcurrentHashMap<>();

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        // 当客户端连接时，打印出客户端的 IP 地址
        System.out.println("连接成功");
        ByteBuf bufff = Unpooled.buffer();
        bufff.writeBytes(hexString2Bytes("5A000101000000DCE5"));
        ctx.writeAndFlush(bufff);
        super.channelActive(ctx);
    }

    // 设备数据的前缀
    private static final String DEVICE_PREFIX = "device:";
    private  static Integer INDEX = 1;
    //
    public void appendClientAsk(String text) {
        if (this.askTextSb == null) {
            askTextSb = new StringBuilder();
        }
        askTextSb.append(text);
    }

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    System.out.println("收到的数据：" + msg);

    if (msg instanceof ByteBuf) {
        ByteBuf byteBuf = (ByteBuf) msg;

        try {
            // 1. 打印原始十六进制数据（用于调试）
            String hexData = ByteBufUtil.hexDump(byteBuf);
            System.out.println("十六进制数据: " + hexData);

            // 2. 检查数据长度是否足够（假设每个参数占4字节，状态码占2字节）
            if (byteBuf.readableBytes() < 22) { // 5个浮点数(4*5=20) + 1个状态码(2) = 22字节
                System.err.println("数据长度不足！");
                return;
            }

            // 3. 读取数据到字节数组（方便解析）

            byte[] bytes = hexStringToByteArray(hexData.substring(14));

            // 4. 解析浮点数参数（IEEE 754，大端序）
            float cod = bytesToFloat(bytes, 0);       // 寄存器 0-1
            float ph = bytesToFloat(bytes, 4);        // 寄存器 2-3
            float flow = bytesToFloat(bytes, 8);      // 寄存器 4-5
            float ammonia = bytesToFloat(bytes, 12);   // 寄存器 6-7
            float phosphorus = bytesToFloat(bytes, 16);// 寄存器 8-9

            // 5. 解析状态码（16位有符号整数）
            int status = bytesToInt16(bytes, 20);     // 寄存器 10

            // 6. 打印解析结果
            System.out.println("解析结果：");
            System.out.println("COD: " + cod + " mg/L");
            System.out.println("pH: " + ph);
            System.out.println("流量: " + flow + " m³/h");
            System.out.println("氨氮: " + ammonia + " mg/L");
            System.out.println("总磷: " + phosphorus + " mg/L");

            protSjService.save(new ProtSj(cod+"",ph+"",flow+"",ammonia+"",phosphorus+"",new Date()));

        } finally {
            // 7. 释放 ByteBuf
            byteBuf.release();
        }
    }
}



    // 解析 IEEE 754 浮点数（4字节）
    private  float bytesToFloat(byte[] bytes, int offset) {
        return ByteBuffer.wrap(bytes, offset, 4)
                .order(ByteOrder.BIG_ENDIAN)
                .getFloat();
    }

    // 解析 16位有符号整数（2字节）
    private  int bytesToInt16(byte[] bytes, int offset) {
        return ByteBuffer.wrap(bytes, offset, 2)
                .order(ByteOrder.BIG_ENDIAN)
                .getShort();
    }



    public    boolean isStartOfToday(Date date) {
        // 创建一个示例的LocalDateTime对象
        LocalDateTime exampleTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
        // 获取今天的开始时间
        LocalDateTime todayStart = LocalDateTime.of(LocalDateTime.now().toLocalDate(), LocalTime.MIDNIGHT);

        // 比较给定的时间和今天的开始时间
        if (exampleTime.isAfter(todayStart)) {
            System.out.println("给定的时间大于今天的开始时间");
            return true;
        } else {
            System.out.println("给定的时间不大于今天的开始时间");
            return false;
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        String key = channel.id().asLongText(); // 或者使用其他唯一标识符
        System.out.println("退出-->"+key);
        channelMap.remove(key);
        super.channelInactive(ctx);
    }
    public static byte[] hexString2Bytes(String src) {

        int l = src.length() / 2;

        byte[] ret = new byte[l];

        for (int i = 0; i < l; i++) {

            ret[i] = (byte) Integer.valueOf(src.substring(i * 2, i * 2 + 2), 16).byteValue();

        }

        return ret;

    }





    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

//        if (true){
//            ctx.writeAndFlush(Unpooled.copiedBuffer(new byte[]{1, 2, 3}));
//        }

//        if (askTextSb.toString().indexOf("end") != -1) {
//            // {处理客户端消息}


//            handleClientAskCmd(askTextSb.toString(), ctx);
//            //清空重置;
//            askTextSb.delete(0, askTextSb.length());
//        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.err.println("发生异常: " + cause.getMessage());
        if (cause.getMessage().indexOf("Connection reset") != -1) {
            log.info("相关采集器设备正在重启:" + cause.toString());
        }
        ctx.close();
    }

    //应答
    public void answerCmd(String answerText, ChannelHandlerContext ctx) {
        ctx.writeAndFlush(Unpooled.copiedBuffer(answerText.getBytes()));
    }


}
