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

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.object.BeanUtils;
import cn.iocoder.yudao.module.pms.controller.admin.inspect.route.vo.IotInspectRoutePageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.inspect.route.vo.IotInspectRouteSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotDeviceDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.IotProductClassifyDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectPlanDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectRouteDO;
import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectPlanMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectRouteMapper;
import cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant;
import cn.iocoder.yudao.module.pms.service.IotProductClassifyService;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import com.alibaba.fastjson.JSON;
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 static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 巡检路线 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class IotInspectRouteServiceImpl implements IotInspectRouteService {

    @Resource
    private IotInspectRouteMapper iotInspectRouteMapper;
    @Resource
    private IotProductClassifyService iotProductClassifyService;
    @Autowired
    private IotDeviceMapper iotDeviceMapper;
    @Autowired
    private DeptService deptService;
    @Autowired
    private IotInspectPlanMapper iotInspectPlanMapper;

    @Override
    public Long createIotInspectRoute(IotInspectRouteSaveReqVO createReqVO) {
        // 插入
        IotInspectRouteDO iotInspectRoute = BeanUtils.toBean(createReqVO, IotInspectRouteDO.class);
        iotInspectRoute.setDeleted(false);
        IotProductClassifyDO iotProductClassify = iotProductClassifyService.getIotProductClassify(iotInspectRoute.getDeviceClassify());
        if (Objects.nonNull(iotProductClassify)) {
            iotInspectRoute.setDeviceClassifyName(iotProductClassify.getName());
        }
        //如果有设备存的就是设备的部门id
        if (Objects.nonNull(iotInspectRoute.getDeviceId())) {
            IotDeviceDO iotDeviceDO = iotDeviceMapper.selectById(iotInspectRoute.getDeviceId());
            if (Objects.nonNull(iotDeviceDO)) {
                iotInspectRoute.setDeptId(iotDeviceDO.getDeptId());
            }
        }
        iotInspectRouteMapper.insert(iotInspectRoute);
        // 返回
        return iotInspectRoute.getId();
    }

    @Override
    public void updateIotInspectRoute(IotInspectRouteSaveReqVO updateReqVO) {
        // 校验存在
        validateIotInspectRouteExists(updateReqVO.getId());
        // 更新
        IotInspectRouteDO updateObj = BeanUtils.toBean(updateReqVO, IotInspectRouteDO.class);
        iotInspectRouteMapper.updateById(updateObj);
    }

    @Override
    public void deleteIotInspectRoute(Long id) {
        // 校验存在
        validateIotInspectRouteExists(id);
        List<IotInspectPlanDO> planDOS = iotInspectPlanMapper.selectList();
        List<Long> routeIds = new ArrayList<>();
        planDOS.forEach(planDO -> {
            List<IotInspectRouteDO> routeDOS = JSON.parseArray(planDO.getDeviceIds(), IotInspectRouteDO.class);
            routeDOS.forEach(routeDO -> {
                routeIds.add(routeDO.getId());
            });
        });
        if (routeIds.contains(id)) {
            throw new ServiceException(new ErrorCode(223, "存在关联该路线的巡检计划，暂无法删除"));
        }
        // 删除
        iotInspectRouteMapper.deleteById(id);
    }

    private void validateIotInspectRouteExists(Long id) {
        if (iotInspectRouteMapper.selectById(id) == null) {
            throw exception(ErrorCodeConstant.IOT_INSPECT_ROUTE_NOT_EXISTS);
        }
    }

    @Override
    public IotInspectRouteDO getIotInspectRoute(Long id) {
        return iotInspectRouteMapper.selectById(id);
    }

    @Override
    public PageResult<IotInspectRouteDO> getIotInspectRoutePage(IotInspectRoutePageReqVO 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 iotInspectRouteMapper.selectPage(pageReqVO, classifies, ids);
    }

    @Override
    public PageResult<IotInspectRouteDO> getRoute(IotInspectRoutePageReqVO pageReqVO) {
        IPage<IotInspectRouteDO> page = iotInspectRouteMapper.getRoute(
                new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), pageReqVO);
        return new PageResult<>(page.getRecords(), page.getTotal());
    }
}
