package com.youchain.Netty;

import cn.hutool.json.JSONUtil;
import com.youchain.basicdata.domain.Box;
import com.youchain.basicdata.repository.BoxRepository;
import com.youchain.basicdata.service.BoxService;
import com.youchain.basicdata.service.dto.BoxDto;
import com.youchain.basicdata.service.dto.BoxQueryCriteria;
import com.youchain.basicdata.service.impl.BoxServiceImpl;
import com.youchain.basicdata.service.impl.BoxServiceImpl;
import com.youchain.basicdata.service.mapstruct.BoxMapper;
import com.youchain.domain.Log;
import com.youchain.exception.handler.ApiResult;
import com.youchain.service.impl.LogServiceImpl;
import com.youchain.utils.RedisUtils;
import com.youchain.utils.SpringContextHolder;
import com.youchain.utils.StringUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.net.InetSocketAddress;
import java.util.List;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.OK;

@Slf4j
public class ServerListenerHandler extends SimpleChannelInboundHandler<String> {


    public static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);


    /**
     * 设备接入连接时处理
     *
     * @param ctx
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        String ip =((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress();
        log.info("有新的连接：[{}]", ip);
        Channel lastClient=NettyUtils.getChannel(ip);
        if(lastClient!=null){
            log.info("当前IP有旧的连接,移除旧的的连接：[{}]", ip);
            clients.remove(lastClient);
        }
        clients.add(ctx.channel());


    }

    /**
     * 数据处理
     *
     * @param ctx
     * @param content
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String content) {
        String ip =((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress();
        // 获取消息实例中的消息体
        // 对不同消息类型进行处理
        //00 00 /00 00 /00 0C /00 /07 /00 00 00 00 00 00 00 00 00 01
        //4位通讯帧号
        //4位通讯协议
        //4位数据长度（在这后面的总长度）
        //2位设备地址 00
        //2位功能码 07 心跳数据
        //16 位  按钮1-按钮8 的状态
        //4位数据 呼叫器编号

        String key="TCP"+ip;

        if(content.length()==36){
            RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class);

            int time=(int) redisUtils.get(key,10);

            if(time>=10000){
                time=10;
            }

            redisUtils.set(key,time+1);

            if(time%8==0){
                StringBuffer buff=new StringBuffer();
                buff.append("0000");//通讯帧数
                buff.append("0000");//协议类型
                buff.append("0006");//长度
                buff.append("01");//设备地址
                buff.append("03");//读取数据
                buff.append("0001");//读取目标数据的起始地址
                buff.append("0008");//读取目标寄存器的数量
                NettyUtils.writeToClient(null,buff.toString(),ctx.channel(),"读取设备状态");
            }

            log.info("心跳内容" + content);
            String bt1=content.substring(16,18);
            String bt2=content.substring(18,20);
            String bt3=content.substring(20,22);
            String bt4=content.substring(22,24);



//            if("01".equals(bt1)){
//                ClickButton(redisUtils,content,ip,NettyUtils.button_1,NettyUtils.light_1);
//            }
//            if("01".equals(bt2)){
//                ClickButton(redisUtils,content,ip,NettyUtils.button_2,NettyUtils.light_2);
//            }
//            if("01".equals(bt3)){
//                ClickButton(redisUtils,content,ip,NettyUtils.button_3,NettyUtils.light_3);
//            }
//            if("01".equals(bt4)){
//                ClickButton(redisUtils,content,ip,NettyUtils.button_4,NettyUtils.light_4);
//            }

        } else{
            log.info("其他消息内容" + content);
        }

    }


//    public void ClickButton(RedisUtils redisUtils,String content,String ip,String ButtonCode,String LightCode){
//        log.info(ButtonCode+"按钮 被按下");
//        //读取bt_key
//        String bt_key="TCP"+ip+ButtonCode;
//        if ((Boolean) redisUtils.get(bt_key,false)) {
//            log.error("{}正在执行...",bt_key);
//            return;
//        }
//        //写入key 为Tue
//        redisUtils.set(bt_key,true,120);
//        //加载操作数据库
//        LampLogRepository lampLogRepository = SpringContextHolder.getBean(LampLogRepository.class);
//        LampLogServiceImpl bean = SpringContextHolder.getBean(LampLogServiceImpl.class);
//        BoxRepository bean1 = SpringContextHolder.getBean(BoxRepository.class);
//        //插入日志
//        LampLog lampLog = new LampLog();
//        lampLog.setIp(ip);//插入ip
//        lampLog.setButtonCode(ButtonCode);
//        lampLog.setRequestContent(content);
//        lampLog.setReturnState(ButtonCode+"被按下");
//        //获取盒子号
//        log.info("ButtonBoxCode:"+ip + ButtonCode+"====");
//        Object buttonBoxCode = redisUtils.hget("ButtonBoxCode", ip + ButtonCode,"")+"";
//        if ("".equals(buttonBoxCode)){
//            log.info("ButtonBoxCode为空:"+ip + ButtonCode+"====");
//            List<Box> boxAllData = bean1.getBoxAllData();
//            for (Box box:boxAllData){
//                redisUtils.hset("ButtonBoxCode",box.getIP()+box.getLampCode(),box.getCode(),60);
//            }
//            lampLog.setButtonBox(redisUtils.hget("ButtonBoxCode", ip + ButtonCode,"")+"");
//            log.info("ButtonBoxCode重新从redis获取:"+ip + ButtonCode+"====lampLog"+lampLog.getButtonBox()+"是否正确");
//        }else {
//            log.info("ButtonBoxCode不为空:"+buttonBoxCode.toString()+"====");
//            lampLog.setButtonBox(buttonBoxCode.toString());
//        }
//        lampLog.setOperationType("自动");
//        //插入日志
//        LampLog save = lampLogRepository.save(lampLog);
//        //先亮灯
//        NettyUtils.light_on(ip,LightCode,save.getId());
//        bean1.updateBoxLampStatus(ip,ButtonCode,"1");
//        //处理业务
//        String boxCode=lampLog.getButtonBox();
//        if(boxCode!=null&&!boxCode.equals("")) {
//            this.buttonService(boxCode);//按钮3的业务处理
//        }
//        save.setReturnContent((String) redisUtils.get(String.valueOf(save.getId())));
//        //修改日志
//        bean.update(save);
//        //释放按钮 修改Key为False
//        redisUtils.del(String.valueOf(save.getId()));
//        NettyUtils.button_off(ip,ButtonCode,save.getId());
//        redisUtils.set(bt_key,false);
//
//    }


    /**
     * 设备下线处理
     *
     * @param ctx
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {

        String ip =((InetSocketAddress)ctx.channel().remoteAddress()).getAddress().getHostAddress();

        clients.remove(ctx.channel());
        log.info("设备下线了:{}", ip);
    }

    /**
     * 设备连接异常处理
     *
     * @param ctx
     * @param cause
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // 打印异常
        log.info("异常：{}", cause.getMessage());
        // 关闭连接
        ctx.close();
        clients.remove(ctx.channel());
    }

    //按钮1 的业务
    public ResponseEntity<Object> buttonService(String buttonBoxCode){
       log.info("WMS按钮"+buttonBoxCode+"的业务......");
       BoxServiceImpl bsi = SpringContextHolder.getBean(BoxServiceImpl.class);
       BoxMapper bm= SpringContextHolder.getBean(BoxMapper.class);
       BoxQueryCriteria bqc=new BoxQueryCriteria();
       bqc.setCode(buttonBoxCode);
       List<BoxDto> bds=bsi.queryAll(bqc);
       if(bds.size()>0){
           BoxDto b=bds.get(0);
           try {
               log.info("进来WMS按钮的业务......");
//               bsi.callBox(b);
           } catch (Exception e) {
               Log log_data=new Log();
               log_data.setRequestIp(b.getIP());
               log_data.setUsername("按钮盒设备:"+b.getLampCode());
               log_data.setDescription("按钮盒设备业务处理");
               log_data.setLogType("ERROR");
               log_data.setReturnData(e.getMessage());
               LogServiceImpl lsi = SpringContextHolder.getBean(LogServiceImpl.class);
               lsi.saveLog(log_data);
               log.error("灯日志"+e.getMessage());
               Box box=bm.toEntity(b);
               box.setLampStatus("0");
               bsi.update(box);
               return new ResponseEntity<>(ApiResult.success(BAD_REQUEST.value(), e.getMessage(), ""), HttpStatus.BAD_REQUEST);
           }
           return new ResponseEntity<>(ApiResult.success(OK.value(), "呼叫成功!", ""), HttpStatus.OK);
       }else{
           return new ResponseEntity<>(ApiResult.success(BAD_REQUEST.value(), "找不到对应的按钮数据", ""), HttpStatus.BAD_REQUEST);
       }
    }

}

