package digital.laboratory.platform.inspection.service.impl;
/*
 *@title TestRecordInstrumentServiceImpl
 *@description
 *@author xy
 *@version 1.0
 *@create 2023/12/19 14:51
 */

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import digital.laboratory.platform.inspection.dto.TestRecordArgumentDto;
import digital.laboratory.platform.inspection.entity.TestRecordInstrument;
import digital.laboratory.platform.inspection.enums.TestRecordArgumentType;
import digital.laboratory.platform.inspection.mapper.TestRecordInstrumentMapper;
import digital.laboratory.platform.inspection.mapper.TestRecordMapper;
import digital.laboratory.platform.inspection.mapper.TestTemplateMapper;
import digital.laboratory.platform.inspection.service.TestRecordInstrumentService;
import digital.laboratory.platform.inspection.service.TestRecordService;
import digital.laboratory.platform.inspection.service.TestTemplateService;
import digital.laboratory.platform.inspetion.api.vo.TestRecordVo;
import digital.laboratory.platform.inspection.vo.TestTemplateVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class TestRecordInstrumentServiceImpl extends ServiceImpl<TestRecordInstrumentMapper, TestRecordInstrument> implements TestRecordInstrumentService {

    @Resource
    private TestRecordService testRecordService;

    @Resource
    private TestRecordMapper testRecordMapper;

    @Resource
    private TestTemplateMapper testTemplateMapper;

    @Resource
    private TestTemplateService testTemplateService;

    @Override
    public TestRecordInstrument addTestRecordInstrument(TestRecordInstrument testRecordInstrument) {
        if (StringUtils.isBlank(testRecordInstrument.getId())) {
            testRecordInstrument.setId(IdWorker.get32UUID());
            log.info("保存对象testRecordInstrument的ID为空，由系统生成一个给它使用 {}", testRecordInstrument.getId());
        }
        boolean ret = this.save(testRecordInstrument);
        if (ret) {
            log.info("{} 保存成功", testRecordInstrument);
            return testRecordInstrument;
        } else {
            log.info("{} 保存失败", testRecordInstrument);
            return null;
        }
    }

    @Override
    public TestRecordInstrument updateTestRecordInstrument(TestRecordInstrument testRecordInstrument) {
        if (testRecordInstrument.getSource() == 0) {
            log.info("数据是其他系统推送录入的，不能修改");
            return null;
        }
        boolean ret = this.updateById(testRecordInstrument);
        if (ret) {
            return testRecordInstrument;
        } else {
            return null;
        }
    }

    /**
     * 通过ID删除仪器设备
     * @param id
     * @return
     */
    @Override
    public Boolean deleteTestRecordInstrument(String id) {
        List<TestRecordVo> testRecordMapList = testRecordMapper.getTestRecordMapList(new LambdaQueryWrapper());
        testRecordMapList.forEach(item -> {
            if (item.getDeviceIdList() != null && item.getDeviceIdList().size() > 0 && item.getDeviceIdList().contains(id)) {
                throw new RuntimeException(String.format("该设备已绑定编号为%s的实验，无法删除!", item.getTestSerialNumber()));
            }
        });
        List<TestTemplateVo> testTemplateMapList = testTemplateMapper.getTestTemplateMapList(new LambdaQueryWrapper());
        testTemplateMapList.forEach(item -> {
            if (item.getDeviceIdList() != null && item.getDeviceIdList().size() > 0 && item.getDeviceIdList().contains(id)) {
                throw new RuntimeException(String.format("该设备已绑定ID为%s的实验，无法删除!", item.getId()));
            }
        });
        return this.removeById(id);
    }

    /**
     * 分页查询
     *
     * @param opCode   通过Opcode区分仪器条件列表 1：查询所有的仪器设备（这个实验绑定的除外） 2：查询这个实验下绑定的仪器设备
     * @param keywords 模糊查询参数
     */
    @Override
    public IPage getTestRecordInstrumentPageList(Page page, String testId, String keywords, Integer opCode) {
        TestRecordVo testRecordVo = testRecordMapper.getTestRecordMapById(testId);
        List<String> deviceIdList = testRecordVo.getDeviceIdList();
        LambdaQueryWrapper<TestRecordInstrument> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(StringUtils.isNotBlank(keywords), qw -> qw
                .like(TestRecordInstrument::getInstrumentNumber, keywords)
                .or()
                .like(TestRecordInstrument::getInstrumentProvider, keywords)
                .or()
                .like(TestRecordInstrument::getInstrumentName, keywords)
                .or()
                .like(TestRecordInstrument::getInstrumentTypeNo, keywords));
        if (opCode == 1) {
            if (deviceIdList != null && deviceIdList.size() > 0) {
                wrapper.notIn(TestRecordInstrument::getId, deviceIdList);
            }
            wrapper.orderByDesc(TestRecordInstrument::getCreateTime);
        } else {//这是为了查询时不报错，加入了空字符串
            if (deviceIdList == null || deviceIdList.size() == 0) {
                deviceIdList = new ArrayList<String>();
                deviceIdList.add("");
            }
            wrapper.in(TestRecordInstrument::getId, deviceIdList)
                    .orderByDesc(TestRecordInstrument::getUpdateTime);
        }
        return this.page(page, wrapper);
    }

    /**
     * 列表查询
     *
     * @param opCode   通过Opcode区分仪器条件列表 1：查询所有的仪器设备（这个实验绑定的除外） 2：查询这个实验下绑定的仪器设备
     * @param keywords 模糊查询参数
     */
    @Override
    public IPage getTemplateInstrumentPageList(Page page, String templateId, String keywords, Integer opCode) {
        TestTemplateVo testTemplateVo = testTemplateMapper.getTestTemplateMapById(templateId);
        List<String> deviceIdList = testTemplateVo.getDeviceIdList();
        LambdaQueryWrapper<TestRecordInstrument> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(StringUtils.isNotBlank(keywords), qw -> qw
                .like(TestRecordInstrument::getInstrumentNumber, keywords)
                .or()
                .like(TestRecordInstrument::getInstrumentProvider, keywords)
                .or()
                .like(TestRecordInstrument::getInstrumentName, keywords)
                .or()
                .like(TestRecordInstrument::getInstrumentTypeNo, keywords));
        if (opCode == 1) {
            if (deviceIdList != null && deviceIdList.size() > 0) {
                wrapper.notIn(TestRecordInstrument::getId, deviceIdList);
            }
            wrapper.orderByDesc(TestRecordInstrument::getCreateTime);
        } else {//这是为了查询时不报错，加入了空字符串
            if (deviceIdList == null || deviceIdList.size() == 0) {
                deviceIdList = new ArrayList<String>();
                deviceIdList.add("");
            }
            wrapper.in(TestRecordInstrument::getId, deviceIdList)
                    .orderByDesc(TestRecordInstrument::getUpdateTime);
        }
        return this.page(page, wrapper);
    }

    @Override
    public List<TestRecordInstrument> getTestRecordInstrumentList(TestRecordInstrument testRecordInstrument) {
        List<TestRecordInstrument> retList = this.list(Wrappers.<TestRecordInstrument>lambdaQuery()
                .like(StringUtils.isNotBlank(testRecordInstrument.getInstrumentName()), TestRecordInstrument::getInstrumentName, testRecordInstrument.getInstrumentName()));
        return retList;
    }

    @Override
    public Boolean checkExist(String id) {
        List<TestRecordInstrument> retList = this.list(Wrappers.<TestRecordInstrument>lambdaQuery()
                .eq(TestRecordInstrument::getId, id));
        if (retList.size() > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 添加或移除实验中的仪器设备
     * @param testRecordArgumentDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean useTestRecordInstrument(TestRecordArgumentDto testRecordArgumentDto) {
        TestRecordInstrument testRecordInstrument = this.getById(testRecordArgumentDto.getArgumentId());
        testRecordInstrument.setUpdateTime(LocalDateTime.now());//这里修改是为了查询实验中已添加的列表可以按照添加顺序进行排序
        return this.updateById(testRecordInstrument) && testRecordService.updateTestRecordArgument(testRecordArgumentDto.getTestRecordId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT.getType(), testRecordArgumentDto.getOpCode());
    }

    /**
     * 添加或移除模板中的仪器设备
     * @param testRecordArgumentDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean useTemplateInstrument(TestRecordArgumentDto testRecordArgumentDto) {
        TestRecordInstrument testRecordInstrument = this.getById(testRecordArgumentDto.getArgumentId());
        testRecordInstrument.setUpdateTime(LocalDateTime.now());//这里修改是为了查询实验中已添加的列表可以按照添加顺序进行排序
        boolean ret = testTemplateService.updateTestTemplate(testRecordArgumentDto.getTemplateId(), testRecordArgumentDto.getArgumentId(), TestRecordArgumentType.TEST_RECORD_ARGUMENT_INSTRUMENT.getType(), testRecordArgumentDto.getOpCode());
        return this.updateById(testRecordInstrument) && ret;
    }

}
