package com.inspect.patrol.linkage.notify;

import com.alibaba.fastjson.JSONObject;
import com.inspect.base.core.exception.ServiceException;
import com.inspect.base.core.sftp.SftpClient;
import com.inspect.base.core.sftp.SftpUploadEntity;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.base.core.web.domain.AjaxResult;
import com.inspect.base.redis.service.RedisService;
import com.inspect.common.security.utils.DictUtils;
import com.inspect.patrol.annotation.FileNameAnnotation;
import com.inspect.patrol.contants.LinkageDeviceType;
import com.inspect.patrol.domain.LinkageAlarmNotifyEntity;
import com.inspect.patrol.domain.PatrolLinkagePos;
import com.inspect.patrol.domain.PatrolLinkageStrategy;
import com.inspect.patrol.domain.PatrolLinkageStrategyReverse;
import com.inspect.patrol.domain.PopupData;
import com.inspect.patrol.linkage.NettyUdpClient;
import com.inspect.patrol.linkage.block.CimeProcessor;
import com.inspect.patrol.linkage.block.ConfirmBlock;
import com.inspect.patrol.linkage.block.IBlock;
import com.inspect.patrol.linkage.block.ReverseBlock;
import com.inspect.patrol.linkage.constain.LinkageContain;
import com.inspect.patrol.linkage.processor.ReceiveProcessor;
import com.inspect.patrol.service.IPatrolLinkageMessageService;
import com.inspect.patrol.service.IPatrolLinkageStrategyReverseService;
import com.inspect.patrol.service.IPatrolLinkageStrategyService;
import com.inspect.patrol.service.PatrolTaskService;
import com.inspect.patrol.service.WebsocketService;
import com.inspect.patrol.service.impl.PatrolLinkagePosServiceImpl;
import com.inspect.system.base.domain.SysDictData;
import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;

import static com.inspect.patrol.linkage.constain.LinkageContain.*;

@ApiIgnore
@RestController
@RequestMapping({"/notify"})
public class LinkageNotify {
   private static final Logger logger = LoggerFactory.getLogger(LinkageNotify.class);
   @Autowired
   private NettyUdpClient nettyUdpClient;
   @Autowired
   private RedisService redisService;
   @Autowired
   private IPatrolLinkageMessageService iPatrolLinkageMessageService;
   @Autowired
   private SftpClient sftpClient;
   @Autowired
   private PatrolLinkagePosServiceImpl patrolLinkagePosServiceImpl;
   @Autowired
   private PatrolTaskService patrolTaskService;
   @Autowired
   private ReceiveProcessor receiveProcessor;
   @Autowired
   private IPatrolLinkageStrategyService patrolLinkageStrategyService;
   @Autowired
   private IPatrolLinkageStrategyReverseService patrolLinkageStrategyReverseService;
   @Value("${sftp.cime_store_path}")
   private String cimeStorePath;
   @Autowired
   private WebsocketService websocketService;

   @GetMapping
   public AjaxResult notify(String result) throws Exception {
      if(!this.redisService.redisTemplate.hasKey(REDIS_LINKAGE_TASK_DATA)) {
         return AjaxResult.success();
      } else {
         List<NotifyMessage> notifyMessages = JSONObject.parseArray(result, NotifyMessage.class);
         String taskId = notifyMessages.get(0).getTaskId();
         String data = (String)this.redisService.redisTemplate.opsForValue().get(REDIS_LINKAGE_TASK_DATA);
         PopupData popupData = JSONObject.parseObject(data, PopupData.class);
         if(!((List)popupData.getPopupInfoDataList().stream().map((item) -> {
            return item.getTaskId();
         }).collect(Collectors.toList())).contains(taskId)) {
            return AjaxResult.success();
         } else {
            PatrolLinkagePos patrolLinkagePos = popupData.getPatrolLinkagePos();
            PatrolLinkageStrategy patrolLinkageStrategy = (PatrolLinkageStrategy)patrolLinkagePos.getPatrolLinkageStrategies().get(0);
            String triggerSignalType = patrolLinkageStrategy.getTriggerSignalType();
            logger.info("==================联动结果通知：" + result);
            byte var11 = -1;
            switch(triggerSignalType.hashCode()) {
            case 49:
               if(triggerSignalType.equals("1")) {
                  var11 = 0;
               }
               break;
            case 50:
               if(triggerSignalType.equals("2")) {
                  var11 = 1;
               }
            }

            switch(var11) {
            case 0:
               logger.info("==================正向联动！");
               break;
            case 1:
               logger.info("==================一键顺控！");
               if("2".equals(patrolLinkageStrategy.getTriggerSignalType()) && LinkageDeviceType.CONTROL.getName().equals(patrolLinkagePos.getLinkageSignal())) {
                  logger.info("==================一键顺控-遥控结果返回！");
                  this.redisService.setCacheObject(REDIS_LINKAGE_CONFIRM_ACTION_RESULT, result);
                  this.redisService.expire(REDIS_LINKAGE_CONFIRM_ACTION_RESULT, 5L, TimeUnit.MINUTES);
                  return AjaxResult.success();
               }

               logger.info("==================一键顺控-遥信发送报文！");
               List<ConfirmBlock> confirmBlocks = this.queryConfirmBlockList(notifyMessages, patrolLinkageStrategy);
               String content = CimeProcessor.combine(confirmBlocks);
               this.sftpUpload(content, ConfirmBlock.class);
               this.iPatrolLinkageMessageService.insertPatrolLinkageMessage("1", content);
            }

            PopupResultMessage popupResultMessage = new PopupResultMessage(notifyMessages, popupData);
            this.sendByWebsocket(popupResultMessage.toResult());
            this.afterLinkage(popupData);
            logger.info("==================联动结束！");
            return AjaxResult.success();
         }
      }
   }

   @GetMapping({"signal"})
   public AjaxResult triggerSignal() throws Exception {
      String value = (String)this.redisService.redisTemplate.opsForList().rightPop("REDIS_LINKAGE_QUEUE");
      this.receiveProcessor.parseLinkageSignal((PatrolLinkagePos)JSONObject.parseObject(value, PatrolLinkagePos.class));
      return AjaxResult.success();
   }

   @PostMapping({"alarm"})
   public AjaxResult alarm(String type, String msg) {
      if(!StringUtils.isEmpty(msg) && "5".equals(type)) {
         logger.info("==================反向联动消息：" + msg);
         (new Thread(() -> {
            LinkageAlarmNotifyEntity linkageAlarmNotifyEntity = (LinkageAlarmNotifyEntity)JSONObject.parseObject(msg, LinkageAlarmNotifyEntity.class);
            PatrolLinkageStrategy param = new PatrolLinkageStrategy();
            param.setTriggerSignalType("3");
            List<PatrolLinkageStrategy> patrolLinkageStrategies = this.patrolLinkageStrategyService.selectPatrolLinkageStrategyList(param);
            List<String> alarmContents = linkageAlarmNotifyEntity.toItemContentList();
            Iterator var6 = patrolLinkageStrategies.iterator();

            while(var6.hasNext()) {
               PatrolLinkageStrategy strategy = (PatrolLinkageStrategy)var6.next();
               if(alarmContents.contains(strategy.getLinkageSignalName())) {
                  try {
                     PatrolLinkageStrategyReverse patrolLinkageStrategyReverse = new PatrolLinkageStrategyReverse();
                     patrolLinkageStrategyReverse.setLinkageStrategyId(strategy.getLinkageStrategyId());
                     List<PatrolLinkageStrategyReverse> list = this.patrolLinkageStrategyReverseService.selectPatrolLinkageStrategyReverseList(patrolLinkageStrategyReverse);
                     strategy.setPatrolLinkageStrategyReverses(list);
                     this.reverseLinkage(strategy);
                     break;
                  } catch (Exception var10) {
                     var10.printStackTrace();
                     throw new ServiceException("反向联动处理异常");
                  }
               }
            }

         })).start();
         return AjaxResult.success();
      } else {
         return AjaxResult.error("告警信息为空！");
      }
   }

   private void afterLinkage(PopupData popupData) {
      popupData.getPopupInfoDataList().forEach((item) -> {
         this.patrolTaskService.updateCameraPatrolTaskExecRecordState(item.getPatrolDeviceCode(), "2");
      });
      this.redisService.deleteObject(REDIS_LINKAGE_TASK_DATA);
      this.redisService.deleteObject(REDIS_LINKAGE_QUEUE_NOW);
   }

   public void reverseLinkage(PatrolLinkageStrategy patrolLinkageStrategy) throws Exception {
      List<ReverseBlock> reverseBlockList = this.queryReverseBlockList(patrolLinkageStrategy);
      String content = CimeProcessor.combine(reverseBlockList);
      this.sftpUpload(content, ReverseBlock.class);
      this.iPatrolLinkageMessageService.insertPatrolLinkageMessage("1", content);
   }

   public List<ReverseBlock> queryReverseBlockList(PatrolLinkageStrategy patrolLinkageStrategy) {
      List<PatrolLinkageStrategyReverse> patrolLinkageStrategyReverses = patrolLinkageStrategy.getPatrolLinkageStrategyReverses();
      List<PatrolLinkagePos> reversePatrolLinkagePosList = this.patrolLinkagePosServiceImpl.selectPatrolLinkagePosByIds((List)patrolLinkageStrategyReverses.stream().map((item) -> {
         return item.getLinkagePosId();
      }).collect(Collectors.toList()));
      List<ReverseBlock> reverseBlockList = new ArrayList();
      List<SysDictData> commandList = DictUtils.getDictCache("linkage_command");

      for(int i = 0; i < patrolLinkageStrategyReverses.size(); ++i) {
         PatrolLinkageStrategyReverse patrolLinkageStrategyReverse = (PatrolLinkageStrategyReverse)patrolLinkageStrategyReverses.get(i);
         PatrolLinkagePos reversePatrolLinkagePos = (PatrolLinkagePos)((List)reversePatrolLinkagePosList.stream().filter((item) -> {
            return item.getLinkagePosId().equals(patrolLinkageStrategyReverse.getLinkagePosId());
         }).collect(Collectors.toList())).get(0);
         ReverseBlock reverseBlock = new ReverseBlock();
         reverseBlock.setSerialNo(String.valueOf(i + 1));
         reverseBlock.setStationNo(String.valueOf(reversePatrolLinkagePos.getStationNo()));
         reverseBlock.setMonitorIndexNo(String.valueOf(reversePatrolLinkagePos.getMonitorIndexNo()));
         reverseBlock.setDeviceName(reversePatrolLinkagePos.getDeviceName());
         reverseBlock.setDeviceType("摇控");
         reverseBlock.setCommand(((SysDictData)((List)commandList.stream().filter((item) -> {
            return item.getDictValue().equals(patrolLinkageStrategyReverse.getCommand());
         }).collect(Collectors.toList())).get(0)).getDictLabel());
         reverseBlockList.add(reverseBlock);
      }

      return reverseBlockList;
   }

   public List<ConfirmBlock> queryConfirmBlockList(List<NotifyMessage> requestList, PatrolLinkageStrategy patrolLinkageStrategy) {
      List<ConfirmBlock> confirmBlocks = new ArrayList();

      for(int i = 0; i < requestList.size(); ++i) {
         NotifyMessage item = (NotifyMessage)requestList.get(i);
         ConfirmBlock confirmBlock = new ConfirmBlock();
         confirmBlock.setSerialNo(String.valueOf(i + 1));
         confirmBlock.setStationNo(patrolLinkageStrategy.getStationNo());
         confirmBlock.setDeviceName(patrolLinkageStrategy.getDeviceName());
         confirmBlock.setMonitorIndexNo(patrolLinkageStrategy.getMonitorIndexNo());
         confirmBlock.setDeviceStatus(item.toResult());
         confirmBlocks.add(confirmBlock);
      }

      return confirmBlocks;
   }

   private void sftpUpload(String cime, Class<? extends IBlock> clazz) throws Exception {
      SftpUploadEntity sftpUploadEntity = new SftpUploadEntity();
      FileNameAnnotation annotation = clazz.getAnnotation(FileNameAnnotation.class);
      sftpUploadEntity.setFileFullName(String.format("%s%s", this.cimeStorePath, annotation.value()));
      sftpUploadEntity.setInputStream(new ByteArrayInputStream(cime.getBytes("GB2312")));
      this.sftpClient.upload(sftpUploadEntity);
   }

   public void sendByWebsocket(List list) {
      if(!"0".equals(this.redisService.getCacheObject(LinkageContain.KEY_LINKAGE_ACTION_ANALYSIS))) {
         JSONObject jsonObject = (new JSONObject()).fluentPut(WEBSOCKET_PATH_KEY, WEBSOCKET_LINKAGE_RESULT).fluentPut("data", list);
         this.websocketService.parseMessage(JSONObject.toJSONString(jsonObject));
      }
   }
}
