package com.bonus.canteen.core.menu.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.bonus.canteen.core.common.constant.LeMqConstant;
import com.bonus.canteen.core.common.enums.LeLevelEnum;
import com.bonus.canteen.core.common.redis.RedisUtil;
import com.bonus.canteen.core.drp.mapper.DrpUnitMapper;
import com.bonus.canteen.core.drp.model.DrpUnit;
import com.bonus.canteen.core.menu.constant.MaterialTypeEnum;
import com.bonus.canteen.core.menu.constant.MenuSalesTypeEnum;
import com.bonus.canteen.core.menu.dto.MenuMaterialLeadInDTO;
import com.bonus.canteen.core.menu.entity.MenuMaterial;
import com.bonus.canteen.core.menu.entity.MenuMaterialCategory;
import com.bonus.canteen.core.menu.mapper.MenuMaterialCategoryMapper;
import com.bonus.canteen.core.menu.mapper.MenuMaterialMapper;
import com.bonus.canteen.core.menu.service.MenuCustomAsyncService;
import com.bonus.canteen.core.menu.service.MenuMaterialCategoryService;
import com.bonus.canteen.core.menu.service.MenuMaterialService;
import com.bonus.canteen.core.menu.utils.PinyinUtil;
import com.bonus.canteen.core.menu.vo.MenuMaterialInitVO;
import com.bonus.canteen.core.order.mq.MqUtil;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.houqin.utils.id.Id;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.lang.invoke.SerializedLambda;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MenuCustomAsyncServiceImpl implements MenuCustomAsyncService {
   private static final Logger log = LoggerFactory.getLogger(MenuCustomAsyncServiceImpl.class);
   @Resource
   @Lazy
   private MenuMaterialCategoryMapper menuMaterialCategoryMapper;
   @Resource
   @Lazy
   private MenuMaterialMapper menuMaterialMapper;
   @Resource
   @Lazy
   private MenuMaterialService menuMaterialService;
   @Resource
   @Lazy
   private DrpUnitMapper drpUnitMapper;
   @Resource
   @Lazy
   private MenuMaterialCategoryService menuMaterialCategoryService;

   @Override
   public void leadInMaterial(MenuMaterialLeadInDTO content, String username, String syncRedisKey) {
      log.info("原料基础库导入_开始!");
      List<MenuMaterialInitVO> noInitMaterialList = this.menuMaterialMapper.selectMaterialNameList();
      if (CollectionUtils.isEmpty(noInitMaterialList)) {
         log.info("***[采购库存_原料基础库导入]_菜品原料基础库导入_未查询到原料信息,无需导入*************");
         RedisUtil.delete(syncRedisKey);
      } else {
         log.info("***[采购库存_原料基础库导入]_菜品原料基础库导入_查询到基础原料数量: {}", noInitMaterialList.size());
         List<String> oldMaterialList = this.menuMaterialMapper.selectList(Wrappers.lambdaQuery(MenuMaterial.class)
                 .eq(MenuMaterial::getDelFlag, DelFlagEnum.DEL_FALSE.key())
                 .eq(content.getAreaId() != null, MenuMaterial::getAreaId, content.getAreaId())
                 .isNull(content.getAreaId() == null, MenuMaterial::getAreaId)
                 .select(MenuMaterial::getMaterialName))
                 .stream().map(MenuMaterial::getMaterialName).collect(Collectors.toList());
         noInitMaterialList = noInitMaterialList.stream().filter((m) -> {
            return !oldMaterialList.contains(m.getMaterialName());
         }).collect(Collectors.toList());
         log.info("***[采购库存_原料基础库导入]_菜品原料基础库导入_需要导入的数量: {}", noInitMaterialList.size());
         Long defaultCategoryId = this.menuMaterialCategoryMapper.selectCategoryIdByWrapper(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                 .eq(MenuMaterialCategory::getCategoryName, "原料").eq(MenuMaterialCategory::getParentId, -1L)
                 .eq(MenuMaterialCategory::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
         if (ObjectUtil.isNull(defaultCategoryId)) {
            MenuMaterialCategory materialCategory = new MenuMaterialCategory();
            defaultCategoryId = Id.next();
            materialCategory.setCategoryId(defaultCategoryId);
            materialCategory.setCategoryName("原料");
            materialCategory.setCategoryType(MaterialTypeEnum.MATERIAL.key());
            materialCategory.setParentId(-1L);
            Long categoryId = Id.next();
            materialCategory.setId(categoryId);
            materialCategory.setBigCategoryId(categoryId);
            materialCategory.setLevel(0);
            this.menuMaterialCategoryMapper.insert(materialCategory);
         }

         if (CollUtil.isEmpty(noInitMaterialList)) {
            log.info("***[采购库存_原料基础库导入]_菜品原料基础库导入_全部原料已经导入,无需导入*************");
         } else {
            Map<String, Long> categoryMap = Maps.newHashMap();
            Long finalDefaultCategoryId = defaultCategoryId;
            noInitMaterialList.forEach((m) -> {
               String bigType = m.getBigType();
               String littleType = m.getLittleType();
               Long bigTypeCategoryId = (Long)categoryMap.get(bigType);
               Long littleTypeCategoryId = (Long)categoryMap.get(littleType);
               MenuMaterialCategory materialCategory;
               if (ObjectUtil.isNull(bigTypeCategoryId)) {
                  bigTypeCategoryId = this.menuMaterialCategoryMapper.selectCategoryIdByWrapper(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                          .eq(MenuMaterialCategory::getCategoryType, MaterialTypeEnum.MATERIAL.key())
                          .eq(MenuMaterialCategory::getCategoryName, bigType)
                          .eq(content.getAreaId() != null, MenuMaterialCategory::getAreaId, content.getAreaId())
                          .isNull(content.getAreaId() == null, MenuMaterialCategory::getAreaId)
                          .eq(MenuMaterialCategory::getParentId, finalDefaultCategoryId)
                          .eq(MenuMaterialCategory::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
                  if (ObjectUtil.isNull(bigTypeCategoryId)) {
                     materialCategory = new MenuMaterialCategory();
                     bigTypeCategoryId = Id.next();
                     materialCategory.setId(Id.next());
                     materialCategory.setCategoryId(bigTypeCategoryId);
                     materialCategory.setCategoryName(bigType);
                     materialCategory.setParentId(finalDefaultCategoryId);
                     materialCategory.setAreaId(content.getAreaId());
                     materialCategory.setCategoryType(MaterialTypeEnum.MATERIAL.key());
                     materialCategory.setLevel(LeLevelEnum.FIRST.getKey());
                     materialCategory.setBigCategoryId(bigTypeCategoryId);
                     this.menuMaterialCategoryMapper.insert(materialCategory);
                     this.menuMaterialCategoryService.generateCategoryNum(materialCategory.getCategoryId(), materialCategory.getParentId(), materialCategory.getCategoryType());
                     categoryMap.put(bigType, bigTypeCategoryId);
                  }
               }

               if (ObjectUtil.isNull(littleTypeCategoryId)) {
                  littleTypeCategoryId = this.menuMaterialCategoryMapper.selectCategoryIdByWrapper(Wrappers.lambdaQuery(MenuMaterialCategory.class)
                          .eq(MenuMaterialCategory::getCategoryType, MaterialTypeEnum.MATERIAL.key())
                          .eq(MenuMaterialCategory::getCategoryName, littleType)
                          .eq(content.getAreaId() != null, MenuMaterialCategory::getAreaId, content.getAreaId())
                          .isNull(content.getAreaId() == null, MenuMaterialCategory::getAreaId)
                          .eq(MenuMaterialCategory::getParentId, bigTypeCategoryId)
                          .eq(MenuMaterialCategory::getDelFlag, DelFlagEnum.DEL_FALSE.key()));
                  if (ObjectUtil.isNull(littleTypeCategoryId)) {
                     materialCategory = new MenuMaterialCategory();
                     littleTypeCategoryId = Id.next();
                     materialCategory.setId(Id.next());
                     materialCategory.setCategoryId(littleTypeCategoryId);
                     materialCategory.setCategoryName(littleType);
                     materialCategory.setParentId(bigTypeCategoryId);
                     materialCategory.setAreaId(content.getAreaId());
                     materialCategory.setCategoryType(MaterialTypeEnum.MATERIAL.key());
                     materialCategory.setLevel(LeLevelEnum.SECOND.getKey());
                     materialCategory.setBigCategoryId(bigTypeCategoryId);
                     this.menuMaterialCategoryMapper.insert(materialCategory);
                     this.menuMaterialCategoryService.generateCategoryNum(materialCategory.getCategoryId(), materialCategory.getParentId(), materialCategory.getCategoryType());
                     categoryMap.put(littleType, littleTypeCategoryId);
                  }
               }

               MenuMaterial insertItem = new MenuMaterial();
               insertItem.setMaterialName(m.getMaterialName());
               insertItem.setNutritionId(m.getNutritionId());
               insertItem.setMaterialId(Id.next());
               insertItem.setCategoryId(littleTypeCategoryId);
               insertItem.setPinyinInitials(PinyinUtil.getFirstLetterFromChinese(m.getMaterialName()));
               insertItem.setPinyinFull(PinyinUtil.convertChineseToPinyin(m.getMaterialName()));
               insertItem.setCrby(username);
               insertItem.setAreaId(content.getAreaId());
               insertItem.setMaterialType(MaterialTypeEnum.MATERIAL.key());
               insertItem.setSalesMode(MenuSalesTypeEnum.WEIGHT_ON.key());
               insertItem.setBigCategoryId(bigTypeCategoryId);
               DrpUnit drpUnit = (DrpUnit)this.drpUnitMapper.selectOne(Wrappers.lambdaQuery(DrpUnit.class).eq(DrpUnit::getDelFlag, DelFlagEnum.DEL_FALSE.key())
                       .eq(DrpUnit::getUnitName, "公斤"));
               if (ObjectUtil.isNotEmpty(drpUnit)) {
                  insertItem.setUnitId(drpUnit.getUnitId());
               } else {
                  drpUnit = new DrpUnit();
                  drpUnit.setUnitId(Id.next());
                  drpUnit.setUnitName("公斤");
                  drpUnit.setRate(new BigDecimal(1000));
                  drpUnit.setWeighType(2);
                  drpUnit.setDelFlag(2);
                  this.drpUnitMapper.insert(drpUnit);
                  insertItem.setUnitId(drpUnit.getUnitId());
               }

               String materialCode = this.menuMaterialService.generateMaterialCode();
               insertItem.setMaterialCode(materialCode);
               this.menuMaterialMapper.insert(insertItem);
            });
            MqUtil.pushToTenantAllDevice((Object)null, LeMqConstant.Topic.DRP_SYNC_MATERIAL);
         }

         RedisUtil.delete(syncRedisKey);
         log.info("原料基础库导入_结束!");
      }
   }

}
