package com.sw.mes.store.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.store.dto.WarehouseModelDto;
import com.sw.mes.store.entity.WarehouseInventory;
import com.sw.mes.store.entity.WarehouseModel;
import com.sw.mes.store.mapper.WarehouseModelMapper;
import com.sw.mes.store.service.WarehouseInventoryService;
import com.sw.mes.store.service.WarehouseModelService;
import org.apache.commons.collections4.CollectionUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author wupeng
 * @Description 线边仓模型Service实现
 * @Date 11:14 2023/7/24
 * @Param
 * @return
 **/
@Service
public class WarehouseModelServiceImpl extends ServiceImpl<WarehouseModelMapper, WarehouseModel>
        implements WarehouseModelService {
    @Autowired
    private WarehouseModelMapper warehouseModelMapper;

    @Autowired
    private WarehouseInventoryService inventoryService;

    @Autowired
    private ModelMapper modelMapper;


    @Override
    public Result removeWithCheck(Long[] ids) {
        for (Long id : ids) {
            WarehouseModel warehouseModel = this.getById(id);
            if (null == warehouseModel) {
                return ResultGenerator.fail("该对象不存在");
            }
            List<Long> typeIds = new ArrayList<>();
            //查询ID下面的子节点
            List<WarehouseModel> types = warehouseModelMapper.findByParentId(id);
            typeIds.add(id);
            typeIds.addAll(types.stream().map(e -> e.getId()).collect(Collectors.toList()));
            //查询当前节点或子节点类型下是否关联了物料主数据
            List<WarehouseInventory> byWarehouseId = inventoryService.getByWarehouseIds(typeIds);
            if (byWarehouseId != null && byWarehouseId.size() > 0) {
                return ResultGenerator.fail("该仓库下存在关联的库存数据，不能删除！");
            } else {
                //删除当前节点及其子节点
                this.removeByIds(typeIds);
            }
        }
        return ResultGenerator.success();
    }

    @Override
    public List<WarehouseModelDto> getChildLocationIds(Long parentId) {
        List<WarehouseModelDto> storeLocations = new ArrayList<WarehouseModelDto>();
        addChild(storeLocations, parentId);
        return storeLocations;
    }


    /**
     * 递归查询库位子节点
     *
     * @param storeLocations
     * @param parentId
     */
    private void addChild(List<WarehouseModelDto> storeLocations, Long parentId) {
        List<WarehouseModel> children = warehouseModelMapper.findByParentId(parentId);
        if (CollectionUtils.isEmpty(children)) {
            return;
        }
        for (WarehouseModel warehouseModel : children) {
            WarehouseModelDto warehouseModelDto = modelMapper.map(warehouseModel, WarehouseModelDto.class);
            //查询所属厂区
            Long factoryId = warehouseModel.getFactoryId();
            WarehouseModel factory = warehouseModelMapper.findById(factoryId);
            if (factory != null) {
                warehouseModelDto.setFactoryName(factory.getName());
            }
            //查询所属仓库
            Long warehouseId = warehouseModel.getWarehouseId();
            WarehouseModel warehouse = warehouseModelMapper.findById(warehouseId);
            if (warehouse != null) {
                warehouseModelDto.setWarehouseName(warehouse.getName());
            }
            //查询所属库区
            Long areaId = warehouseModel.getAreaId();
            WarehouseModel area = warehouseModelMapper.findById(areaId);
            if (area != null) {
                warehouseModelDto.setAreaName(area.getName());
            }
            storeLocations.add(warehouseModelDto);
            addChild(storeLocations, warehouseModel.getId());
        }
    }

    @Override
    public List<WarehouseModel> findByParentId(Long parentId) {
        return warehouseModelMapper.findByParentId(parentId);
    }

    @Override
    public WarehouseModel findByName(String name) {
        return warehouseModelMapper.findByName(name);
    }

    @Override
    public WarehouseModel findByCode(String code) {
        return warehouseModelMapper.findByCode(code);
    }

    @Override
    public List<WarehouseModel> findByUserId(Integer userId) {
        return warehouseModelMapper.findByUserId(userId);
    }

    @Override
    public Result create(WarehouseModelDto warehouseModelDto) {
        //校验仓库编码和名称是否重复
        WarehouseModel warehouseModelCode = this.findByCode(warehouseModelDto.getCode());
        if (warehouseModelCode != null) {
            return ResultGenerator.fail("编码重复，请重新输入！");
        }
        WarehouseModel warehouseModelName = this.findByName(warehouseModelDto.getName());
        if (warehouseModelName != null) {
            return ResultGenerator.fail("名称重复，请重新输入！");
        }
        WarehouseModel warehouseModel = modelMapper.map(warehouseModelDto, WarehouseModel.class);
        warehouseModel.setCreateUserId(BaseContextHandler.getUserID());
        warehouseModel.setCreateUserName(BaseContextHandler.getUsername());
        warehouseModel.setCreateTime(new Date());
        this.saveOrUpdate(warehouseModel);
        return ResultGenerator.success();
    }

    @Override
    public Map<String, WarehouseModelDto> getSuperior(Long id) {
        if (id == null || id == 0) {
            throw new BusinessException("ID不能为空");
        }
        WarehouseModel warehouseModel = warehouseModelMapper.findById(id);
        if (warehouseModel == null) {
            throw new BusinessException("原数据不存在！");
        }
        Map<String, WarehouseModelDto> result = new HashMap<>();
        //查询父级
        WarehouseModel parent = warehouseModelMapper.findById(warehouseModel.getParentId());
        if (parent != null) {
            result.put("parent", modelMapper.map(parent, WarehouseModelDto.class));
            //查询爷级
            WarehouseModel grandparent = warehouseModelMapper.findById(parent.getParentId());
            if (grandparent != null) {
                result.put("grandparent", modelMapper.map(grandparent, WarehouseModelDto.class));
            }
        }
        return result;
    }

    @Override
    public Page<WarehouseModel> listByPage(IPage page, ServletRequest request) {
        Integer userId = BaseContextHandler.getUserID();
        String type = request.getParameter("search_LIKE_type");
        Page<WarehouseModel> pages = warehouseModelMapper.listByPage(page, userId, type);
        return pages;
    }

    @Override
    public void updateByDto(WarehouseModelDto dto) {
        if (dto.getId() == null) {
            throw new BusinessException("id不能为空");
        }
        WarehouseModel warehouseModel = this.getById(dto.getId());
        if (warehouseModel == null) {
            throw new BusinessException("原信息不存在");
        }
        //如果修改了编码，校验编码是否已经存在
        if (!warehouseModel.getCode().equals(dto.getCode())) {
            WarehouseModel warehouseModelCode = this.findByCode(dto.getCode());
            if (warehouseModelCode != null) {
                throw new BusinessException("仓库编码已存在，请重新输入！");
            }
        }
        //如果修改了名称，校验名称是否已经存在
        if (!warehouseModel.getName().equals(dto.getName())) {
            WarehouseModel warehouseModelName = this.findByName(dto.getName());
            if (warehouseModelName != null) {
                throw new BusinessException("仓库名称已存在，请重新输入！");
            }
        }
        if (warehouseModel.getCode().equals(dto.getCode()) && warehouseModel.getName().equals(dto.getName())) {
            throw new BusinessException("仓库名称和编码与原信息一致，请重新输入！");
        }
        warehouseModel.setCode(dto.getCode());
        warehouseModel.setName(dto.getName());
        warehouseModel.setUpdateUserId(BaseContextHandler.getUserID());
        warehouseModel.setUpdateUserName(BaseContextHandler.getUsername());
        warehouseModel.setUpdateTime(new Date());
        this.saveOrUpdate(warehouseModel);
    }

    @Override
    public WarehouseModel getCode(String code) {
        return warehouseModelMapper.findByCode(code);
    }
}




