package com.bonus.canteen.core.device.manage.controller;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.bonus.canteen.core.allocation.api.AllocCanteenApi;
import com.bonus.canteen.core.allocation.canteen.vo.AllocCanteenTreeVO;
import com.bonus.canteen.core.auth.api.MgrAuthApi;
import com.bonus.canteen.core.common.base.BaseController;
import com.bonus.canteen.core.common.page.PageDTO;
import com.bonus.canteen.core.common.page.PageVO;
import com.bonus.canteen.core.common.page.QueryParseHelper;
import com.bonus.canteen.core.common.utils.BaseTreeNode;
import com.bonus.canteen.core.device.manage.dto.*;
import com.bonus.canteen.core.device.manage.model.DeviceInfo;
import com.bonus.canteen.core.device.manage.model.DeviceStateLog;
import com.bonus.canteen.core.device.manage.service.DeviceInfoService;
import com.bonus.canteen.core.device.manage.service.DeviceLockerService;
import com.bonus.canteen.core.device.manage.service.DeviceStateLogService;
import com.bonus.canteen.core.device.manage.service.DeviceTcpService;
import com.bonus.canteen.core.device.manage.vo.DeviceFullInfoVO;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.houqin.constant.LeConstants;
import com.bonus.common.houqin.constant.SourceTypeEnum;
import com.bonus.common.houqin.utils.BRequest;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Api(
   tags = {"设备管理模块"}
)
@RequestMapping({"/api/v2/device"})
public class DeviceInfoV2Controller extends BaseController {
   private static final Logger log = LoggerFactory.getLogger(DeviceInfoV2Controller.class);
   @Autowired
   private DeviceInfoService deviceInfoService;
   @Autowired
   private DeviceLockerService deviceLockerService;
//   @ApiModelProperty
//   @Autowired
//   private DeviceWeighAlarmInfoService deviceWeighAlarmInfoService;
   @ApiModelProperty
   @Autowired
   private AllocCanteenApi allocCanteenApi;
   @Autowired
   private DeviceTcpService deviceTcpService;
   @Autowired
   private MgrAuthApi mgrAuthApi;
   @Autowired
   private DeviceStateLogService deviceStateLogService;

   @ApiOperation(
      value = "添加新设备",
      notes = "必传参数商家id、食堂id,设备编号、设备名称、设备类型、设备sn码、设备ip"
   )
   @PostMapping({"/insert"})
   public AjaxResult insertDevice(@RequestBody DeviceDTO request) {
      this.deviceInfoService.insert(request);
      return AjaxResult.success();
   }

   @ApiOperation("更新设备信息")
   @PostMapping({"/update"})
   public AjaxResult updateDevice(@RequestBody DeviceDTO request) {
      if (request.getDeviceId() == null) {
         throw new ServiceException("设备id不能为空");
      } else {
         this.deviceInfoService.update(request);
         return AjaxResult.success();
      }
   }

   @ApiOperation(
      value = "删除设备信息",
      notes = "content：设备id"
   )
   @PostMapping({"/delete"})
   public AjaxResult delDevice(@RequestParam Long deviceId) {
      this.deviceInfoService.delete(deviceId);
      return AjaxResult.success();
   }

   @GetMapping({"/getBySn"})
   @ApiOperation(
      value = "设备sn码获取设备信息",
      notes = "content：设备SN"
   )
   public DeviceFullInfoVO getBySn(BRequest<String> request) {
      DeviceInfo deviceInfo = this.deviceInfoService.getBySn((String)request.getContent());
      if (deviceInfo == null) {
         return null;
      } else {
         List<DeviceFullInfoVO> deviceFullInfoVOList = this.deviceInfoService.fillFullVo(CollUtil.toList(deviceInfo));
         return deviceFullInfoVOList.get(0);
      }
   }

   @ApiOperation(
      value = "分页查询设备信息",
      notes = "page：分页信息，object：canteenId:食堂ID, stallId:店铺档口id, deviceState:1在线2离线, "
   )
   @PostMapping({"/page"})
   public PageVO<DeviceFullInfoVO> page(@RequestBody BRequest<String> request) {
      request.setContent(Base64.decodeStr(request.getContent()));
      DeviceSearchDTO param = QueryParseHelper.getParamFromContent(request.getContent(), DeviceSearchDTO.class);
      List<Long> systemCanteenIds;
      if (CollUtil.isNotEmpty(param.getAreaIdList()) && ObjectUtil.isEmpty(param.getCanteenIdList())) {
         systemCanteenIds = this.allocCanteenApi.getCanteenIdListByAreaIdList((List)param.getAreaIdList());
         if (ObjectUtil.isEmpty(systemCanteenIds)) {
            return PageVO.of(new ArrayList());
         }

         param.setCanteenIdList(this.allocCanteenApi.getCanteenIdListByAreaIdList((List)param.getAreaIdList()));
      }

      List<AllocCanteenTreeVO> systemCanteen = this.mgrAuthApi.getTenantCanteen(LeConstants.COMMON_YES, DelFlagEnum.DEL_FALSE.key(), true);
      if (ObjectUtil.isEmpty(systemCanteen)) {
         return PageVO.of(new ArrayList());
      } else {
         if (!SourceTypeEnum.PRINTER.getKey().equals(param.getDeviceType())) {
            Collection<Long> canteenStallIdIdList = systemCanteen.stream().filter((node) -> {
               return node.ifCanteen() || node.ifStall();
            }).map(BaseTreeNode::getId).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(canteenStallIdIdList)) {
               param.setCanteenStallIdListPermission(canteenStallIdIdList);
            }
         }

         PageDTO page = QueryParseHelper.getPageFromContent((String)request.getContent());
         PageDTO.OrderItem pageOrderItem = new PageDTO.OrderItem();
         pageOrderItem.setColumn("device_id");
         pageOrderItem.setAsc(false);
         if (ObjectUtil.isNotEmpty(param.getOrderByName()) && ObjectUtil.isNotEmpty(param.getAsc())) {
            pageOrderItem.setColumn(param.getOrderByName());
            pageOrderItem.setAsc(param.getAsc());
         }

         page.setOrders(Convert.toList(PageDTO.OrderItem.class, pageOrderItem));
         PageDTO.startPage(page);
         Page<DeviceInfo> dataPage = (Page)this.deviceInfoService.listPermission(param);
         List<DeviceFullInfoVO> voList = this.deviceInfoService.fillFullVo(dataPage).stream().filter((s) -> {
            return ObjectUtil.isEmpty(param.getOnlineState()) || s.getOnlineState().equals(param.getOnlineState());
         }).collect(Collectors.toList());
         return PageVO.of((List)dataPage, voList);
      }
   }

   @ApiOperation("查询支付设备列表")
   @PostMapping({"/getPayDeviceList"})
   public List<DeviceFullInfoVO> getPayDeviceList(@RequestBody DeviceBindDTO deviceBindDTO) {
      List<DeviceInfo> deviceInfoList = this.deviceInfoService.listPaymentDevice();
      List<DeviceFullInfoVO> voList = this.deviceInfoService.fillFullVo(deviceInfoList).stream().filter((s) -> {
         return ObjectUtil.equal(deviceBindDTO.getCanteenId(), s.getFirstCanteenId())
                 && (ObjectUtil.isEmpty(deviceBindDTO.getStallId())
                 || ObjectUtil.equal(deviceBindDTO.getStallId(), s.getFirstShopstallId()));
      }).collect(Collectors.toList());
      return voList;
   }

//   @PostMapping({"/updateIssue"})
//   @RequiresAuthentication
//   @ApiOperation(
//      value = "批量更新发布屏字体配置",
//      notes = "字体大小和字体颜色，颜色使用16进制"
//   )
//   public AjaxResult updateIssue(@RequestBody LeRequest<List<DeviceIssueDTO>> request) {
//      this.deviceInfoService.updateIssueConfig((List)request.getContent());
//      return AjaxResult.success();
//   }

//   @ApiOperation("设备激活收钱吧")
//   @PostMapping({"/shouqianba/activate"})
//   @RequiresPermissions({"machine:activate:shouqianbaActivate"})
//   @RequiresAuthentication
//   public SqbBizResponse shouqianbaActivate(@RequestBody LeRequest<SqbActivationDTO> request) {
//      SqbActivationDTO sqbActivationDTO = (SqbActivationDTO)request.getContent();
//      if (ObjectUtil.isEmpty(sqbActivationDTO)) {
//         throw new LeException("缺少参数");
//      } else {
//         return this.deviceInfoService.shouqianbaActivate(sqbActivationDTO);
//      }
//   }

//   @GetMapping({"/locker/listByDeviceId"})
////   @RequiresGuest
//   @ApiOperation(
//      value = "获取指定取餐柜详情",
//      notes = "content：设备id"
//   )
//   public List<DeviceLockerVO> listLockerByDeviceId(BRequest<Long> request) {
//      List<DeviceLocker> deviceLockerList = this.deviceLockerService.list((new DeviceLockerSearchDTO()).setDeviceId((Long)request.getContent()));
//      List<DeviceLockerVO> voList = this.deviceLockerService.fillVo(deviceLockerList);
//      return voList;
//   }

//   @PostMapping({"/locker/disable"})
//   @RequiresAuthentication
//   @ApiOperation("禁用/启用指定取餐柜门")
//   public LeResponse<?> disableLocker(@RequestBody LeRequest<DeviceLockerDisabledDTO> leRequest) {
//      this.deviceLockerService.disabledMealCounter((DeviceLockerDisabledDTO)leRequest.getContent());
//      return LeResponse.succ();
//   }

//   @ApiOperation(
//      value = "计量主机查询报警信息分页",
//      notes = "object字段：deviceNum:终端编号, deviceSn:设备sn码, stallId:档口id, canteenId:食堂id"
//   )
//   @GetMapping({"/weigh/getAlarmByPage"})
////   @RequiresGuest
//   public PageVO<DeviceWeighAlarmInfo> getMachineByPage(BRequest<String> request) {
//      PageDTO page = QueryParseHelper.getPageFromContent((String)request.getContent());
//      DeviceWeighAlarmInfoSearchDto param = (DeviceWeighAlarmInfoSearchDto)QueryParseHelper.getParamFromContent((String)request.getContent(), DeviceWeighAlarmInfoSearchDto.class);
//      PageHelper.startPage(page);
//      Page<DeviceWeighAlarmInfo> dataList = (Page)this.deviceWeighAlarmInfoService.list(param);
//      return PageVO.of((List)dataList);
//   }

   @ApiOperation("")
   @PostMapping({"/tcp/state"})
   public AjaxResult state(@RequestBody BRequest<List<DeviceTcpDto>> leRequest) {
      return AjaxResult.success(this.deviceTcpService.status(leRequest.getContent()));
   }

//   @PostMapping({"/getchildandrecipeBySn"})
//   @RequiresGuest
//   @ApiOperation(
//      value = "设备sn码获取子绑定设备及需要下发的设备",
//      notes = "content：设备SN"
//   )
//   public DeviceCPJOrWeightUpdateVo getchildBySn(@RequestHeader Map<String, String> headers, @RequestBody LeRequest<String> request) {
//      DeviceInfo deviceInfo = this.deviceInfoService.getDeviceInfoBySnCacheable(this.getMachineSnHeaders(headers));
//      if (deviceInfo == null) {
//         return null;
//      } else {
//         List<DeviceInfoVO> deviceInfoVOList = this.deviceInfoService.listDeviceInfoVoByParentId(deviceInfo);
//         DeviceCPJOrWeightUpdateVo deviceCPJOrWeightUpdateVo = new DeviceCPJOrWeightUpdateVo();
//         deviceCPJOrWeightUpdateVo.setDeviceInfoVO(BeanUtil.copyToList(deviceInfoVOList, DeviceInfoCPJOrWeightVO.class));
//         List<DeviceCPJOrWeightUpdateVo.SendNum> deviceNumList = new ArrayList();
//         deviceInfoVOList.stream().forEach((s) -> {
//            String type = RedisUtil.getString(String.format("yunshitang:merchantId:recipesendtype:macNumber".replace("merchantId", TenantContextHolder.getTenantId().toString()).replace("macNumber", s.getDeviceNum())));
//            if (ObjectUtil.isNotEmpty(type) && type.equals(TcpMenuSendTypeEnum.ENABLED.key().toString())) {
//               DeviceCPJOrWeightUpdateVo.SendNum sendNum = new DeviceCPJOrWeightUpdateVo.SendNum();
//               DeviceSendMenuTimeDTO localDateTime = (DeviceSendMenuTimeDTO)RedisUtil.getObj(String.format("yunshitang:%s:devicesendtime:%s", TenantContextHolder.getTenantId(), s.getDeviceNum()));
//               sendNum.setDeviceNum(s.getDeviceNum());
//               sendNum.setLocalDateTimeMenuSend(ObjectUtil.isNotEmpty(localDateTime) ? localDateTime.getLocalDateTimeMenu() : null);
//               deviceNumList.add(sendNum);
//            }
//
//         });
//         deviceCPJOrWeightUpdateVo.setDeviceNumList(deviceNumList);
//         return deviceCPJOrWeightUpdateVo;
//      }
//   }

//   @PostMapping({"/tcp/update/devicestate"})
//   @RequiresGuest
//   @ApiOperation(
//      value = "上传网关绑定的出品机状态",
//      notes = "content：设备SN"
//   )
//   public LeResponse<?> updatedevicestate(@RequestHeader Map<String, String> headers, @RequestBody LeRequest<List<DeviceHeartBeatDto>> request) {
//      DeviceInfo deviceInfo = this.deviceInfoService.getDeviceInfoBySnCacheable(this.getMachineSnHeaders(headers));
//      this.deviceTcpService.updatestate(deviceInfo.getDeviceIp(), (List)request.getContent(), true);
//      return LeResponse.succ();
//   }

   @ApiOperation("分页查询设备异常信息")
   @PostMapping({"/statelog/page"})
   public PageVO<DeviceStateLog> statelogpage(@RequestBody BRequest<String> request) {
      request.setContent(Base64.decodeStr(request.getContent()));
      DeviceStateLogSearchDTO param = QueryParseHelper.getParamFromContent((String)request.getContent(),
              DeviceStateLogSearchDTO.class);
      PageDTO page = QueryParseHelper.getPageFromContent(request.getContent());
      PageHelper.startPage(page);
      Page<DeviceStateLog> dataPage = (Page)this.deviceStateLogService.query(param);
      return PageVO.of((List)dataPage);
   }
}
