package com.bonus.core.device.manage.vo;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.bonus.constant.SourceTypeEnum;
import com.bonus.core.common.utils.SysUtil;
import com.bonus.core.device.manage.model.DeviceBind;
import com.bonus.core.device.manage.model.DeviceDishes;
import com.bonus.core.device.manage.model.DeviceInfo;
import com.bonus.core.device.manage.model.DeviceRecipe;
import com.bonus.core.device.manage.strategy.DeviceStrategy;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.annotations.ApiModelProperty;

import java.util.List;
import java.util.Map;
import java.util.Objects;

public class DeviceInfoVO {
   @ApiModelProperty("主键id")
   private Long deviceId;
   @ApiModelProperty("生效范围id")
   private Long effId;
   @ApiModelProperty("设备sn码")
   private String deviceSn;
   @ApiModelProperty("设备名称")
   private String deviceName;
   @ApiModelProperty("设备编号")
   private String deviceNum;
   @ApiModelProperty("设备型号")
   private String deviceModel;
   @ApiModelProperty("设备类型")
   private Integer deviceType;
   @ApiModelProperty("设备密码")
   private String devicePwd;
   @ApiModelProperty("设备安装地址")
   private String deviceAddr;
   @ApiModelProperty("设备key")
   private String deviceKey;
   @ApiModelProperty("关联设备id")
   private Long deviceParentId;
   @ApiModelProperty("关联父设备类型")
   private String deviceParentType;
   @ApiModelProperty("版本号（MQTT上报）")
   private Integer versionCode;
   @ApiModelProperty("版本名称（MQTT上报）")
   private String versionName;
   @ApiModelProperty("设备在线状态 1在线 2离线（MQTT上报）")
   private Integer onlineState;
   @ApiModelProperty("消费模式(扣费模式)")
   private Integer consumMode;
   @ApiModelProperty("通讯模式")
   private Integer commMode;
   @ApiModelProperty("通信协议")
   private Integer deviceAgreement;
   @ApiModelProperty("设备ip")
   private String deviceIp;
   @ApiModelProperty("子网掩码")
   private String deviceMask;
   @ApiModelProperty("设备mac")
   private String deviceMac;
   @ApiModelProperty("网关")
   private String deviceGateway;
   @ApiModelProperty("首选dns")
   private String firstDns;
   @ApiModelProperty("备选dns")
   private String nextDns;
   @ApiModelProperty("是否限额")
   private Integer ifQuotaLimit;
   @ApiModelProperty("是否打折")
   private Integer ifDiscount;
   @ApiModelProperty("是否限次")
   private Integer ifTimeLimit;
   @ApiModelProperty("是否启用叫号")
   private Integer ifUseCallNum;
   @ApiModelProperty("设备是否启用 1-是 2-否")
   private Integer ifEnable;
   @ApiModelProperty("图片地址（当mch_type为40 时，该字段表示背景图）")
   private String imgUrl;
   @ApiModelProperty("账户余额不足多少提醒")
   private Integer amountNotify;
   @ApiModelProperty("餐盘绑定有效时间")
   private Integer bindingValidTime;
   @ApiModelProperty("订单自动结算时间")
   private Integer ordAutomaticPay;
   @ApiModelProperty("是否允许离线消费")
   private Integer ifOffLinePay;
   @ApiModelProperty("报警时长")
   private Integer alarmTime;
   @ApiModelProperty("勺子重量")
   private Integer spoonWeight;
   @ApiModelProperty("心跳包时间(电子菜排)")
   private Long heartBeatTime;
   @ApiModelProperty("轮播播放时间(电子菜排)")
   private Long carouselTime;
   @ApiModelProperty("字幕标语(电子菜排)")
   private String titleSlogan;
   @ApiModelProperty("字体大小(电子菜排)")
   private Integer fontSize;
   @ApiModelProperty("字体颜色，默认黑色")
   private String fontColor;
   @ApiModelProperty("界面样式(电子菜排)")
   private Integer guiStyle;
   @ApiModelProperty("设备背景或轮播图片")
   private JsonNode imageMap;
   @ApiModelProperty("字体行数")
   private Integer lineNum;
   @ApiModelProperty("刷脸设备单次扣款金额")
   private Integer oncePayAmount;
   @ApiModelProperty("设备数据传输状态，1-传输完毕， 0-传输中")
   private Integer dataStatus;
   @ApiModelProperty("单笔订单开门数量")
   private Integer ordOpenLimit;
   @ApiModelProperty("单个柜门存单上限")
   private Integer detailNumLimit;
   @ApiModelProperty("第三方终端sn")
   private String terminalSn;
   @ApiModelProperty("第三方终端秘钥")
   private String terminalKey;
   @ApiModelProperty("打印机状态 1、离线。rn   * 2、在线，工作状态正常。rn   * 3、在线，工作状态不正常。")
   private Integer priStatus;
   @ApiModelProperty("打印机key")
   private String priKey;
   @ApiModelProperty("闸机默认消费金额")
   private Integer gateDefaultAmount;
   @ApiModelProperty("设备时间校准心跳缓存（非MQTT设备）")
   private String heartbeatStateCache;
   @ApiModelProperty("设备通讯状态 1在线 2离线")
   private String deviceState = "2";
   @ApiModelProperty("绑定关系")
   private List<BindVO> bindList;
   @ApiModelProperty("菜谱信息")
   private List<RecipeVO> recipeList;
   @ApiModelProperty("菜品信息")
   private List<DishesVO> dishesList;
   @ApiModelProperty("设备基础设置")
   private Map deviceMetadata;
   @ApiModelProperty("设备绑定食堂")
   private Long firstCanteenId;
   @ApiModelProperty("设备绑定食堂")
   private Long firstShopstallId;

   public String getDeviceState() {
      if (!DeviceStrategy.supportsMQTT(this.deviceType, this.versionCode)) {
         return StrUtil.isNotEmpty(this.heartbeatStateCache) ? "1" : "2";
      } else {
         return this.onlineState != null && this.onlineState == 1 ? "1" : "2";
      }
   }

   public static DeviceInfoVO of(DeviceInfo deviceInfo, List<DeviceBind> bindList, List<DeviceRecipe> recipeList, List<DeviceDishes> dishesList, Map deviceMetadata) {
      DeviceInfoVO vo = new DeviceInfoVO();
      BeanUtil.copyProperties(deviceInfo, vo, new String[0]);
      vo.setBindList((List)(CollUtil.isNotEmpty(bindList) ? BeanUtil.copyToList(bindList, BindVO.class) : CollUtil.newArrayList(new BindVO[0])));
      vo.setRecipeList((List)(CollUtil.isNotEmpty(recipeList) ? BeanUtil.copyToList(recipeList, RecipeVO.class) : CollUtil.newArrayList(new RecipeVO[0])));
      vo.setDishesList((List)(CollUtil.isNotEmpty(dishesList) ? BeanUtil.copyToList(dishesList, DishesVO.class) : CollUtil.newArrayList(new DishesVO[0])));
      vo.setDeviceMetadata(deviceMetadata);
      return vo;
   }

   public String getImgUrl() {
      return SysUtil.getCutFileUrl(this.imgUrl);
   }

   public Long getFirstCanteenId() {
      return (Long)ListUtil.toList(this.bindList).stream().map(BindVO::getCanteenId).filter(Objects::nonNull).findFirst().orElse((Long) null);
   }

   public Long getFirstShopstallId() {
      return (Long)ListUtil.toList(this.bindList).stream().map(BindVO::getStallId).filter(Objects::nonNull).findFirst().orElse((Long) null);
   }

   public Long getFirstRecipeId() {
      return (Long)ListUtil.toList(this.getRecipeList()).stream().map(RecipeVO::getRecipeId).filter(Objects::nonNull).findFirst().orElse((Long) null);
   }

   public String getDeviceModel() {
      if (ObjectUtil.isNotEmpty(this.deviceMetadata) && ObjectUtil.equals(SourceTypeEnum.AUTONOMOUS_WEIGHING.getKey(), this.deviceType)) {
         return this.deviceMetadata.getOrDefault("weighScaleModel", "").toString().equals("2") ? "3" : "2";
      } else {
         return this.deviceModel;
      }
   }

   public Long getDeviceId() {
      return this.deviceId;
   }

   public Long getEffId() {
      return this.effId;
   }

   public String getDeviceSn() {
      return this.deviceSn;
   }

   public String getDeviceName() {
      return this.deviceName;
   }

   public String getDeviceNum() {
      return this.deviceNum;
   }

   public Integer getDeviceType() {
      return this.deviceType;
   }

   public String getDevicePwd() {
      return this.devicePwd;
   }

   public String getDeviceAddr() {
      return this.deviceAddr;
   }

   public String getDeviceKey() {
      return this.deviceKey;
   }

   public Long getDeviceParentId() {
      return this.deviceParentId;
   }

   public String getDeviceParentType() {
      return this.deviceParentType;
   }

   public Integer getVersionCode() {
      return this.versionCode;
   }

   public String getVersionName() {
      return this.versionName;
   }

   public Integer getOnlineState() {
      return this.onlineState;
   }

   public Integer getConsumMode() {
      return this.consumMode;
   }

   public Integer getCommMode() {
      return this.commMode;
   }

   public Integer getDeviceAgreement() {
      return this.deviceAgreement;
   }

   public String getDeviceIp() {
      return this.deviceIp;
   }

   public String getDeviceMask() {
      return this.deviceMask;
   }

   public String getDeviceMac() {
      return this.deviceMac;
   }

   public String getDeviceGateway() {
      return this.deviceGateway;
   }

   public String getFirstDns() {
      return this.firstDns;
   }

   public String getNextDns() {
      return this.nextDns;
   }

   public Integer getIfQuotaLimit() {
      return this.ifQuotaLimit;
   }

   public Integer getIfDiscount() {
      return this.ifDiscount;
   }

   public Integer getIfTimeLimit() {
      return this.ifTimeLimit;
   }

   public Integer getIfUseCallNum() {
      return this.ifUseCallNum;
   }

   public Integer getIfEnable() {
      return this.ifEnable;
   }

   public Integer getAmountNotify() {
      return this.amountNotify;
   }

   public Integer getBindingValidTime() {
      return this.bindingValidTime;
   }

   public Integer getOrdAutomaticPay() {
      return this.ordAutomaticPay;
   }

   public Integer getIfOffLinePay() {
      return this.ifOffLinePay;
   }

   public Integer getAlarmTime() {
      return this.alarmTime;
   }

   public Integer getSpoonWeight() {
      return this.spoonWeight;
   }

   public Long getHeartBeatTime() {
      return this.heartBeatTime;
   }

   public Long getCarouselTime() {
      return this.carouselTime;
   }

   public String getTitleSlogan() {
      return this.titleSlogan;
   }

   public Integer getFontSize() {
      return this.fontSize;
   }

   public String getFontColor() {
      return this.fontColor;
   }

   public Integer getGuiStyle() {
      return this.guiStyle;
   }

   public JsonNode getImageMap() {
      return this.imageMap;
   }

   public Integer getLineNum() {
      return this.lineNum;
   }

   public Integer getOncePayAmount() {
      return this.oncePayAmount;
   }

   public Integer getDataStatus() {
      return this.dataStatus;
   }

   public Integer getOrdOpenLimit() {
      return this.ordOpenLimit;
   }

   public Integer getDetailNumLimit() {
      return this.detailNumLimit;
   }

   public String getTerminalSn() {
      return this.terminalSn;
   }

   public String getTerminalKey() {
      return this.terminalKey;
   }

   public Integer getPriStatus() {
      return this.priStatus;
   }

   public String getPriKey() {
      return this.priKey;
   }

   public Integer getGateDefaultAmount() {
      return this.gateDefaultAmount;
   }

   public String getHeartbeatStateCache() {
      return this.heartbeatStateCache;
   }

   public List<BindVO> getBindList() {
      return this.bindList;
   }

   public List<RecipeVO> getRecipeList() {
      return this.recipeList;
   }

   public List<DishesVO> getDishesList() {
      return this.dishesList;
   }

   public Map getDeviceMetadata() {
      return this.deviceMetadata;
   }

   public void setDeviceId(final Long deviceId) {
      this.deviceId = deviceId;
   }

   public void setEffId(final Long effId) {
      this.effId = effId;
   }

   public void setDeviceSn(final String deviceSn) {
      this.deviceSn = deviceSn;
   }

   public void setDeviceName(final String deviceName) {
      this.deviceName = deviceName;
   }

   public void setDeviceNum(final String deviceNum) {
      this.deviceNum = deviceNum;
   }

   public void setDeviceModel(final String deviceModel) {
      this.deviceModel = deviceModel;
   }

   public void setDeviceType(final Integer deviceType) {
      this.deviceType = deviceType;
   }

   public void setDevicePwd(final String devicePwd) {
      this.devicePwd = devicePwd;
   }

   public void setDeviceAddr(final String deviceAddr) {
      this.deviceAddr = deviceAddr;
   }

   public void setDeviceKey(final String deviceKey) {
      this.deviceKey = deviceKey;
   }

   public void setDeviceParentId(final Long deviceParentId) {
      this.deviceParentId = deviceParentId;
   }

   public void setDeviceParentType(final String deviceParentType) {
      this.deviceParentType = deviceParentType;
   }

   public void setVersionCode(final Integer versionCode) {
      this.versionCode = versionCode;
   }

   public void setVersionName(final String versionName) {
      this.versionName = versionName;
   }

   public void setOnlineState(final Integer onlineState) {
      this.onlineState = onlineState;
   }

   public void setConsumMode(final Integer consumMode) {
      this.consumMode = consumMode;
   }

   public void setCommMode(final Integer commMode) {
      this.commMode = commMode;
   }

   public void setDeviceAgreement(final Integer deviceAgreement) {
      this.deviceAgreement = deviceAgreement;
   }

   public void setDeviceIp(final String deviceIp) {
      this.deviceIp = deviceIp;
   }

   public void setDeviceMask(final String deviceMask) {
      this.deviceMask = deviceMask;
   }

   public void setDeviceMac(final String deviceMac) {
      this.deviceMac = deviceMac;
   }

   public void setDeviceGateway(final String deviceGateway) {
      this.deviceGateway = deviceGateway;
   }

   public void setFirstDns(final String firstDns) {
      this.firstDns = firstDns;
   }

   public void setNextDns(final String nextDns) {
      this.nextDns = nextDns;
   }

   public void setIfQuotaLimit(final Integer ifQuotaLimit) {
      this.ifQuotaLimit = ifQuotaLimit;
   }

   public void setIfDiscount(final Integer ifDiscount) {
      this.ifDiscount = ifDiscount;
   }

   public void setIfTimeLimit(final Integer ifTimeLimit) {
      this.ifTimeLimit = ifTimeLimit;
   }

   public void setIfUseCallNum(final Integer ifUseCallNum) {
      this.ifUseCallNum = ifUseCallNum;
   }

   public void setIfEnable(final Integer ifEnable) {
      this.ifEnable = ifEnable;
   }

   public void setImgUrl(final String imgUrl) {
      this.imgUrl = imgUrl;
   }

   public void setAmountNotify(final Integer amountNotify) {
      this.amountNotify = amountNotify;
   }

   public void setBindingValidTime(final Integer bindingValidTime) {
      this.bindingValidTime = bindingValidTime;
   }

   public void setOrdAutomaticPay(final Integer ordAutomaticPay) {
      this.ordAutomaticPay = ordAutomaticPay;
   }

   public void setIfOffLinePay(final Integer ifOffLinePay) {
      this.ifOffLinePay = ifOffLinePay;
   }

   public void setAlarmTime(final Integer alarmTime) {
      this.alarmTime = alarmTime;
   }

   public void setSpoonWeight(final Integer spoonWeight) {
      this.spoonWeight = spoonWeight;
   }

   public void setHeartBeatTime(final Long heartBeatTime) {
      this.heartBeatTime = heartBeatTime;
   }

   public void setCarouselTime(final Long carouselTime) {
      this.carouselTime = carouselTime;
   }

   public void setTitleSlogan(final String titleSlogan) {
      this.titleSlogan = titleSlogan;
   }

   public void setFontSize(final Integer fontSize) {
      this.fontSize = fontSize;
   }

   public void setFontColor(final String fontColor) {
      this.fontColor = fontColor;
   }

   public void setGuiStyle(final Integer guiStyle) {
      this.guiStyle = guiStyle;
   }

   public void setImageMap(final JsonNode imageMap) {
      this.imageMap = imageMap;
   }

   public void setLineNum(final Integer lineNum) {
      this.lineNum = lineNum;
   }

   public void setOncePayAmount(final Integer oncePayAmount) {
      this.oncePayAmount = oncePayAmount;
   }

   public void setDataStatus(final Integer dataStatus) {
      this.dataStatus = dataStatus;
   }

   public void setOrdOpenLimit(final Integer ordOpenLimit) {
      this.ordOpenLimit = ordOpenLimit;
   }

   public void setDetailNumLimit(final Integer detailNumLimit) {
      this.detailNumLimit = detailNumLimit;
   }

   public void setTerminalSn(final String terminalSn) {
      this.terminalSn = terminalSn;
   }

   public void setTerminalKey(final String terminalKey) {
      this.terminalKey = terminalKey;
   }

   public void setPriStatus(final Integer priStatus) {
      this.priStatus = priStatus;
   }

   public void setPriKey(final String priKey) {
      this.priKey = priKey;
   }

   public void setGateDefaultAmount(final Integer gateDefaultAmount) {
      this.gateDefaultAmount = gateDefaultAmount;
   }

   public void setHeartbeatStateCache(final String heartbeatStateCache) {
      this.heartbeatStateCache = heartbeatStateCache;
   }

   public void setDeviceState(final String deviceState) {
      this.deviceState = deviceState;
   }

   public void setBindList(final List<BindVO> bindList) {
      this.bindList = bindList;
   }

   public void setRecipeList(final List<RecipeVO> recipeList) {
      this.recipeList = recipeList;
   }

   public void setDishesList(final List<DishesVO> dishesList) {
      this.dishesList = dishesList;
   }

   public void setDeviceMetadata(final Map deviceMetadata) {
      this.deviceMetadata = deviceMetadata;
   }

   public void setFirstCanteenId(final Long firstCanteenId) {
      this.firstCanteenId = firstCanteenId;
   }

   public void setFirstShopstallId(final Long firstShopstallId) {
      this.firstShopstallId = firstShopstallId;
   }


   public static class BindVO {
      @ApiModelProperty("主键id")
      private Long id;
      @ApiModelProperty("设备id")
      private Long deviceId;
      @ApiModelProperty("食堂id")
      private Long canteenId;
      @ApiModelProperty("店铺档口id")
      private Long stallId;
      @ApiModelProperty("包间id")
      private Long roomId;
      @ApiModelProperty("是否启用打印")
      private Integer ifUsePrint;

      public Long getId() {
         return this.id;
      }

      public Long getDeviceId() {
         return this.deviceId;
      }

      public Long getCanteenId() {
         return this.canteenId;
      }

      public Long getStallId() {
         return this.stallId;
      }

      public Long getRoomId() {
         return this.roomId;
      }

      public Integer getIfUsePrint() {
         return this.ifUsePrint;
      }

      public void setId(final Long id) {
         this.id = id;
      }

      public void setDeviceId(final Long deviceId) {
         this.deviceId = deviceId;
      }

      public void setCanteenId(final Long canteenId) {
         this.canteenId = canteenId;
      }

      public void setStallId(final Long stallId) {
         this.stallId = stallId;
      }

      public void setRoomId(final Long roomId) {
         this.roomId = roomId;
      }

      public void setIfUsePrint(final Integer ifUsePrint) {
         this.ifUsePrint = ifUsePrint;
      }

   }

   public static class RecipeVO {
      @ApiModelProperty("主键id")
      private Long id;
      @ApiModelProperty("设备id")
      private Long deviceId;
      @ApiModelProperty("食堂id")
      private Long canteenId;
      @ApiModelProperty("店铺档口id")
      private Long stallId;
      @ApiModelProperty("菜谱id")
      private Long recipeId;

      public Long getId() {
         return this.id;
      }

      public Long getDeviceId() {
         return this.deviceId;
      }

      public Long getCanteenId() {
         return this.canteenId;
      }

      public Long getStallId() {
         return this.stallId;
      }

      public Long getRecipeId() {
         return this.recipeId;
      }

      public void setId(final Long id) {
         this.id = id;
      }

      public void setDeviceId(final Long deviceId) {
         this.deviceId = deviceId;
      }

      public void setCanteenId(final Long canteenId) {
         this.canteenId = canteenId;
      }

      public void setStallId(final Long stallId) {
         this.stallId = stallId;
      }

      public void setRecipeId(final Long recipeId) {
         this.recipeId = recipeId;
      }
   }

   public static class DishesVO {
      @ApiModelProperty("id主键")
      private Long id;
      @ApiModelProperty("设备id")
      private Long deviceId;
      @ApiModelProperty("菜品id")
      private Long dishesId;

      public Long getId() {
         return this.id;
      }

      public Long getDeviceId() {
         return this.deviceId;
      }

      public Long getDishesId() {
         return this.dishesId;
      }

      public void setId(final Long id) {
         this.id = id;
      }

      public void setDeviceId(final Long deviceId) {
         this.deviceId = deviceId;
      }

      public void setDishesId(final Long dishesId) {
         this.dishesId = dishesId;
      }

   }
}
