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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicematerial.vo.IotDeviceMaterialPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbommaterial.vo.IotMainWorkOrderBomMaterialPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbommaterial.vo.IotMainWorkOrderBomMaterialRespVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorderbommaterial.vo.IotMainWorkOrderBomMaterialSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicematerial.IotDeviceMaterialDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorderbommaterial.IotMainWorkOrderBomMaterialDO;
import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicematerial.IotDeviceMaterialMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotmainworkorderbommaterial.IotMainWorkOrderBomMaterialMapper;
import cn.iocoder.yudao.module.pms.service.IotDeviceService;
import cn.iocoder.yudao.module.pms.service.iotcommonbommaterial.IotCommonBomMaterialService;
import cn.iocoder.yudao.module.pms.service.iotdevicematerial.IotDeviceMaterialService;
import cn.iocoder.yudao.module.system.api.dept.DeptSapOrgApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptSapOrgRespDTO;
import cn.iocoder.yudao.module.system.api.saporg.SapOrgApi;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
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.pms.enums.ErrorCodeConstant.IOT_MAIN_WORK_ORDER_BOM_MATERIAL_NOT_EXISTS;


/**
 * PMS 保养工单明细设备BOM挂载物料关联 Service 实现类
 *
 * @author ruiqi
 */
@Service
@Validated
public class IotMainWorkOrderBomMaterialServiceImpl implements IotMainWorkOrderBomMaterialService {

    @Resource
    private IotMainWorkOrderBomMaterialMapper iotMainWorkOrderBomMaterialMapper;
    @Autowired
    private DeptService deptService;
    @Autowired
    private IotCommonBomMaterialService iotCommonBomMaterialService;
    @Autowired
    private IotDeviceMaterialService iotDeviceMaterialService;
    @Autowired
    private IotDeviceService iotDeviceService;
    @Autowired
    private SapOrgApi sapOrgApi;
    @Autowired
    private DeptSapOrgApi deptSapOrgApi;
    @Autowired
    private IotDeviceMaterialMapper iotDeviceMaterialMapper;

    @Override
    public Long createIotMainWorkOrderBomMaterial(IotMainWorkOrderBomMaterialSaveReqVO createReqVO) {
        // 插入
        IotMainWorkOrderBomMaterialDO iotMainWorkOrderBomMaterial = BeanUtils.toBean(createReqVO, IotMainWorkOrderBomMaterialDO.class);
        iotMainWorkOrderBomMaterialMapper.insert(iotMainWorkOrderBomMaterial);
        // 返回
        return iotMainWorkOrderBomMaterial.getId();
    }

    @Override
    public void updateIotMainWorkOrderBomMaterial(IotMainWorkOrderBomMaterialSaveReqVO updateReqVO) {
        // 校验存在
        validateIotMainWorkOrderBomMaterialExists(updateReqVO.getId());
        // 更新
        IotMainWorkOrderBomMaterialDO updateObj = BeanUtils.toBean(updateReqVO, IotMainWorkOrderBomMaterialDO.class);
        iotMainWorkOrderBomMaterialMapper.updateById(updateObj);
    }

    @Override
    public void deleteIotMainWorkOrderBomMaterial(Long id) {
        // 校验存在
        validateIotMainWorkOrderBomMaterialExists(id);
        // 删除
        iotMainWorkOrderBomMaterialMapper.deleteById(id);
    }

    private void validateIotMainWorkOrderBomMaterialExists(Long id) {
        if (iotMainWorkOrderBomMaterialMapper.selectById(id) == null) {
            throw exception(IOT_MAIN_WORK_ORDER_BOM_MATERIAL_NOT_EXISTS);
        }
    }

    @Override
    public IotMainWorkOrderBomMaterialDO getIotMainWorkOrderBomMaterial(Long id) {
        return iotMainWorkOrderBomMaterialMapper.selectById(id);
    }

    @Override
    public PageResult<IotMainWorkOrderBomMaterialDO> getIotMainWorkOrderBomMaterialPage(IotMainWorkOrderBomMaterialPageReqVO pageReqVO) {
        return iotMainWorkOrderBomMaterialMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<IotMainWorkOrderBomMaterialRespVO> selectMaterialsByDept(IotMainWorkOrderBomMaterialPageReqVO pageReqVO) {
        // 根据 设备 关联的 SAP工厂 库存地点 成本中心 查询 本地库存 SAP库存
        // 查询设备所属的部门
        IotDeviceDO device = iotDeviceService.getIotDevice(pageReqVO.getDeviceId());
        if (ObjUtil.isEmpty(device)) {
            throw exception(IOT_MAIN_WORK_ORDER_BOM_MATERIAL_NOT_EXISTS);
        }
        if (Objects.isNull(device.getDeptId())) {
            throw exception(IOT_MAIN_WORK_ORDER_BOM_MATERIAL_NOT_EXISTS);
        }
        // 查询设备所属部门下的所有子部门列表
        Set<Long> ids = new HashSet<>();
        ids = deptService.getChildDeptIdListFromCache(device.getDeptId());
        ids.add(device.getDeptId());
        // 查询设备所属部门关联的SAP工厂 成本中心 库存地点
        List<DeptSapOrgRespDTO> sapOrgS = deptSapOrgApi.getSapOrgListByDeptIds(ids);
        Set<Long> factoryIds = new HashSet<>();
        Set<Long> costCenterIds = new HashSet<>();
        Set<Long> stockLocationIds = new HashSet<>();
        if (CollUtil.isEmpty(sapOrgS)) {
            // throw exception(IOT_MAIN_WORK_ORDER_BOM_MATERIAL_NOT_EXISTS);
            // todo 应该有必要的提示信息 部门需要维护SAP组织信息 不维护组织部门的SAP属性 查询所有数据
            // return new PageResult<>(new ArrayList<>(), 0l);
        }
        sapOrgS.forEach(sapOrg -> {
            if (ObjUtil.isNotEmpty(sapOrg.getFactoryId())) {
                factoryIds.add(sapOrg.getFactoryId());
            }
            if (ObjUtil.isNotEmpty(sapOrg.getCostCenterId())) {
                costCenterIds.add(sapOrg.getCostCenterId());
            }
            if (ObjUtil.isNotEmpty(sapOrg.getStockLocationId())) {
                stockLocationIds.add(sapOrg.getStockLocationId());
            }
        });
        // IotDeviceMaterialSaveReqVO reqVO = new IotDeviceMaterialSaveReqVO();
        // reqVO.setBomNodeId(pageReqVO.getBomNodeId());
        // List<IotDeviceMaterialDO> bomMaterials = iotDeviceMaterialService.getIotDeviceMaterials(reqVO);
        IotDeviceMaterialPageReqVO materialReqVO = new IotDeviceMaterialPageReqVO();
        materialReqVO.setDeviceId(device.getId());
        materialReqVO.setBomNodeId(pageReqVO.getBomNodeId());
        List<IotDeviceMaterialDO> bomMaterials = iotDeviceMaterialMapper.selectList(materialReqVO);
        List<String> materialCodes = new ArrayList<>();
        Map<String, IotDeviceMaterialDO> bomNodePair = new HashMap<>();
        if (CollUtil.isNotEmpty(bomMaterials)) {
            materialCodes = bomMaterials.stream()
                    .map(IotDeviceMaterialDO::getCode) // 提取每个元素的 code 属性
                    .collect(Collectors.toList());
            // 组装每个bomNodeId关联的物料编码
            bomNodePair = CollectionUtils.convertMap(bomMaterials, IotDeviceMaterialDO::getCode);
        }
        IPage<IotMainWorkOrderBomMaterialRespVO> iotMaintainMaterialDOIPage =
                iotMainWorkOrderBomMaterialMapper.selectMaterialsBySapOrg(Page.of(pageReqVO.getPageNo(), pageReqVO.getPageSize()),
                         null, materialCodes, factoryIds, costCenterIds, stockLocationIds,
                        pageReqVO.getMaterialName(), pageReqVO.getMaterialCode());
        List<IotMainWorkOrderBomMaterialRespVO> materials = iotMaintainMaterialDOIPage.getRecords();
        if (CollUtil.isNotEmpty(materials)) {
            for (IotMainWorkOrderBomMaterialRespVO material : materials) {
                if (bomNodePair.containsKey(material.getMaterialCode())){
                    material.setBomMaterialFlag("Y");
                }
            }
        }
        return new PageResult<>(iotMaintainMaterialDOIPage.getRecords(), iotMaintainMaterialDOIPage.getTotal());
    }

    @Override
    public List<IotMainWorkOrderBomMaterialDO> getIotMainWorkOrderBomMaterialList(IotMainWorkOrderBomMaterialPageReqVO pageReqVO) {
        List<IotMainWorkOrderBomMaterialDO> workOrderMaterials = iotMainWorkOrderBomMaterialMapper.selectList(pageReqVO);
        return workOrderMaterials;
    }
}