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

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
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.inspect.item.vo.IotInspectItemPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.inspect.item.vo.IotInspectItemSaveReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.inspect.route.vo.IotInspectRoutePageReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotProductClassifyDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectItemDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectOrderDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectOrderDetailDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectRouteDO;
import cn.iocoder.yudao.module.pms.dal.mysql.IotProductClassifyMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectItemMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderDetailMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectPlanMapper;
import cn.iocoder.yudao.module.pms.service.IotProductClassifyService;
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_INSPECT_ITEM_NOT_EXISTS;

/**
 * 巡检项 Service 实现类
 *
 * @author 李鹏辉
 */
@Service
@Validated
public class IotInspectItemServiceImpl implements IotInspectItemService {

    @Resource
    private IotInspectItemMapper iotInspectItemMapper;
    @Autowired
    private IotProductClassifyService iotProductClassifyService;
    @Autowired
    private IotProductClassifyMapper iotProductClassifyMapper;
    @Autowired
    private DeptService deptService;
    @Autowired
    private IotInspectOrderMapper iotInspectOrderMapper;
    @Autowired
    private IotInspectOrderDetailMapper iotInspectOrderDetailMapper;
    @Autowired
    private IotInspectPlanMapper iotInspectPlanMapper;

    @Override
    public Long createIotInspectItem(IotInspectItemSaveReqVO createReqVO) {
        // 插入
        IotInspectItemDO iotInspectItem = BeanUtils.toBean(createReqVO, IotInspectItemDO.class);
        iotInspectItem.setDeleted(false);
        IotProductClassifyDO iotProductClassify = iotProductClassifyService.getIotProductClassify(iotInspectItem.getDeviceClassify());
        if (Objects.nonNull(iotProductClassify)) {
            iotInspectItem.setDeviceClassifyName(iotProductClassify.getName());
        }
        iotInspectItemMapper.insert(iotInspectItem);
        // 返回
        return iotInspectItem.getId();
    }

    @Override
    public void updateIotInspectItem(IotInspectItemSaveReqVO updateReqVO) {
        // 校验存在
        validateIotInspectItemExists(updateReqVO.getId());
        // 更新
        IotInspectItemDO updateObj = BeanUtils.toBean(updateReqVO, IotInspectItemDO.class);
        iotInspectItemMapper.updateById(updateObj);
    }

    @Override
    public void deleteIotInspectItem(Long id) {
        // 校验存在
        validateIotInspectItemExists(id);
        //查找是否有巡检计划及巡检工单及路线
        List<IotInspectOrderDetailDO> detailDOS = iotInspectOrderDetailMapper.selectList("item_id", id);
        if (CollUtil.isNotEmpty(detailDOS)) {
            List<Long> orderIds = detailDOS.stream().map(IotInspectOrderDetailDO::getOrderId).distinct().collect(Collectors.toList());
            List<IotInspectOrderDO> orderDOS = iotInspectOrderMapper.selectByIds(orderIds);
            if (CollUtil.isNotEmpty(orderDOS)) {
                List<String> planCodes = orderDOS.stream().map(IotInspectOrderDO::getPlanCode).distinct().collect(Collectors.toList());
                Long l = iotInspectPlanMapper.selectCountByPlanCode(planCodes);
                if (l > 0) {
                    throw new ServiceException(new ErrorCode(222, "该巡检项关联计划或路线，不能删除"));
                }
            }
        }
        // 删除
        iotInspectItemMapper.deleteById(id);
    }

    private void validateIotInspectItemExists(Long id) {
        if (iotInspectItemMapper.selectById(id) == null) {
            throw exception(IOT_INSPECT_ITEM_NOT_EXISTS);
        }
    }

    @Override
    public IotInspectItemDO getIotInspectItem(Long id) {
        return iotInspectItemMapper.selectById(id);
    }

    @Override
    public PageResult<IotInspectItemDO> getIotInspectItemPage(IotInspectItemPageReqVO pageReqVO) {
        Set<Long> classifies = new HashSet<>();
        if (Objects.nonNull(pageReqVO.getDeviceClassify())) {
            classifies = iotProductClassifyService.getChildIotProductClassifyList(pageReqVO.getDeviceClassify());
            classifies.add(pageReqVO.getDeviceClassify());
        }
        Set<Long> ids = new HashSet<>();
        if (Objects.nonNull(pageReqVO.getDeptId())) {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
        }
        return iotInspectItemMapper.selectPage(pageReqVO, classifies, ids);
    }

    @Override
    public PageResult<IotInspectItemDO> getRouteItem(IotInspectItemPageReqVO pageReqVO) {
        IPage<IotInspectItemDO> page = iotInspectItemMapper.getRouteItem(
                new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
        if (CollUtil.isNotEmpty(page.getRecords())) {
            return new PageResult<>(page.getRecords(), page.getTotal());
        }
        IotProductClassifyDO iotProductClassifyDO = iotProductClassifyMapper.selectById(pageReqVO.getDeviceClassify());
        pageReqVO.setDeviceClassify(iotProductClassifyDO.getParentId());
        IPage<IotInspectItemDO> parentPage = iotInspectItemMapper.getRouteItem(
                new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
        return new PageResult<>(parentPage.getRecords(), parentPage.getTotal());
    }
}
