package cn.iocoder.yudao.module.pms.service.iotcommonbommaterial;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.pms.controller.admin.iotcommonbommaterial.vo.IotCommonBomMaterialPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotcommonbommaterial.vo.IotCommonBomMaterialSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotcommonbommaterial.IotCommonBomMaterialDO;
import cn.iocoder.yudao.module.pms.dal.mysql.iotcommonbommaterial.IotCommonBomMaterialMapper;
import cn.iocoder.yudao.module.pms.service.iotbom.IotBomService;
import com.google.common.collect.ImmutableMap;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_COMMON_BOM_MATERIAL_EXISTS;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_COMMON_BOM_MATERIAL_NOT_EXISTS;

/**
 * PMS 设备分类公共BOM挂载物料关联 Service 实现类
 *
 * @author ruiqi
 */
@Service
@Validated
public class IotCommonBomMaterialServiceImpl implements IotCommonBomMaterialService {

    @Resource
    private IotCommonBomMaterialMapper iotCommonBomMaterialMapper;
    @Resource
    private IotBomService iotBomService;

    @Override
    public Long createIotCommonBomMaterial(IotCommonBomMaterialSaveReqVO createReqVO) {
        // 插入
        IotCommonBomMaterialDO iotCommonBomMaterial = BeanUtils.toBean(createReqVO, IotCommonBomMaterialDO.class);
        // 校验 相同节点下是否存在相同id的物料
        List<IotCommonBomMaterialDO> commonBomMaterials = iotCommonBomMaterialMapper.selectList(createReqVO);
        if (CollUtil.isNotEmpty(commonBomMaterials)) {
            throw exception(IOT_COMMON_BOM_MATERIAL_EXISTS);
        }
        iotCommonBomMaterialMapper.insert(iotCommonBomMaterial);
        // 将设备分类BOM及BOM节点挂载的物料同步到设备BOM
        iotBomService.syncDeviceBomAndMaterials(iotCommonBomMaterial.getDeviceCategoryId());
        // 返回
        return iotCommonBomMaterial.getId();
    }

    @Override
    public void updateIotCommonBomMaterial(IotCommonBomMaterialSaveReqVO updateReqVO) {
        // 校验存在
        validateIotCommonBomMaterialExists(updateReqVO.getId());
        // 更新
        IotCommonBomMaterialDO updateObj = BeanUtils.toBean(updateReqVO, IotCommonBomMaterialDO.class);
        iotCommonBomMaterialMapper.updateById(updateObj);
        // 更新此设备分类下的设备BOM (如果设备BOM的 bom_sync_status = 0)
        iotBomService.syncDeviceBomAndMaterials(updateReqVO.getDeviceCategoryId());
    }

    @Override
    public void deleteIotCommonBomMaterial(Long id) {
        // 校验存在
        validateIotCommonBomMaterialExists(id);
        // 删除
        iotCommonBomMaterialMapper.deleteById(id);
    }

    private void validateIotCommonBomMaterialExists(Long id) {
        if (iotCommonBomMaterialMapper.selectById(id) == null) {
            throw exception(IOT_COMMON_BOM_MATERIAL_NOT_EXISTS);
        }
    }

    @Override
    public IotCommonBomMaterialDO getIotCommonBomMaterial(Long id) {
        return iotCommonBomMaterialMapper.selectById(id);
    }

    @Override
    public PageResult<IotCommonBomMaterialDO> getIotCommonBomMaterialPage(IotCommonBomMaterialPageReqVO pageReqVO) {
        return iotCommonBomMaterialMapper.selectPage(pageReqVO);
    }

    @Override
    public List<IotCommonBomMaterialDO> getIotCommonBomMaterials(IotCommonBomMaterialSaveReqVO reqVO) {
        return iotCommonBomMaterialMapper.selectList1(reqVO);
    }

    @Override
    public void deleteBomMaterial(Long bomNodeId, String code) {
        if (ObjUtil.isEmpty(bomNodeId) || StrUtil.isBlank(code)) {
            throw exception(IOT_COMMON_BOM_MATERIAL_NOT_EXISTS);
        }
        // 查询指定 bomNodeId code 的记录是否存在
        IotCommonBomMaterialSaveReqVO reqVO = new IotCommonBomMaterialSaveReqVO();
        reqVO.setBomNodeId(bomNodeId);
        reqVO.setCode(code);
        List<IotCommonBomMaterialDO> bomMaterials = iotCommonBomMaterialMapper.selectList(reqVO);
        if (CollUtil.isEmpty(bomMaterials)) {
            throw exception(IOT_COMMON_BOM_MATERIAL_NOT_EXISTS);
        }
        int count = iotCommonBomMaterialMapper.deleteByMap(ImmutableMap.of(
                "bom_node_id", bomNodeId,
                "code", code
        ));
        // 将设备分类BOM及BOM节点挂载的物料同步到设备BOM
        iotBomService.syncDeviceBomAndMaterials(bomMaterials.get(0).getDeviceCategoryId());
    }

    @Override
    public Long addMaterials(List<IotCommonBomMaterialSaveReqVO> materials) {
        Long resultCount = 0L;
        if (CollUtil.isEmpty(materials)) {
            throw exception(IOT_COMMON_BOM_MATERIAL_NOT_EXISTS);
        }
        Long bomNodeId = materials.get(0).getBomNodeId();
        if (ObjUtil.isEmpty(bomNodeId)) {
            throw exception(IOT_COMMON_BOM_MATERIAL_NOT_EXISTS);
        }
        // 先查询当前BOM节点下所有物料 与要添加的物料匹配 筛选出在数据库中不存在的物料 插入到数据库
        IotCommonBomMaterialSaveReqVO reqVO = new IotCommonBomMaterialSaveReqVO();
        reqVO.setBomNodeId(bomNodeId);
        List<IotCommonBomMaterialDO> existMaterials = iotCommonBomMaterialMapper.selectList(reqVO);
        List<IotCommonBomMaterialSaveReqVO> newMaterials = new ArrayList<>();
        if (CollUtil.isNotEmpty(existMaterials)) {
            // 提取已存在的物料编码集合
            Set<String> existCodes = existMaterials.stream()
                    .map(IotCommonBomMaterialDO::getCode) // 获取DO对象的code字段
                    .filter(Objects::nonNull)             // 过滤可能的null值
                    .collect(Collectors.toSet());
            // 筛选出不存在的物料
            newMaterials = materials.stream()
                    .filter(material -> material.getCode() != null)     // 确保物料编码不为null
                    .filter(material -> !existCodes.contains(material.getCode())) // 检查是否不存在
                    .collect(Collectors.toList());
        } else {
            newMaterials = materials;
        }
        List<IotCommonBomMaterialDO> tobeAddedMaterials = new ArrayList<>();
        if (CollUtil.isNotEmpty(newMaterials)) {
            newMaterials.forEach(material -> {
                IotCommonBomMaterialDO iotCommonBomMaterial = BeanUtils.toBean(material, IotCommonBomMaterialDO.class);
                tobeAddedMaterials.add(iotCommonBomMaterial);
            });
            iotCommonBomMaterialMapper.insertBatch(tobeAddedMaterials);
            resultCount = Long.valueOf(tobeAddedMaterials.size());
            // 将设备分类BOM及BOM节点挂载的物料同步到设备BOM
            iotBomService.syncDeviceBomAndMaterials(tobeAddedMaterials.get(0).getDeviceCategoryId());
        }
        return resultCount;
    }

}