//package cn.iocoder.yudao.module.iot.service.recipe;
//
//import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
//import org.springframework.stereotype.Service;
//import javax.annotation.Resource;
//import org.springframework.validation.annotation.Validated;
//import org.springframework.transaction.annotation.Transactional;
//
//import java.util.*;
//import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.*;
//import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO;
//import cn.iocoder.yudao.framework.common.pojo.PageResult;
//import cn.iocoder.yudao.framework.common.pojo.PageParam;
//import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
//
//import cn.iocoder.yudao.module.iot.dal.mysql.recipe.RecipeMapper;
//import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
//
//import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
//import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.*;
//
//import cn.iocoder.yudao.framework.common.exception.ServiceException;
//import cn.hutool.core.util.StrUtil;
//import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
//import cn.iocoder.yudao.framework.common.exception.ServiceException;
//
//import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO; // 引入现有DeviceDO
//import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper; // 引入现有DeviceMapper
//
///**
// * 配方管理主 Service 实现类
// *
// * @author 内蒙必硕
// */
//@Service
//@Validated
//public class RecipeServiceImpl implements RecipeService {
//
//    @Resource
//    private RecipeMapper recipeMapper;
//
////    @Override
////    public Long createRecipe(RecipeSaveReqVO createReqVO) {
////        // 插入
////        RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class);
////        recipeMapper.insert(recipe);
////        // 返回
////        return recipe.getId();
////    }
//@Override
//public Long createRecipe(RecipeSaveReqVO createReqVO) {
//    String recipeCode = createReqVO.getRecipeCode();
//
//    // 1. 校验recipeCode不为空（使用新增的RECIPE_CODE_EMPTY错误码）
//    if (StrUtil.isBlank(recipeCode)) {
//        throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_EMPTY);
//    }
//
//    // 2. 校验recipeCode是否重复（使用新增的RECIPE_CODE_DUPLICATE错误码）
//    boolean exists = recipeMapper.exists(
//            new LambdaQueryWrapperX<RecipeDO>().eq(RecipeDO::getRecipeCode, recipeCode)
//    );
//    if (exists) {
//        throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_DUPLICATE);
//    }
//
//    // ========== 原有逻辑保持不变 ==========
//    RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class);
//    recipeMapper.insert(recipe);
//    return recipe.getId();
//}
//
//    @Override
//    public void updateRecipe(RecipeSaveReqVO updateReqVO) {
//        // 校验存在
//        validateRecipeExists(updateReqVO.getId());
//        // 更新
//        RecipeDO updateObj = BeanUtils.toBean(updateReqVO, RecipeDO.class);
//        recipeMapper.updateById(updateObj);
//    }
//
//    @Override
//    public void deleteRecipe(Long id) {
//        // 校验存在
//        validateRecipeExists(id);
//        // 删除
//        recipeMapper.deleteById(id);
//    }
//
//    private void validateRecipeExists(Long id) {
//        if (recipeMapper.selectById(id) == null) {
//            throw exception(RECIPE_NOT_EXISTS);
//        }
//    }
//
//    @Override
//    public RecipeDO getRecipe(Long id) {
//        return recipeMapper.selectById(id);
//    }
//
//}
package cn.iocoder.yudao.module.iot.service.recipe;

import cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipePageReqVO;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipeRespVO;
import cn.iocoder.yudao.module.iot.controller.admin.recipe.vo.RecipeSaveReqVO;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipe.RecipeDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.recipetype.RecipeTypeDO;
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.recipe.RecipeMapper;
import cn.iocoder.yudao.module.iot.service.recipetype.RecipeTypeService;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.RECIPE_NOT_EXISTS;

/**
 * 配方管理主 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class RecipeServiceImpl implements RecipeService {

    @Resource
    private RecipeMapper recipeMapper;
    @Resource
    private DeviceMapper deviceMapper; // 注入现有DeviceMapper
    @Resource
    private ErpProductService erpProductService;
    @Resource
    private RecipeTypeService recipeTypeService;

    // ========== 原有方法保持不变 ==========
    @Override
    public Long createRecipe(RecipeSaveReqVO createReqVO) {
        String recipeCode = createReqVO.getRecipeCode();
        if (StrUtil.isBlank(recipeCode)) {
            throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_EMPTY);
        }
        boolean exists = recipeMapper.exists(
                new LambdaQueryWrapperX<RecipeDO>().eq(RecipeDO::getRecipeCode, recipeCode)
        );
        if (exists) {
            throw new ServiceException(ErrorCodeConstants.RECIPE_CODE_DUPLICATE);
        }

        // 根据 ID 获取对应的名称
        String productName = null;
        if (createReqVO.getProductId() != null) {
            ErpProductDO product = erpProductService.getProduct(createReqVO.getProductId());
            if (product != null) {
                productName = product.getName();
            }
        }

        String machineName = null;
        if (createReqVO.getMachineId() != null) {
            DeviceDO device = deviceMapper.selectById(createReqVO.getMachineId());
            if (device != null) {
                machineName = device.getDeviceName();
            }
        }

        String recipeType = null;
        if (createReqVO.getRecipeTypeId() != null) {
            RecipeTypeDO recipeTypeDO = recipeTypeService.getRecipeType(createReqVO.getRecipeTypeId());
            if (recipeTypeDO != null) {
                recipeType = recipeTypeDO.getName();
            }
        }

        // 创建配方对象并设置属性
        RecipeDO recipe = BeanUtils.toBean(createReqVO, RecipeDO.class);
        recipe.setProductName(productName);
        recipe.setMachineName(machineName);
        recipe.setRecipeType(recipeType);

        recipeMapper.insert(recipe);
        return recipe.getId();
    }

    @Override
    public void updateRecipe(RecipeSaveReqVO updateReqVO) {
        validateRecipeExists(updateReqVO.getId());

        // 根据 ID 获取对应的名称
        String productName = null;
        if (updateReqVO.getProductId() != null) {
            ErpProductDO product = erpProductService.getProduct(updateReqVO.getProductId());
            if (product != null) {
                productName = product.getName();
            }
        }

        String machineName = null;
        if (updateReqVO.getMachineId() != null) {
            DeviceDO device = deviceMapper.selectById(updateReqVO.getMachineId());
            if (device != null) {
                machineName = device.getDeviceName();
            }
        }

        String recipeType = null;
        if (updateReqVO.getRecipeTypeId() != null) {
            RecipeTypeDO recipeTypeDO = recipeTypeService.getRecipeType(updateReqVO.getRecipeTypeId());
            if (recipeTypeDO != null) {
                recipeType = recipeTypeDO.getName();
            }
        }

        // 创建更新对象并设置属性
        RecipeDO updateObj = BeanUtils.toBean(updateReqVO, RecipeDO.class);
        updateObj.setProductName(productName);
        updateObj.setMachineName(machineName);
        updateObj.setRecipeType(recipeType);

        recipeMapper.updateById(updateObj);
    }

    @Override
    public void deleteRecipe(Long id) {
        validateRecipeExists(id);
        recipeMapper.deleteById(id);
    }

    private void validateRecipeExists(Long id) {
        if (recipeMapper.selectById(id) == null) {
            throw exception(RECIPE_NOT_EXISTS);
        }
    }

    @Override
    public RecipeDO getRecipe(Long id) {
        return recipeMapper.selectById(id);
    }

    @Override
    public PageResult<RecipeDO> getRecipePage(RecipePageReqVO pageReqVO) {
        return recipeMapper.selectPage(pageReqVO);
    }

    // ========== 新增带deviceId的方法（改为public，供Controller直接调用） ==========
    /**
     * 分页查询配方，包含deviceId字段
     */
    public PageResult<RecipeRespVO> getRecipePageWithDeviceId(RecipePageReqVO pageReqVO) {
        // 1. 查询配方分页数据
        PageResult<RecipeDO> recipePage = recipeMapper.selectPage(pageReqVO);
        List<RecipeDO> recipeList = recipePage.getList();
        if (recipeList.isEmpty()) {
            return PageResult.empty(recipePage.getTotal());
        }

        // 2. 提取所有machineName，批量查询deviceId（避免N+1查询）
        List<String> machineNames = recipeList.stream()
                .map(RecipeDO::getMachineName)
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        // 调用现有DeviceMapper查询设备名称->ID映射
        List<DeviceDO> deviceList = deviceMapper.selectList(
                new LambdaQueryWrapperX<DeviceDO>().in(DeviceDO::getDeviceName, machineNames)
        );
        // 构建设备名称到ID的映射（处理重复名称，取第一个）
        Map<String, Long> deviceName2IdMap = new HashMap<>();
        for (DeviceDO device : deviceList) {
            deviceName2IdMap.putIfAbsent(device.getDeviceName(), device.getId());
        }

        // 3. 转换为VO并设置deviceId
        List<RecipeRespVO> respVOList = new ArrayList<>();
        for (RecipeDO recipe : recipeList) {
            RecipeRespVO respVO = BeanUtils.toBean(recipe, RecipeRespVO.class);
            // 根据machineName关联设置deviceId
            respVO.setDeviceId(deviceName2IdMap.get(recipe.getMachineName()));
            respVOList.add(respVO);
        }

        return new PageResult<>(respVOList, recipePage.getTotal());
    }

    /**
     * 查询单个配方，包含deviceId字段
     */
    public RecipeRespVO getRecipeWithDeviceId(Long id) {
        RecipeDO recipe = getRecipe(id);
        if (recipe == null) {
            return null;
        }
        RecipeRespVO respVO = BeanUtils.toBean(recipe, RecipeRespVO.class);
        // 关联查询deviceId
        if (recipe.getMachineName() != null) {
            DeviceDO device = deviceMapper.selectOne(
                    new LambdaQueryWrapperX<DeviceDO>().eq(DeviceDO::getDeviceName, recipe.getMachineName())
            );
            if (device != null) {
                respVO.setDeviceId(device.getId());
            }
        }
        return respVO;
    }
}