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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
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.AllocStall;
import com.bonus.canteen.core.device.manage.mapper.DeviceRecipeMapper;
import com.bonus.canteen.core.device.manage.model.DeviceRecipe;
import com.bonus.canteen.core.device.manage.vo.DeviceRecipeVO;
import com.bonus.canteen.core.allocation.canteen.model.*;
import com.bonus.canteen.core.menu.api.MenuDishesApi;
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.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class DeviceRecipeService {
   @Autowired
   private DeviceRecipeMapper deviceRecipeMapper;
   @Autowired
   private AllocStallApi allocStallApi;
   @Autowired
   private AllocCanteenApi allocCanteenApi;
   @Autowired
   private MenuDishesApi menuDishesApi;

//   private void insert(DeviceRecipeDTO dto) {
//      DeviceRecipe entity = dto.convertToEntity();
//      if (entity.getId() == null) {
//         entity.setId(Id.next());
//      }
//
//      this.deviceRecipeMapper.insert(entity);
//   }
//
//   @Transactional(
//      rollbackFor = {Exception.class}
//   )
//   public void insert(List<DeviceRecipeDTO> dtoList) {
//      if (!CollUtil.isEmpty(dtoList)) {
//         Iterator var2 = dtoList.iterator();
//
//         while(var2.hasNext()) {
//            DeviceRecipeDTO dto = (DeviceRecipeDTO)var2.next();
//            this.insert(dto);
//         }
//
//      }
//   }
//
//   @Transactional
//   public void update(Long deviceId, List<DeviceRecipeDTO> dtoList) {
//      this.deleteByDeviceId(deviceId);
//      if (!CollUtil.isEmpty(dtoList)) {
//         this.insert(dtoList);
//      }
//   }
//
//   @Transactional
//   public void update(List<DeviceRecipeDTO> dtoList) {
//      if (!CollUtil.isEmpty(dtoList)) {
//         this.deleteByDeviceIds(dtoList.stream().map(DeviceRecipeDTO::getDeviceId).toList());
//         this.insert(dtoList);
//      }
//   }
//
//   @Transactional
//   public void updateRecipeByCanteenOrStall(Long canteenId, Long shopstallId, Long recipeId) {
//      if (canteenId == null && shopstallId == null) {
//         throw new LeException("档口id和食堂id不能都为空");
//      } else {
//         LambdaUpdateWrapper<DeviceRecipe> updateWrapper = (LambdaUpdateWrapper)Wrappers.lambdaUpdate(DeviceRecipe.class).set(DeviceRecipe::getRecipeId, recipeId);
//         if (canteenId != null) {
//            updateWrapper.eq(DeviceRecipe::getCanteenId, canteenId);
//         }
//
//         if (shopstallId != null) {
//            updateWrapper.eq(DeviceRecipe::getStallId, shopstallId);
//         }
//
//         this.deviceRecipeMapper.update((Object)null, updateWrapper);
//      }
//   }
//
//   @Transactional
//   public void updateRecipeByCanteenOrStall(Long canteenId, Long shopstallId, Long recipeId, List<Long> machineIdList) {
//      if (canteenId == null && shopstallId == null) {
//         throw new LeException("档口id和食堂id不能都为空");
//      } else {
//         LambdaUpdateWrapper<DeviceRecipe> updateWrapper = (LambdaUpdateWrapper)Wrappers.lambdaUpdate(DeviceRecipe.class).set(DeviceRecipe::getRecipeId, recipeId);
//         if (canteenId != null) {
//            updateWrapper.eq(DeviceRecipe::getCanteenId, canteenId);
//         }
//
//         if (shopstallId != null) {
//            updateWrapper.eq(DeviceRecipe::getStallId, shopstallId);
//         }
//
//         if (ObjectUtil.isNotEmpty(machineIdList)) {
//            updateWrapper.in(DeviceRecipe::getDeviceId, machineIdList);
//         }
//
//         this.deviceRecipeMapper.update((Object)null, updateWrapper);
//      }
//   }
//
//   @Transactional
//   public void deleteRecipeByCanteenOrStall(Long canteenId, Long shopstallId, Long recipeId) {
//      if (canteenId == null && shopstallId == null) {
//         throw new LeException("档口id和食堂id不能都为空");
//      } else {
//         LambdaUpdateWrapper<DeviceRecipe> deleteWrapper = Wrappers.lambdaUpdate(DeviceRecipe.class);
//         if (canteenId != null) {
//            deleteWrapper.eq(DeviceRecipe::getCanteenId, canteenId);
//         }
//
//         if (shopstallId != null) {
//            deleteWrapper.eq(DeviceRecipe::getStallId, shopstallId);
//         }
//
//         if (ObjectUtil.isNotEmpty(recipeId)) {
//            deleteWrapper.eq(DeviceRecipe::getRecipeId, recipeId);
//         }
//
//         this.deviceRecipeMapper.delete(deleteWrapper);
//      }
//   }
//
//   public void updateRecipeByDeviceIdList(List<Long> deviceIdList, Long recipeId) {
//      LambdaUpdateWrapper<DeviceRecipe> updateWrapper = (LambdaUpdateWrapper)Wrappers.lambdaUpdate(DeviceRecipe.class).set(DeviceRecipe::getRecipeId, recipeId);
//      updateWrapper.in(DeviceRecipe::getDeviceId, deviceIdList);
//      this.deviceRecipeMapper.update((Object)null, updateWrapper);
//   }
//
//   public void deleteByDeviceId(Long deviceId) {
//      this.deviceRecipeMapper.delete((Wrapper)Wrappers.lambdaQuery(DeviceRecipe.class).eq(DeviceRecipe::getDeviceId, deviceId));
//   }
//
//   public void deleteByDeviceIds(List<Long> deviceIds) {
//      this.deviceRecipeMapper.delete((Wrapper)Wrappers.lambdaQuery(DeviceRecipe.class).in(DeviceRecipe::getDeviceId, deviceIds));
//   }

   public List<DeviceRecipe> listByDeviceIds(List<Long> deviceIds) {
      return (CollUtil.isEmpty(deviceIds) ? CollUtil.newArrayList(new DeviceRecipe[0]) :
              this.deviceRecipeMapper.selectList(Wrappers.lambdaQuery(DeviceRecipe.class)
                      .in(DeviceRecipe::getDeviceId, deviceIds)));
   }

   public List<DeviceRecipeVO> listVoByDeviceIds(List<Long> deviceIds) {
      List<DeviceRecipe> deviceRecipeList = this.listByDeviceIds(deviceIds);
      if (CollUtil.isEmpty(deviceRecipeList)) {
         return CollUtil.newArrayList(new DeviceRecipeVO[0]);
      } else {
         List<Long> stallIds = CollUtil.map(deviceRecipeList, DeviceRecipe::getStallId, true);
         List<Long> canteenIds = CollUtil.map(deviceRecipeList, DeviceRecipe::getCanteenId, true);
         List<Long> recipeIds = CollUtil.map(deviceRecipeList, DeviceRecipe::getRecipeId, true);
         Map<Long, AllocStall> stallsMapById = CollUtil.isEmpty(stallIds) ? MapUtil.empty() :
                 (Map)this.allocStallApi.listStallByStallIdList(CollUtil.newHashSet(stallIds)).stream()
                         .collect(Collectors.toMap(AllocStall::getStallId, Function.identity()));
         Map<Long, AllocCanteen> canteenMapById = CollUtil.isEmpty(canteenIds) ? MapUtil.empty() :
                 (Map)this.allocCanteenApi.queryCanteenByCanteenIdList(CollUtil.newHashSet(canteenIds))
                         .stream().collect(Collectors.toMap(AllocCanteen::getCanteenId, Function.identity()));
         Map<Long, String> recipeNameMapById = CollUtil.isEmpty(recipeIds) ? MapUtil.empty() :
                 this.menuDishesApi.getRecipeMapByIdList((Long[])recipeIds.toArray(new Long[0]));
         return (List)deviceRecipeList.stream().map((s) -> {
            return DeviceRecipeVO.of(s, (AllocStall)stallsMapById.get(s.getStallId()), (AllocCanteen)canteenMapById.get(s.getCanteenId()), (String)recipeNameMapById.get(s.getRecipeId()));
         }).collect(Collectors.toList());
      }
   }

//   public Integer deviceCountByRecipeId(Long recipeId) {
//      List<DeviceRecipe> deviceBinds = this.deviceRecipeMapper.selectList((Wrapper)Wrappers.lambdaQuery(DeviceRecipe.class).eq(DeviceRecipe::getRecipeId, recipeId));
//      return ((Set)deviceBinds.stream().map(DeviceRecipe::getDeviceId).collect(Collectors.toSet())).size();
//   }
//
//   public Integer deviceCountByRecipeId(List<Long> recipeIds) {
//      List<DeviceRecipe> deviceBinds = this.deviceRecipeMapper.selectList((Wrapper)Wrappers.lambdaQuery(DeviceRecipe.class).in(DeviceRecipe::getRecipeId, recipeIds));
//      return ((Set)deviceBinds.stream().map(DeviceRecipe::getDeviceId).collect(Collectors.toSet())).size();
//   }
}
