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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bonus.canteen.core.allocation.api.AllocCanteenApi;
import com.bonus.canteen.core.allocation.api.AllocStallApi;
import com.bonus.canteen.core.allocation.canteen.model.AllocCanteen;
import com.bonus.canteen.core.allocation.canteen.model.AllocMealLine;
import com.bonus.canteen.core.allocation.canteen.model.AllocStall;
import com.bonus.canteen.core.allocation.canteen.vo.AllocAreaFullNameVO;
import com.bonus.canteen.core.device.manage.mapper.DeviceBindMapper;
import com.bonus.canteen.core.device.manage.model.DeviceBind;
import com.bonus.canteen.core.device.manage.vo.DeviceBindVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.invoke.SerializedLambda;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class DeviceBindService {
   @Autowired
   private DeviceBindMapper deviceBindMapper;
   @Autowired
   private AllocStallApi allocStallApi;
   @Autowired
   private AllocCanteenApi allocCanteenApi;

//   private void insert(DeviceBindDTO dto) {
//      DeviceBind entity = dto.convertToEntity();
//      if (entity.getId() == null) {
//         entity.setId(Id.next());
//      }
//
//      this.deviceBindMapper.insert(entity);
//   }
//
//   @Transactional(
//      rollbackFor = {Exception.class}
//   )
//   public void insert(List<DeviceBindDTO> dtoList) {
//      if (!CollUtil.isEmpty(dtoList)) {
//         Iterator var2 = dtoList.iterator();
//
//         while(var2.hasNext()) {
//            DeviceBindDTO dto = (DeviceBindDTO)var2.next();
//            this.insert(dto);
//         }
//
//      }
//   }
//
//   @Transactional
//   public void update(Long deviceId, List<DeviceBindDTO> dtoList) {
//      this.deleteByDeviceId(deviceId);
//      if (!CollUtil.isEmpty(dtoList)) {
//         this.insert(dtoList);
//      }
//   }
//
//   public void deleteByDeviceId(Long deviceId) {
//      this.deviceBindMapper.delete((Wrapper)Wrappers.lambdaQuery(DeviceBind.class).eq(DeviceBind::getDeviceId, deviceId));
//   }
//
//   public void deleteByDeviceIds(List<Long> deviceIds) {
//      if (!CollUtil.isEmpty(deviceIds)) {
//         this.deviceBindMapper.delete((Wrapper)Wrappers.lambdaQuery(DeviceBind.class).in(DeviceBind::getDeviceId, deviceIds));
//      }
//   }
//
//   public boolean existsByCanteenId(Long canteenId) {
//      return this.deviceBindMapper.exists((Wrapper)Wrappers.lambdaQuery(DeviceBind.class).eq(DeviceBind::getCanteenId, canteenId));
//   }
//
//   public boolean existsByStallId(Long stallId) {
//      return this.deviceBindMapper.exists((Wrapper)Wrappers.lambdaQuery(DeviceBind.class).eq(DeviceBind::getStallId, stallId));
//   }

   public List<DeviceBind> listBySn(String deviceSn) {
      return (List)(StrUtil.isEmpty(deviceSn) ? CollUtil.newArrayList(new DeviceBind[0]) : this.deviceBindMapper.list(deviceSn, (Integer)null));
   }

//   public List<DeviceBind> listByType(Integer deviceType) {
//      return (List)(deviceType == null ? CollUtil.newArrayList(new DeviceBind[0]) : this.deviceBindMapper.list((String)null, deviceType));
//   }

   public List<DeviceBind> listByDeviceIds(List<Long> deviceIds) {
      return CollUtil.isEmpty(deviceIds) ? ListUtil.empty() : this.deviceBindMapper.selectList(Wrappers
              .lambdaQuery(DeviceBind.class).in(DeviceBind::getDeviceId, deviceIds));
   }
//
//   public List<DeviceBindVO> listVoByDeviceId(Long deviceId) {
//      return this.listVoByDeviceIds(ListUtil.toList(new Long[]{deviceId}));
//   }

   public List<DeviceBindVO> listVoByDeviceIds(List<Long> deviceIds) {
      List<DeviceBind> deviceBindList = this.listByDeviceIds(deviceIds);
      if (CollUtil.isEmpty(deviceBindList)) {
         return Collections.emptyList();
      } else {
         List<Long> stallIds = CollUtil.map(deviceBindList, DeviceBind::getStallId, true);
         List<Long> canteenIds = CollUtil.map(deviceBindList, DeviceBind::getCanteenId, true);
         List<Long> mealLineIds = CollUtil.map(deviceBindList, DeviceBind::getMealLineId, true);
         List<Long> areaIds = CollUtil.map(deviceBindList, DeviceBind::getAreaId, true);
         Map<Long, AllocStall> stallsMapById = CollUtil.isEmpty(stallIds) ? MapUtil.empty() :
                 this.allocStallApi.listStallByStallIdList(CollUtil.newHashSet(stallIds)).stream()
                         .collect(Collectors.toMap(AllocStall::getStallId, Function.identity()));
         Map<Long, AllocCanteen> canteenNameMapById = CollUtil.isEmpty(canteenIds) ? MapUtil.empty() :
                 this.allocCanteenApi.queryCanteenByCanteenIdList(CollUtil.newHashSet(canteenIds))
                         .stream().collect(Collectors.toMap(AllocCanteen::getCanteenId, Function.identity()));
         Map<Long, AllocMealLine> mealLineMapById = CollUtil.isEmpty(mealLineIds) ? MapUtil.empty()
                 : this.allocCanteenApi.queryMealLineByMealLineIdList(CollUtil.newHashSet(mealLineIds))
                 .stream().collect(Collectors.toMap(AllocMealLine::getMealLineId, Function.identity()));
         Map<Long, AllocAreaFullNameVO> areaLineMapById = CollUtil.isEmpty(areaIds) ? MapUtil.empty() :
                 (Map)this.allocCanteenApi.listAreaFullName(areaIds).stream().collect(Collectors
                         .toMap(AllocAreaFullNameVO::getAreaId, Function.identity()));
         return deviceBindList.stream().map((s) -> {
            return DeviceBindVO.of(s, (AllocMealLine)mealLineMapById.get(s.getMealLineId()), (AllocStall)stallsMapById
                    .get(s.getStallId()), (AllocCanteen)canteenNameMapById.get(s.getCanteenId()),
                    (AllocAreaFullNameVO)areaLineMapById.get(s.getAreaId()));
         }).collect(Collectors.toList());
      }
   }
}
