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

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bonus.canteen.core.alloc.domain.AllocArea;
import com.bonus.canteen.core.alloc.domain.AllocCanteen;
import com.bonus.canteen.core.alloc.domain.AllocStall;
import com.bonus.canteen.core.alloc.service.IAllocAreaService;
import com.bonus.canteen.core.alloc.service.IAllocCanteenService;
import com.bonus.canteen.core.alloc.service.IAllocStallService;
import com.bonus.canteen.core.common.utils.LogUtil;
import com.bonus.canteen.core.menu.domain.*;
import com.bonus.canteen.core.menu.dto.*;
import com.bonus.canteen.core.menu.enums.MenuDishesTypeDefaultFlagEnum;
import com.bonus.canteen.core.menu.enums.MenuMaterialTypeEnum;
import com.bonus.canteen.core.menu.enums.MenuSalesTypeEnum;
import com.bonus.canteen.core.menu.mapper.*;
import com.bonus.canteen.core.menu.service.IMenuDishesService;
import com.bonus.canteen.core.menu.service.MenuDishesBaseService;
import com.bonus.canteen.core.menu.service.MenuDishesSizeService;
import com.bonus.canteen.core.menu.vo.MenuNutritionDetailVO;
import com.bonus.canteen.core.utils.Arith;
import com.bonus.canteen.core.utils.NutritionEntity;
import com.bonus.canteen.core.utils.NutritionEntityUtil;
import com.bonus.canteen.core.utils.PinyinUtil;
import com.bonus.canteen.core.utils.excel.EasyExcelUtil;
import com.bonus.common.core.exception.ServiceException;
import com.bonus.common.core.utils.DateUtils;
import com.bonus.common.houqin.constant.DelFlagEnum;
import com.bonus.common.houqin.utils.id.Id;
import com.bonus.common.security.utils.SecurityUtils;
import com.google.common.collect.Lists;
import io.swagger.annotations.ApiModelProperty;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.hibernate.validator.internal.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Size;

/**
 * 菜品信息Service业务层处理
 *
 * @author xsheng
 * @date 2025-04-03
 */
@Service
public class MenuDishesServiceImpl extends ServiceImpl<MenuDishesMapper, MenuDishes>  implements IMenuDishesService {
    @Autowired
    private MenuDishesMapper menuDishesMapper;

    @Resource
    private IAllocAreaService allocAreaService;
    @Resource
    private IAllocCanteenService allocCanteenService;

    @Resource
    private IAllocStallService allocStallService;

    @Resource
    @Lazy
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private MenuRecipeMapper menuRecipeMapper;


    @Resource
    private MenuDishesBaseService menuDishesBaseService;

    @Resource
    private MenuMaterialMapper menuMaterialMapper;

    @Resource
    private MenuDishesSizeService menuDishesSizeService;

    @Resource
    private MenuMateralDishesMapper menuMaterialDishesMapper;
    @Resource
    private MenuMaterialNutritionMapper menuMaterialNutritionMapper;

    @Lazy
    @Resource(
            name = "smartCanteenTaskExecutor"
    )
    private AsyncTaskExecutor asyncTaskExecutor;

    private static final Logger log = LoggerFactory.getLogger(MenuDishesServiceImpl.class);

    /**
     * 查询菜品信息
     *
     * @param id 菜品信息主键
     * @return 菜品信息
     */
    @Override
    public MenuDishes selectMenuDishesById(Long id) {
        return menuDishesMapper.selectMenuDishesById(id);
    }

    /**
     * 查询菜品信息列表
     *
     * @param menuDishes 菜品信息
     * @return 菜品信息
     */
    @Override
    public List<MenuDishes> selectMenuDishesList(MenuDishes menuDishes) {
        return menuDishesMapper.selectMenuDishesList(menuDishes);
    }

    /**
     * 新增菜品信息
     *
     * @param menuDishes 菜品信息
     * @return 结果
     */
    @Override
    public int insertMenuDishes(MenuDishes menuDishes) {
        menuDishes.setCreateTime(LocalDateTime.now());
        try {
            menuDishes.setPinyinFull(PinyinUtil.getFirstLetterFromChinese(menuDishes.getDishesName()));
            menuDishes.setPinyinFull(PinyinUtil.convertChineseToPinyin(menuDishes.getDishesName()));
            return menuDishesMapper.insertMenuDishes(menuDishes);
        } catch (Exception e) {
            throw new ServiceException("错误信息描述");
        }
    }

    /**
     * 修改菜品信息
     *
     * @param menuDishesDTO 菜品信息
     * @return 结果
     */
    @Override
    public int updateMenuDishes(MenuDishesDTO menuDishesDTO) {
    //    try {
            if(menuDishesDTO.getDishesId() == null){
                throw new ServiceException("菜品ID不能为空");
            }
            if(menuDishesDTO.getBaseDishesId() == null){
                throw new ServiceException("菜品基础ID不能为空");
            }
            MenuDishes menuDishesOne = menuDishesMapper.getOneByName(menuDishesDTO);
            if(menuDishesOne !=null && menuDishesOne.getDishesId() != Long.parseLong(menuDishesDTO.getDishesId())){
                throw new ServiceException("菜品已存在");
            }
            menuDishesOne = menuDishesMapper.getOneByNum(menuDishesDTO);
            if(menuDishesOne !=null && menuDishesOne.getDishesId() != Long.parseLong(menuDishesDTO.getDishesId())){
                throw new ServiceException("编号已存在");
            }
            menuDishesDTO.setUpdateBy(SecurityUtils.getUsername());
            int baseNum = menuDishesMapper.updateMenuDishesBase(menuDishesDTO);
            if(menuDishesDTO.getAreaId()==null){
                menuDishesDTO.setAreaId(-1L);
            }
            if(menuDishesDTO.getCanteenId() == null){
                menuDishesDTO.setCanteenId(-1L);
            }
            if(menuDishesDTO.getShopstallId() == null){
                menuDishesDTO.setShopstallId(-1L);
            }
            int dishesNum = menuDishesMapper.editMenuDishes(menuDishesDTO);
            List<MenuDishesAddMaterialDTO> materialList= menuDishesDTO.getMaterialList();
            List<NutritionEntity> nutritionEntityList = new ArrayList<>();
            System.err.println("长度："+materialList.size());
            for (MenuDishesAddMaterialDTO i: materialList) {
                NutritionEntity nutritionEntity = menuDishesMapper.getNutritionEntity(i);
                if(nutritionEntity !=null){
                    System.err.println(i.getMaterialId()+",开始值："+nutritionEntity.getCalcium());
                    nutritionEntity.setWeight(i.getWeight());
                    nutritionEntity.setBaseWeight(100.0);
                    nutritionEntityList.add(nutritionEntity);
                }
            }
            if(materialList !=null && materialList.size() > 0){
                menuDishesMapper.updateMenuMaterialDishes(Long.parseLong(menuDishesDTO.getDishesId()));
                menuDishesMapper.addMenuMaterialDishes(Long.parseLong(menuDishesDTO.getDishesId()),materialList);
            }
            NutritionEntityUtil nutritionEntityUtil = new NutritionEntityUtil();
            NutritionEntity nutritionEntity = nutritionEntityUtil.countNutrition(nutritionEntityList);
            if(nutritionEntityList !=null && nutritionEntityList.size() >0){
                System.err.println("总和："+nutritionEntity.getCalcium());
                //计算营养成分
                nutritionEntity = countNum(nutritionEntity,menuDishesDTO.getWeight());
                System.err.println("计算后："+nutritionEntity.getCalcium());
                return menuDishesMapper.addFinalNutrition(nutritionEntity,Long.parseLong(menuDishesDTO.getDishesId()));
            }

            //添加菜品和材料关系表
            if(materialList != null && materialList.size() > 0){
                menuDishesMapper.updateMenuMaterialDishes(Long.parseLong(menuDishesDTO.getDishesId()));
                menuDishesMapper.addMenuMaterialDishes(Long.parseLong(menuDishesDTO.getDishesId()),materialList);
            }else{
                menuDishesMapper.updateMenuMaterialDishes(Long.parseLong(menuDishesDTO.getDishesId()));
            }
            return menuDishesMapper.editMenuDishes(menuDishesDTO);
//        } catch (Exception e) {
//            throw new ServiceException(e.toString());
//        }
    }

    /**
     * 批量删除菜品信息
     *
     * @param ids 需要删除的菜品信息主键
     * @return 结果
     */
    @Override
    public int deleteMenuDishesByIds(Long[] ids) {
        List<Long> baseDishesIds = menuDishesMapper.getBassIdByIds(ids);
        if(baseDishesIds != null && baseDishesIds.size() >0){
            menuDishesMapper.deleteBaseDishesByIds(baseDishesIds.toArray(new Long[baseDishesIds.size()]));
        }

        return menuDishesMapper.deleteMenuByIds(ids);
    }

    /**
     * 删除菜品信息信息
     *
     * @param id 菜品信息主键
     * @return 结果
     */
    @Override
    public int deleteMenuDishesById(Long id) {
        return menuDishesMapper.deleteMenuDishesById(id);
    }

    @Override
    public List<MapBean> getDishesType(MapBean mapBean) {
        return menuDishesMapper.getDishesType(mapBean);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public int addMenuDishes(MenuDishesDTO menuDishesDTO) {
        //检查菜品是否已存在
        MenuDishes menuDishesOne = menuDishesMapper.getOneByName(menuDishesDTO);
        if(menuDishesOne !=null && menuDishesOne.getDishesId() != Long.parseLong(menuDishesDTO.getDishesId())){
            throw new ServiceException("菜品已存在");
        }
        menuDishesOne = menuDishesMapper.getOneByNum(menuDishesDTO);
        if(menuDishesOne !=null && !StringHelper.isNullOrEmptyString(menuDishesDTO.getDishesNum())){
            throw new ServiceException("编号已存在");
        }
        Long dishesId = Id.next();
        Long baseDishesId = Id.next();
        menuDishesDTO.setCreateBy(SecurityUtils.getUsername());
        //添加基础主表信息
        menuDishesDTO.setBaseDishesId(baseDishesId+"");
        menuDishesDTO.setDishesId(dishesId+"");
        menuDishesDTO.setCustomId(-1);
        addIds(menuDishesDTO);
       int baseNum =  menuDishesMapper.addMenuDishesBase(menuDishesDTO);
       //添加主要信息
        int dishesNum =  menuDishesMapper.addMenuDishes(menuDishesDTO);

        List<MenuDishesAddMaterialDTO> materialList= menuDishesDTO.getMaterialList();
        List<NutritionEntity> nutritionEntityList = new ArrayList<>();
        System.err.println("长度："+materialList.size());
        for (MenuDishesAddMaterialDTO i: materialList) {
            NutritionEntity nutritionEntity = menuDishesMapper.getNutritionEntity(i);
            if(nutritionEntity !=null){
                System.err.println(i.getMaterialId()+",开始值："+nutritionEntity.getCalcium());
                nutritionEntity.setWeight(i.getWeight());
                nutritionEntity.setBaseWeight(100.0);
                nutritionEntityList.add(nutritionEntity);
            }
        }
        if(materialList != null && materialList.size() > 0){
            //添加菜品和材料关系表
            menuDishesMapper.updateMenuMaterialDishes(Long.parseLong(menuDishesDTO.getDishesId()));
            menuDishesMapper.addMenuMaterialDishes(dishesId,materialList);
            NutritionEntityUtil nutritionEntityUtil = new NutritionEntityUtil();
            NutritionEntity nutritionEntity = nutritionEntityUtil.countNutrition(nutritionEntityList);
            if(nutritionEntityList !=null && nutritionEntityList.size() >0){
                System.err.println("总和："+nutritionEntity.getCalcium());
                //计算营养成分
                nutritionEntity = countNum(nutritionEntity,menuDishesDTO.getWeight());
                System.err.println("计算后："+nutritionEntity.getCalcium());
                return menuDishesMapper.addFinalNutrition(nutritionEntity,dishesId);
            }
        }

        return 1;
    }

    private void addIds(MenuDishesDTO menuDishesDTO){

        List<Integer> labelIdList = menuDishesDTO.getLabelIdList();

        List<Integer> tasteIdList = menuDishesDTO.getTasteIdList();

        List<Integer> season =  menuDishesDTO.getSeason();

        List<Integer> suitIdList = menuDishesDTO.getSuitIdList();

        List<Integer> mealList =   menuDishesDTO.getMealList();

        if(labelIdList !=null && !labelIdList.isEmpty()){
            String result = labelIdList.stream() .map(String::valueOf).collect(Collectors.joining(","));
            menuDishesDTO.setLabelId(result);
        }
        if(tasteIdList !=null && !tasteIdList.isEmpty()){
            String result = tasteIdList.stream() .map(String::valueOf).collect(Collectors.joining(","));
            menuDishesDTO.setTasteId(result);
        }
        if(season !=null && !season.isEmpty()){
            String result = season.stream() .map(String::valueOf).collect(Collectors.joining(","));
            menuDishesDTO.setSeasonId(result);
        }
        if(suitIdList !=null && !suitIdList.isEmpty()){
            String result = suitIdList.stream() .map(String::valueOf).collect(Collectors.joining(","));
            menuDishesDTO.setSuitId(result);
        }
        if(mealList !=null && !mealList.isEmpty()){
            String result = mealList.stream() .map(String::valueOf).collect(Collectors.joining(","));
            menuDishesDTO.setMealId(result);
        }

    }


    private NutritionEntity countNum(NutritionEntity nutritionEntity,Double weight) {
        Field[] fields = nutritionEntity.getClass().getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                Double value = (Double) field.get(nutritionEntity);
                if(value !=null){
                    System.err.println("先前值----："+value);
                    double proportion = Arith.div(weight , 100);
                    value = Arith.mul(value, proportion);
                    field.set(nutritionEntity, value);
                    System.err.println("后来值++++："+value);
                }else{
                    field.set(nutritionEntity, 0.00);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return nutritionEntity;
    }



    //首字母转小写
    public static String toLowerCaseFirstOne(String s)
    {
        if(Character.isLowerCase(s.charAt(0))) {
            return s;
        } else {
            return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
        }
    }
    //首字母转大写
    public static String toUpperCaseFirstOne(String s) {
        if (Character.isUpperCase(s.charAt(0))) {
            return s;
        } else {
            return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
        }
    }


    @Override
    public MenuDishes check(MenuDishesDTO menuDishesDTO) {
        if(menuDishesDTO.getDishesId() == null){
            throw new ServiceException("菜品ID不能为空");
        }
        MenuDishes menuDishesDTO1 = menuDishesMapper.getDishMessageByDishesId(menuDishesDTO.getDishesId());
        List<MenuDishesAddMaterialDTO> menuDishesAddMaterialDTO= menuDishesMapper.getMenuMaterialDishes(menuDishesDTO.getDishesId());
        if(menuDishesAddMaterialDTO !=null){
            menuDishesDTO1.setMaterialList(menuDishesAddMaterialDTO);
        }
        List<Integer> mealList =   new ArrayList<>();
        if (menuDishesDTO1.getLabelId() !=null && !menuDishesDTO1.getLabelId().isEmpty()){
            List<Integer> list = Arrays.stream(menuDishesDTO1.getLabelId().split("\\s*,\\s*"))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            menuDishesDTO1.setLabelIdList(list);
        }
        if (menuDishesDTO1.getTasteId()!=null && !menuDishesDTO1.getTasteId().isEmpty()){
            List<Integer> list = Arrays.stream(menuDishesDTO1.getTasteId().split("\\s*,\\s*"))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            menuDishesDTO1.setTasteIdList(list);
        }
        if (menuDishesDTO1.getSeasonId() !=null && !menuDishesDTO1.getSeasonId().isEmpty()){
            List<Integer> list = Arrays.stream(menuDishesDTO1.getSeasonId().split("\\s*,\\s*"))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            menuDishesDTO1.setSeason(list);

        }
        if(menuDishesDTO1.getSuitId() !=null && !menuDishesDTO1.getSuitId().isEmpty()){
            List<Integer> list = Arrays.stream(menuDishesDTO1.getSuitId().split("\\s*,\\s*"))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            menuDishesDTO1.setSuitIdList(list);

        }
        if(menuDishesDTO1.getMealId() !=null && !menuDishesDTO1.getMealId().isEmpty()){
            List<Integer> list = Arrays.stream(menuDishesDTO1.getMealId().split("\\s*,\\s*"))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            menuDishesDTO1.setMealList(list);
        }
        if(-1 == menuDishesDTO1.getCookId()){
            menuDishesDTO1.setCookId(null);
        }
        if(menuDishesDTO1.getAreaId()== -1L){
            menuDishesDTO1.setAreaId(null);
        }
        if(menuDishesDTO1.getCanteenId() == -1L){
            menuDishesDTO1.setCanteenId(null);
        }
        if(menuDishesDTO1.getShopstallId() == -1L){
            menuDishesDTO1.setShopstallId(null);
        }
        return menuDishesDTO1;
    }

    @Override
    public DishesImportCheckResult importDishesCheck(MultipartFile excel) {
        List<MenuDishesImportDTO> menuDishesImportDTOS = null;
        DishesImportCheckResult dishesImportCheckResult = new DishesImportCheckResult();
        try {
            menuDishesImportDTOS = EasyExcelUtil.readSingleExcel(excel, new MenuDishesImportDTO(), 1);
        } catch (Exception var42) {
            throw new ServiceException("导入新增菜品错误"+ var42.getMessage());
        }
        if (CollectionUtils.isEmpty(menuDishesImportDTOS)) {
            throw new ServiceException("导入新增菜品为空");
        } else {
            List<String> sqlDishesNameList = this.menuRecipeMapper.selectDishesNameAndCanteenName();
            ImportDishesContext importDishesContext = this.getImportDishesContext(null);
            Map<String, Long> areaMap = importDishesContext.getAreaMap();
            Map<String, Long> dishesCookMap = importDishesContext.getDishesCookMap();
            Map<String, Long> typeMap = importDishesContext.getTypeMap();
            Map<String, AllocStall> allocStallMap = importDishesContext.getAllocStallMap();
            Map<String, AllocCanteen> allocCanteenMap = importDishesContext.getAllocCanteenMap();
            Map<Long, AllocArea> allocAreaIdMap = importDishesContext.getAllocAreaIdMap();
            Map<Long, AllocCanteen> allocCanteenIdMap = importDishesContext.getAllocCanteenIdMap();
            Map<String, Long> materialMap = importDishesContext.getMaterialMap();
            List<Integer> salesModeKeyList = Arrays.stream(MenuSalesTypeEnum.values()).map(MenuSalesTypeEnum::key).collect(Collectors.toList());
            List<String> menuMaterialTypeList = Arrays.stream(MenuMaterialTypeEnum.values()).map(MenuMaterialTypeEnum::key).map(Object::toString).collect(Collectors.toList());
            List<String> dishesNameList = Lists.newArrayList();
            List<MenuDishesImportDTO> successList = new ArrayList<>();
            List<MenuDishesImportDTO> errorList = new ArrayList<>();
            Iterator var19 = menuDishesImportDTOS.iterator();

            while(var19.hasNext()) {
                MenuDishesImportDTO data = (MenuDishesImportDTO)var19.next();

                try {
                    BigDecimal price = data.getPrice();
                    if (BigDecimal.ZERO.compareTo(price) > 0) {
                        data.setFailReason("菜品价格为负数");
                        errorList.add(data);
                    } else {
                        Integer salesMode = data.getSalesMode();
                        if (!salesModeKeyList.contains(salesMode)) {
                            data.setFailReason("计价方式只能填写1或者2");
                            errorList.add(data);
                        } else {
                            String dishesTypeName = data.getDishesTypeName();
                            if (CharSequenceUtil.isNotBlank(dishesTypeName) && typeMap.get(dishesTypeName) == null) {
                                data.setFailReason(dishesTypeName + "菜品类别不存在");
                                errorList.add(data);
                            } else {
                                Long notNormSizeType = 2L;
                                if (MenuSalesTypeEnum.PORTION_ON.key().equals(salesMode) && notNormSizeType.equals(data.getSizeType())) {
                                    BigDecimal largePrice = data.getLargePrice();
                                    BigDecimal littlePrice = data.getLittlePrice();
                                    Double largeWeight = data.getLargeWeight();
                                    Double littleWeight = data.getLittleWeight();
                                    if (ObjectUtil.hasNull(new Object[]{largePrice, littlePrice, largeWeight, littleWeight})) {
                                        data.setFailReason("大小份菜品需要录入大份单价、小份单价、大份份量、小份份量");
                                        errorList.add(data);
                                        continue;
                                    }
                                }

                                String dishesName = data.getDishesName();
                                String canteenName = data.getCanteenName();
                                String stallName = data.getStallName();
                                String areaName = data.getAreaName();
                                String itemDishesName = Stream.of(data.getDishesName(), areaName, canteenName, stallName).map((x) -> {
                                    return CharSequenceUtil.isBlank(x) ? "*" : x;
                                }).collect(Collectors.joining("-"));
                                if (CharSequenceUtil.isBlank(dishesName)) {
                                    data.setFailReason("菜品名称为空");
                                    errorList.add(data);
                                } else if (dishesNameList.contains(itemDishesName)) {
                                    data.setFailReason("菜品名称重复");
                                    errorList.add(data);
                                } else if (CollUtil.isNotEmpty(sqlDishesNameList) && sqlDishesNameList.contains(itemDishesName)) {
                                    data.setFailReason("菜品名称数据库已存在");
                                    errorList.add(data);
                                } else {
                                    String menuMaterialNames = data.getMenuMaterialNames();
                                    BigDecimal totalWeight = BigDecimal.ZERO;
                                    if (CharSequenceUtil.isNotBlank(menuMaterialNames)) {
                                        String[] materialList = menuMaterialNames.replace("；", ";").split(";");
                                        String[] var33 = materialList;
                                        int var34 = materialList.length;

                                        for(int var35 = 0; var35 < var34; ++var35) {
                                            String material = var33[var35];
                                            String[] materialSplit = material.split("&");
                                            if (materialSplit.length != 3) {
                                                data.setFailReason(material + "原料格式不正确");
                                                errorList.add(data);
                                                break;
                                            }

                                            String materialName = materialSplit[0];
                                            String materialType = materialSplit[1];
                                            String materialWeight = materialSplit[2];
                                            if (materialMap.get(materialName) == null) {
                                                data.setFailReason(materialName + "原料不存在");
                                                errorList.add(data);
                                                break;
                                            }

                                            if (!menuMaterialTypeList.contains(materialType)) {
                                                data.setFailReason(materialType + "原料类型填写错误");
                                                errorList.add(data);
                                                break;
                                            }

                                            if (!NumberUtil.isNumber(materialWeight)) {
                                                data.setFailReason(materialWeight + "原料重量不是数字");
                                                errorList.add(data);
                                                break;
                                            }

                                            BigDecimal weight = new BigDecimal(materialWeight);
                                            totalWeight = totalWeight.add(weight);
                                            if (BigDecimal.ZERO.compareTo(weight) > 0) {
                                                data.setFailReason(materialWeight + "原料重量为负数");
                                                errorList.add(data);
                                            }
                                        }

                                        if (ObjectUtil.isNotEmpty(data.getFailReason())) {
                                            continue;
                                        }
                                    }

                                    if (ObjectUtil.isNotEmpty(data.getCookName()) && dishesCookMap.get(data.getCookName()) == null) {
                                        data.setFailReason(data.getCookName() + "灶类不存在!");
                                        errorList.add(data);
                                    } else if (ObjectUtil.isNotNull(data.getUnitPrice()) && data.getUnitPrice() != 50 && data.getUnitPrice() != 100) {
                                        data.setFailReason("称重单位仅支持输入50或者100");
                                        errorList.add(data);
                                    } else {
                                        Long areaId;
                                        if (ObjectUtil.isNotEmpty(stallName)) {
                                            AllocStall allocStall = allocStallMap.get(stallName);
                                            if (allocStall == null) {
                                                data.setFailReason("档口名称不存在");
                                                errorList.add(data);
                                                continue;
                                            }

                                            if (ObjectUtil.isEmpty(canteenName)) {
                                                data.setFailReason("食堂名称不能为空");
                                                errorList.add(data);
                                                continue;
                                            }

                                            areaId = allocStall.getCanteenId();
                                            AllocCanteen allocCanteen = allocCanteenIdMap.get(areaId);
                                            if (!allocCanteen.getCanteenName().equals(canteenName)) {
                                                data.setFailReason("食堂：" + canteenName + "填写错误");
                                                errorList.add(data);
                                                continue;
                                            }
                                        }

                                        if (ObjectUtil.isNotEmpty(canteenName)) {
                                            AllocCanteen allocCanteen = allocCanteenMap.get(canteenName);
                                            if (allocCanteen == null) {
                                                data.setFailReason("食堂名称不存在");
                                                errorList.add(data);
                                                continue;
                                            }

                                            if (ObjectUtil.isEmpty(areaName)) {
                                                data.setFailReason("区域名称不能为空");
                                                errorList.add(data);
                                                continue;
                                            }

                                            areaId = allocCanteen.getAreaId();
                                            AllocArea allocArea = allocAreaIdMap.get(areaId);
                                            if (!allocArea.getAreaName().equals(areaName)) {
                                                data.setFailReason("区域：" + allocArea.getAreaName() + "填写错误");
                                                errorList.add(data);
                                                continue;
                                            }
                                        }

                                        if (ObjectUtil.isNotEmpty(areaName) && !areaMap.containsKey(areaName)) {
                                            data.setFailReason("区域名称不存在");
                                            errorList.add(data);
                                        } else {
                                            dishesNameList.add(itemDishesName);
                                            successList.add(data);
                                        }
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception var43) {
                    data.setFailReason(var43.getMessage());
                    errorList.add(data);
                }
            }

            dishesImportCheckResult.setErrorList(errorList);
            dishesImportCheckResult.setSuccessList(successList);
            return dishesImportCheckResult;
        }
    }

    @Override
    public Boolean newImportDishes(List<MenuDishesImportDTO> menuDishesImportDTOS) {
//        String dishesLockRedisKey = "yst:merchant-id:dishes:lock".replace("merchant-id", TenantContextHolder.getTenantId().toString());
//        String asyncState = this.stringRedisTemplate.opsForValue().get(dishesLockRedisKey);
//        if (StringUtils.isNotBlank(asyncState)) {
//            throw new ServiceException("导入菜品进行中,不要重复操作哦 ^_^");
//        } else {
        try {
            String currentTraceId = LogUtil.getCurrentTraceId();
            String username = SecurityUtils.getUsername();
            this.asyncTaskExecutor.execute(() -> {
                LogUtil.putLogTraceId(currentTraceId);
                log.info("[批量导入菜品]开始导入菜品");
                this.importDishesDTO(menuDishesImportDTOS, username);
            });
        } catch (Exception var7) {
            log.info("[批量导入菜品]系统错误：{}", var7.getMessage(), var7);
            throw new ServiceException("批量导入菜品发生错误");
        }
        return true;
//        }
    }



    public void importDishesDTO(List<MenuDishesImportDTO> importDishesList, String username) {
        DishesImportCheckResult dishesImportCheckResult = new DishesImportCheckResult();
        List<MenuDishesImportDTO> successList = new ArrayList<>();
        List<MenuDishesImportDTO> errorList = new ArrayList<>();
//        String dishesLockRedisKey = "yst:merchant-id:dishes:lock".replace("merchant-id", TenantContextHolder.getTenantId().toString());
//        this.stringRedisTemplate.opsForValue().set(dishesLockRedisKey, "1", 20L, TimeUnit.MINUTES);

        try {
            ImportDishesContext importDishesContext = this.getImportDishesContext(username);
            List<MenuDishes> dishesAddList = Lists.newArrayList();
            List<MenuDishesBase> dishesBaseList = Lists.newArrayList();
            List<MenuDishesSize> dishesSizeList = Lists.newArrayList();
            Iterator var11 = importDishesList.iterator();

            while(var11.hasNext()) {
                MenuDishesImportDTO importDishes = (MenuDishesImportDTO)var11.next();

                try {
                    String sizeTypeStr;
                    JSONObject sizeTypeJson;
                    if (MenuSalesTypeEnum.PORTION_ON.key().equals(importDishes.getSalesMode()) && importDishes.getSizeType() == 2L) {
                        MenuDishesBase dishesBase = this.generateBaseAndSize(dishesSizeList, importDishes.getDishesName(), "大份", "小份");
                        sizeTypeStr = importDishes.getDishesName();
                        MenuDishes dishesAddLa = this.generateDishes(importDishes, importDishesContext);
                        sizeTypeJson = new JSONObject();
                        sizeTypeJson.put("sizeType", "大份");
                        dishesAddLa.setBaseDishesId(dishesBase.getBaseDishesId());
                        dishesAddLa.setPrice(dishesAddLa.getLargePrice());
                        dishesAddLa.setWeight(dishesAddLa.getLargeWeight());
                        dishesAddLa.setSizeJson(sizeTypeJson.toJSONString());
                        dishesAddLa.setDishesName(sizeTypeStr + "-大份");
                        MenuDishes dishesAddLi = this.generateDishes(importDishes, importDishesContext);
                        JSONObject sizeTypeJsonLi = new JSONObject();
                        sizeTypeJsonLi.put("sizeType", "小份");
                        dishesAddLi.setBaseDishesId(dishesBase.getBaseDishesId());
                        dishesAddLi.setPrice(dishesAddLi.getLittlePrice());
                        dishesAddLi.setWeight(dishesAddLi.getLittleWeight());
                        dishesAddLi.setSizeJson(sizeTypeJsonLi.toJSONString());
                        dishesAddLi.setDishesName(sizeTypeStr + "-小份");
                        dishesAddLi.setCustomId(-1);
                        dishesBaseList.add(dishesBase);
                        dishesAddList.add(dishesAddLa);
                        dishesAddList.add(dishesAddLi);
                    } else {
                        MenuDishes dishesAdd = this.generateDishes(importDishes, importDishesContext);
                        sizeTypeStr = "";
                        if (MenuSalesTypeEnum.PORTION_ON.key().equals(importDishes.getSalesMode())) {
                            sizeTypeStr = "标准";
                        } else if (importDishes.getUnitPrice() == 50) {
                            sizeTypeStr = "50g";
                            dishesAdd.setWeight(50.0);
                        } else if (importDishes.getUnitPrice() == 100) {
                            sizeTypeStr = "100g";
                            dishesAdd.setWeight(100.0);
                        }

                        MenuDishesBase dishesBase = this.generateBaseAndSize(dishesSizeList, importDishes.getDishesName(), sizeTypeStr);
                        sizeTypeJson = new JSONObject();
                        sizeTypeJson.put("sizeType", sizeTypeStr);
                        dishesAdd.setBaseDishesId(dishesBase.getBaseDishesId());
                        dishesAdd.setSizeJson(sizeTypeJson.toJSONString());
                        dishesBaseList.add(dishesBase);
                        dishesAddList.add(dishesAdd);
                    }

                    successList.add(importDishes);
                } catch (Exception var23) {
                    log.error("导入菜品异常: ", var23);
                }
            }



            if (CollUtil.isNotEmpty(dishesAddList)) {
//                MenuDishesMapper var10001 = this.menuDishesMapper;
//                Objects.requireNonNull(var10001);
//                dishesAddList.forEach(var10001::insert);
                for (MenuDishes dishes : dishesAddList) {
                    dishes.setCustomId(-1);
                    this.menuDishesMapper.insertMenuDishes(dishes);
                }
                this.menuDishesBaseService.saveBatch(dishesBaseList);
                //  this.menuDishesSizeService.saveBatch(dishesSizeList);
            }

//            MqUtil.sendDataChange(dishesAddList, LeMqConstant.DataChangeType.ADD, LeMqConstant.Topic.DATA_CHANGE_DISHES);
//            dishesImportCheckResult.setSuccessList(successList);
//            dishesImportCheckResult.setErrorList(errorList);
//            String resultRedisKey = "yst:merchant-id:dishes:upgrade:result".replace("merchant-id", TenantContextHolder.getTenantId().toString());
//            RedisUtil.setString(resultRedisKey, JSONUtil.toJsonStr(dishesImportCheckResult), 60L);
        } catch (Exception var24) {
            //   this.stringRedisTemplate.delete(dishesLockRedisKey);
            log.error("导入异常: ", var24);
        } finally {
            //    this.stringRedisTemplate.delete(dishesLockRedisKey);
        }

    }


    public MenuDishes generateDishes(MenuDishesImportDTO importDishes, ImportDishesContext importDishesContext) {
        MenuDishes dishesAdd = new MenuDishes();
        Map<String, Long> typeMap = importDishesContext.getTypeMap();
        Map<String, Long> materialMap = importDishesContext.getMaterialMap();
        String username = importDishesContext.getUsername();
        Long defaultTypeId = importDishesContext.getDefaultTypeId();
        Map<String, Long> dishesCookMap = importDishesContext.getDishesCookMap();
        long dishesId = Id.next();
        dishesAdd.setDishesId(dishesId);
        dishesAdd.setDishesName(importDishes.getDishesName());
        //  String sequenceNo = this.menuSequenceService.getSequenceNo(2);
        //   dishesAdd.setDishesNum(sequenceNo);
        dishesAdd.setPrice(importDishes.getPrice().multiply(new BigDecimal("100")).intValue());
        dishesAdd.setSalesMode(importDishes.getSalesMode());
        dishesAdd.setCookId((Long)dishesCookMap.get(importDishes.getCookName()));
        // dishesAdd.setCustomId(this.menuCustomDictService.getNoRepeatCustomId(0));
        dishesAdd.setTypeId((Long)Optional.ofNullable((Long)typeMap.get(importDishes.getDishesTypeName())).orElse(defaultTypeId));
        dishesAdd.setPinyinInitials(PinyinUtil.getFirstLetterFromChinese(importDishes.getDishesName()));
        dishesAdd.setPinyinFull(PinyinUtil.convertChineseToPinyin(importDishes.getDishesName()));
        Integer unitPrice = (Integer)Optional.ofNullable(importDishes.getUnitPrice()).orElse(100);
        dishesAdd.setUnitPrice(unitPrice);
        this.setAllocData(importDishes, dishesAdd, importDishesContext);
        if (MenuSalesTypeEnum.PORTION_ON.key().equals(importDishes.getSalesMode())) {
            Long sizeType = (Long)Optional.ofNullable(importDishes.getSizeType()).orElse(1L);
            if (sizeType == 2L) {
                dishesAdd.setLargePrice(importDishes.getLargePrice().multiply(new BigDecimal("100")).intValue());
                dishesAdd.setLittlePrice(importDishes.getLittlePrice().multiply(new BigDecimal("100")).intValue());
                dishesAdd.setLargeWeight(importDishes.getLargeWeight());
                dishesAdd.setLittleWeight(importDishes.getLittleWeight());
            }

            dishesAdd.setSizeType(sizeType);
        }

        String menuMaterialNames = importDishes.getMenuMaterialNames();
        Double importDishesWeight = importDishes.getWeight();
        Double totalWeight = 0.0;
        if (CharSequenceUtil.isNotBlank(menuMaterialNames)) {
            ArrayList<MenuMaterialDishes> menuMaterialDishesList = Lists.newArrayList();
            String[] menuMaterials = menuMaterialNames.split(";");
            String[] var18 = menuMaterials;
            int var19 = menuMaterials.length;

            for(int var20 = 0; var20 < var19; ++var20) {
                String menuMaterial = var18[var20];
                String[] materialSplit = menuMaterial.split("&");
                String materialName = materialSplit[0];
                String materialType = materialSplit[1];
                String materialWeight = materialSplit[2];
                BigDecimal weight = new BigDecimal(materialWeight);
                Long materialId = (Long)materialMap.get(materialName);
                MenuMaterialDishes menuMaterialDishes = new MenuMaterialDishes();
                menuMaterialDishes.setMaterialType(Integer.valueOf(materialType));
                menuMaterialDishes.setMaterialId(materialId);
                menuMaterialDishes.setWeight(Double.valueOf(materialWeight));
                menuMaterialDishes.setDishesId(dishesId);
                menuMaterialDishes.setCreateBy(username);
                menuMaterialDishesList.add(menuMaterialDishes);
                totalWeight = totalWeight + weight.doubleValue();
            }

            this.menuRecipeMapper.insertMenuMateralDishes(menuMaterialDishesList);
            List<NutritionEntity> nutritionEntityList = this.selectNutritionWeightList(dishesId);
            if (CollUtil.isNotEmpty(nutritionEntityList)) {
                NutritionEntity nutritionEntity = NutritionEntityUtil.countNutrition(nutritionEntityList);
                BeanUtils.copyProperties(nutritionEntity, dishesAdd);
            }
        }

        if (ObjectUtil.isNotNull(importDishesWeight) && MenuSalesTypeEnum.PORTION_ON.key().equals(importDishes.getSalesMode())) {
            totalWeight = importDishesWeight;
        }

        dishesAdd.setWeight(totalWeight);
        return dishesAdd;
    }


    public List<NutritionEntity> selectNutritionWeightList(Long dishesId) {
        List<MenuMaterialDishes> menuMaterialDishes = this.menuMaterialDishesMapper.selectList(Wrappers.lambdaQuery(MenuMaterialDishes.class)
                .select(MenuMaterialDishes::getMaterialId, MenuMaterialDishes::getWeight).eq(MenuMaterialDishes::getDishesId, dishesId));
        if (ObjectUtils.isEmpty(menuMaterialDishes)) {
            return new ArrayList<>();
        } else {
            List<Long> materialIds = menuMaterialDishes.stream().map(MenuMaterialDishes::getMaterialId).collect(Collectors.toList());
            Map<Long, Double> materialWeight =
                    menuMaterialDishes.stream().collect(Collectors.toMap(MenuMaterialDishes::getMaterialId, MenuMaterialDishes::getWeight));
            Map<Long, MenuMaterialNutrition> data = this.getMenuMaterialNutrition(materialIds);
            List<NutritionEntity> result = new ArrayList<>();
            Iterator var7 = menuMaterialDishes.iterator();

            while(var7.hasNext()) {
                MenuMaterialDishes menuMaterialDish = (MenuMaterialDishes)var7.next();
                MenuMaterialNutrition menuMaterialNutrition = data.get(menuMaterialDish.getMaterialId());
                if (ObjectUtils.isNotEmpty(menuMaterialNutrition)) {
                    NutritionEntity nutritionEntity = BeanUtil.copyProperties(menuMaterialNutrition, NutritionEntity.class, new String[0]);
                    nutritionEntity.setWeight(materialWeight.get(menuMaterialDish.getMaterialId()));
                    nutritionEntity.setBaseWeight(100.0);
                    result.add(nutritionEntity);
                }
            }

            return result;
        }
    }



    public Map<Long, MenuMaterialNutrition> getMenuMaterialNutrition(List<Long> materialIdList) {
        List<MenuMaterialNutrition> menuMaterialNutritions = this.menuMaterialNutritionMapper
                .selectList(Wrappers.lambdaQuery(MenuMaterialNutrition.class)
                        .in(MenuMaterialNutrition::getMaterialId, materialIdList));
        Iterator var4;
        Long materialId;
        if (CollUtil.isNotEmpty(menuMaterialNutritions)) {
            Map<Long, MenuMaterialNutrition> collect = (Map) menuMaterialNutritions.stream().collect(Collectors.toMap(MenuMaterialNutrition::getMaterialId, (e) -> {
                return e;
            }, (o, n) -> {
                return o;
            }));
            if (menuMaterialNutritions.size() == materialIdList.size()) {
                return collect;
            } else {
                var4 = materialIdList.iterator();

                while (var4.hasNext()) {
                    materialId = (Long) var4.next();
                    Long finalMaterialId = materialId;
                    collect.computeIfAbsent(materialId, (k) -> {
                        MenuNutritionDetailVO result = this.menuRecipeMapper.getMenuNutritionDetailById(this.getByMaterialId(finalMaterialId).getNutritionId());
                        MenuMaterialNutrition menuMaterialNutrition = new MenuMaterialNutrition();
                        BeanUtil.copyProperties(result, menuMaterialNutrition, new String[0]);
                        return menuMaterialNutrition;
                    });
                }

                return collect;
            }
        } else {
            Map<Long, MenuMaterialNutrition> collect = new HashMap();
            var4 = materialIdList.iterator();

            while (var4.hasNext()) {
                materialId = (Long) var4.next();
                MenuNutritionDetailVO result = this.menuRecipeMapper
                        .getMenuNutritionDetailById(this.getByMaterialId(materialId).getNutritionId());
                MenuMaterialNutrition menuMaterialNutrition = new MenuMaterialNutrition();
                BeanUtil.copyProperties(result, menuMaterialNutrition, new String[0]);
                collect.put(materialId, menuMaterialNutrition);
            }

            return collect;
        }
    }



    public MenuMaterial getByMaterialId(Long materialId) {
        return this.menuMaterialMapper.selectMenuMaterialMaterialId(materialId);
    }



    public void setAllocData(MenuDishesImportDTO importDishes, MenuDishes dishesAdd, ImportDishesContext importDishesContext) {
        Long stallId = -1L;
        Long canteenId = -1L;
        Long areaId = -1L;
        Map<String, Long> stallMap = importDishesContext.getStallMap();
        Map<Long, Long> canteenStallMap = importDishesContext.getCanteenStallMap();
        Map<Long, Long> areaCanteenMap = importDishesContext.getAreaCanteenMap();
        Map<String, Long> canteenMap = importDishesContext.getCanteenMap();
        Map<String, AllocArea> allocAreaMap = importDishesContext.getAllocAreaMap();
        if (ObjectUtil.isNotEmpty(importDishes.getStallName())) {
            stallId = (Long)stallMap.get(importDishes.getStallName());
            canteenId = (Long)canteenStallMap.get(stallId);
            areaId = (Long)areaCanteenMap.get(canteenId);
        } else if (ObjectUtil.isNotEmpty(importDishes.getCanteenName())) {
            canteenId = (Long)canteenMap.get(importDishes.getCanteenName());
            areaId = (Long)areaCanteenMap.get(canteenId);
        } else if (ObjectUtil.isNotEmpty(importDishes.getAreaName())) {
            areaId = ((AllocArea)allocAreaMap.get(importDishes.getAreaName())).getAreaId();
        }

        dishesAdd.setCanteenId(canteenId);
        dishesAdd.setAreaId(areaId);
        dishesAdd.setShopstallId(stallId);
    }

    public MenuDishesBase generateBaseAndSize(List<MenuDishesSize> dishesSizeList, String dishesName, String... sizeTypeStrArr) {
        MenuDishesBase dishesBase = new MenuDishesBase();
        Long baseDishesId = Id.next();
        dishesBase.setBaseDishesId(baseDishesId);
        dishesBase.setDishesName(dishesName);
        String[] var6 = sizeTypeStrArr;
        int var7 = sizeTypeStrArr.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            String sizeTypeStr = var6[var8];
            MenuDishesSize dishesSize = new MenuDishesSize();
            dishesSize.setBaseDishesId(baseDishesId);
            dishesSize.setSizeId(Id.next());
            dishesSize.setSizeName(sizeTypeStr);
            dishesSizeList.add(dishesSize);
        }

        return dishesBase;
    }


    public ImportDishesContext getImportDishesContext(String username) {
        ImportDishesContext importDishesContext = new ImportDishesContext();
        List<MapBean> materialMapList = menuRecipeMapper.getMenuMaterialMap();
        Map<String, Long> materialMap = new HashMap<>();
        materialMapList.forEach(map -> {
            materialMap.put(map.getKey(), toLong(map.getValue()));
        });

        Long defaultTypeId = this.getDefaultTypeId();

        List<AllocArea> allocAreaList = allocAreaService.selectAllocAreaList(null);
        Map<String, AllocArea> areaMap = new HashMap<>();
        allocAreaList.forEach(allocArea -> {
            String areaName = allocArea.getAreaName();
            if (areaName != null) {
                areaMap.put(areaName, allocArea);
            }
        });

        List<AllocCanteen> allocCanteenList = allocCanteenService.selectAllocCanteenList(null);
        Map<String, AllocCanteen> canteenMap = new HashMap<>();
        allocCanteenList.forEach(allocCanteen -> {
            String canteenName = allocCanteen.getCanteenName();
            if (canteenName != null) {
                canteenMap.put(canteenName, allocCanteen);
            }
        });

        List<AllocStall> allocStallList = allocStallService.selectAllocStallList(null);
        Map<String, AllocStall> stallMap = new HashMap<>();
        allocStallList.forEach(allocStall -> {
            String stallName = allocStall.getStallName();
            if (stallName != null) {
                stallMap.put(stallName, allocStall);
            }
        });

        List<MapBean>  typeMapList = this.menuRecipeMapper.getMenuMaterialTypeMap();
        Map<String, Long> typeMap =  new HashMap<>();
        typeMapList.forEach(map -> {
            typeMap.put(map.getKey(), toLong(map.getValue()));
        });


        List<MapBean> dishesCookMList = this.menuRecipeMapper.getDishesCookMap();
        Map<String, Long> dishesCookMap =  new HashMap<>();
        dishesCookMList.forEach(map -> {
            dishesCookMap.put(map.getKey(), toLong(map.getValue()));
        });

        importDishesContext.setAllocAreaMap(areaMap);
        importDishesContext.setAllocStallMap(stallMap);
        importDishesContext.setAllocCanteenMap(canteenMap);
        importDishesContext.setTypeMap(typeMap);
        importDishesContext.setMaterialMap(materialMap);
        importDishesContext.setDefaultTypeId(defaultTypeId);
        importDishesContext.setUsername(username);
        importDishesContext.setDishesCookMap(dishesCookMap);
        return importDishesContext;
    }

    public Long getDefaultTypeId() {
        Long typeId = this.menuRecipeMapper.selectDefaultTypeId(MenuDishesTypeDefaultFlagEnum.DEFAULT.key());
        if (ObjectUtil.isNull(typeId)) {
            MenuDishesType dishesType = new MenuDishesType();
            typeId = Id.next();
            dishesType.setTypeId(typeId);
            dishesType.setTypeName("默认");
            dishesType.setAliasName("default");
            dishesType.setDefaultFlag(MenuDishesTypeDefaultFlagEnum.DEFAULT.key());
            this.menuRecipeMapper.insertMenuDishesType(dishesType);
        }

        return typeId;
    }

    private Long toLong(Object value) {
        if (value == null) return 0L;
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        try {
            return Long.parseLong(value.toString());
        } catch (NumberFormatException e) {
            return 0L; // 或抛出异常
        }
    }


    @Override
    public List<MenuDishes> getByNames(Set<String> dishesNames) {
        return this.list(Wrappers.lambdaQuery(MenuDishes.class)
                //.eq(MenuDishes::getDelFlag, DelFlagEnum.DEL_FALSE.key())
                .in(MenuDishes::getDishesName, dishesNames));
    }
}
