package cn.iocoder.yudao.module.mes.service.dvsubject;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodel.DeviceModelDO;
import cn.iocoder.yudao.module.mes.controller.admin.dvsubject.vo.DvSubjectPageReqVO;
import cn.iocoder.yudao.module.mes.controller.admin.dvsubject.vo.DvSubjectSaveReqVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.devicetype.DeviceTypeDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.dvsubject.DvSubjectDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.subjectplan.SubjectPlanDO;
import cn.iocoder.yudao.module.mes.dal.mysql.dvsubject.DvSubjectMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.subjectplan.SubjectPlanMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;

import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_MODEL_CODE_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;

/**
 * 维保项目 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class DvSubjectServiceImpl implements DvSubjectService {

    @Resource
    private DvSubjectMapper dvSubjectMapper;

    @Resource
    private SubjectPlanMapper subjectPlanMapper;

    @Override
    public Long createDvSubject(DvSubjectSaveReqVO createReqVO) {

        validateCodeOnly(createReqVO.getSubjectCode());
        // 插入
        DvSubjectDO dvSubject = BeanUtils.toBean(createReqVO, DvSubjectDO.class);
        dvSubjectMapper.insert(dvSubject);
        // 返回
        return dvSubject.getId();
    }

    private void validateCodeOnly( String code) {
        if (dvSubjectMapper.exists(Wrappers.<DvSubjectDO>lambdaQuery()
                .eq(DvSubjectDO::getSubjectCode, code))) {
            throw exception(SUBJECT_EXISTS);
        }
    }

    @Override
    public void updateDvSubject(DvSubjectSaveReqVO updateReqVO) {
        // 校验存在
        validateDvSubjectExists(updateReqVO.getId());

        //编码重复判断
        Long count = dvSubjectMapper.selectCount(new LambdaQueryWrapper<DvSubjectDO>()
                .eq(DvSubjectDO::getSubjectCode, updateReqVO.getSubjectCode())
                .ne(DvSubjectDO::getId, updateReqVO.getId())
        );
        if (count > 0) {
            throw exception(SUBJECT_EXISTS);
        }
        // 更新
        DvSubjectDO updateObj = BeanUtils.toBean(updateReqVO, DvSubjectDO.class);
        dvSubjectMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDvSubject(List<Long> idList) {
        if (CollectionUtils.isEmpty(idList)) {
            return;
        }

        // 批量校验存在性
        List<DvSubjectDO> existList = dvSubjectMapper.selectBatchIds(idList);
        if (existList.size() != idList.size()) {
            throw exception(DV_SUBJECT_NOT_EXISTS);
        }

        // 批量校验引用
        validateBatchReferences(idList);

        // 批量删除
        dvSubjectMapper.deleteByIds(idList);
    }

    private void validateBatchReferences(List<Long> idList) {
        boolean exists = subjectPlanMapper.exists(
                Wrappers.<SubjectPlanDO>lambdaQuery()
                        .in(SubjectPlanDO::getSubjectId, idList)
        );

        if (exists) {
            throw exception(DV_SUBJECT_REFERENCES);
        }
    }



    private void validateDvSubjectExists(Long id) {
        if (dvSubjectMapper.selectById(id) == null) {
            throw exception(DV_SUBJECT_NOT_EXISTS);
        }
    }

    @Override
    public DvSubjectDO getDvSubject(Long id) {
        return dvSubjectMapper.selectById(id);
    }

    @Override
    public PageResult<DvSubjectDO> getDvSubjectPage(DvSubjectPageReqVO pageReqVO) {
        return dvSubjectMapper.selectPage(pageReqVO);
    }

    @Override
    public List<DvSubjectDO> getDvSubjectList() {
        return dvSubjectMapper.selectList();
    }

}