package com.patzn.lims.drug.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.patzn.cloud.commons.toolkit.DateUtils;
import com.patzn.cloud.commons.toolkit.FileUtils;
import com.patzn.cloud.commons.toolkit.StringHandleUtils;
import com.patzn.lims.common.ObjectUtils;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.oss.OssClient;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.drug.dto.DrugSampleDTO;
import com.patzn.lims.drug.dto.DrugSampleReportDTO;
import com.patzn.lims.drug.entity.*;
import com.patzn.lims.drug.eunms.ItemStatusEnum;
import com.patzn.lims.drug.eunms.OosStatusEnum;
import com.patzn.lims.drug.eunms.SampleStatusEnum;
import com.patzn.lims.drug.eunms.SingleJudgeEnum;
import com.patzn.lims.drug.mapper.DrugSampleMapper;
import com.patzn.lims.drug.service.*;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.drug.vo.DrugCatalogueItemVO;
import com.patzn.lims.drug.vo.DrugItemVO;
import com.patzn.lims.drug.vo.DrugSampleOosVO;
import com.patzn.lims.drug.vo.DrugSampleVO;
import com.patzn.lims.res.enums.CodeTypeEnum;
import com.patzn.lims.res.service.ILmsCodeRuleService;
import com.patzn.lims.sys.entity.SysFileSignature;
import com.patzn.lims.sys.entity.SysFileTemplate;
import com.patzn.lims.sys.service.ISysFileSignatureService;
import com.patzn.lims.sys.service.ISysFileTemplateService;
//import com.patzn.lims.sys.service.ISysMessageService;
import com.patzn.poibox.utils.BytePictureUtils;
import com.patzn.poibox.xwpf.PoiUtil2007;
import com.patzn.poibox.xwpf.XWPFTemplate;
import com.patzn.poibox.xwpf.template.render.data.PictureRenderData;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 食药样品主表 服务实现类
 * </p>
 *
 * @author wwd
 * @since 2020-02-29
 */
@Service
public class DrugSampleServiceImpl extends BaseServiceImpl<DrugSampleMapper, DrugSample> implements IDrugSampleService {

    @Autowired
    private IDrugSampleOperationService drugSampleOperationService;
    @Autowired
    private IDrugCatalogueItemService drugCatalogueItemService;

    @Autowired
    private IDrugItemService drugItemService;


    @Autowired
    private IDrugItemRelEquipService drugItemRelEquipService;

    @Autowired
    private IDrugItemOperationService drugItemOperationService;

    @Autowired
    private IDrugSampleRecordService drugSampleRecordService;

    @Autowired
    private ILmsCodeRuleService lmsCodeRuleService;
    @Autowired
    private ISysFileTemplateService sysFileTemplateService;

    @Autowired
    private IDrugSampleReportService drugSampleReportService;

    @Autowired
    private OssClient ossClient;

    @Autowired
    private ISysFileSignatureService  sysFileSignatureService;

    @Autowired
    private IDrugSampleOosService drugSampleOosService;
//    @Autowired
//    private ISysMessageService sysMessageService;


    @Override
    public Page<DrugSample> page(Page<DrugSample> page, DrugSample drugSample) {
        QueryWrapper<DrugSample> wrapper = Wrappers.<DrugSample>query(drugSample);
        return this.page(page, wrapper);
    }

    @Override
    public Page<DrugSampleVO> pageVO(Page page, DrugSampleVO vo) {
        return baseMapper.selectVOList(page,vo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addEnvRegister(DrugSampleDTO dto, Account account) {
        return addReg(dto,account,CodeTypeEnum.ENV_SAMPLE);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitEnvPlan(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);
        //如果有非送样状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.DRAFT));
        if (count>0){
            PtAssert.fail("您选择的计划含有已经提交的，请确认");
        }
        if (update(new DrugSample().setStatus(SampleStatusEnum.ENV_PLAN_CHECK).setProgress(SampleStatusEnum.ENV_PLAN_CHECK),
                Wrappers.<DrugSample>query().in("id",ids))){
            drugSampleOperationService.updateRegisterToMake(account,ids);
            drugSampleRecordService.record(account,SampleStatusEnum.DRAFT,SampleStatusEnum.ENV_PLAN_CHECK,ids,"环境监测计划提交");
            return  true;
        }
        return false;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitEnvPlanCheck(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);
        //如果有非送样状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.ENV_PLAN_CHECK));
        if (count>0){
            PtAssert.fail("您选择的计划含有已经提交的，请确认");
        }
        if (update(new DrugSample().setStatus(SampleStatusEnum.ENV_PLAN_EXECUTE).setProgress(SampleStatusEnum.ENV_PLAN_EXECUTE),
                Wrappers.<DrugSample>query().in("id",ids))){
            drugSampleOperationService.updateMakeToReceive(account,ids);
            drugSampleRecordService.record(account,SampleStatusEnum.ENV_PLAN_CHECK,SampleStatusEnum.ENV_PLAN_EXECUTE,ids,"环境监测计划评审通过");
            return  true;
        }
        return false;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean backEnvPlanCheck(Long[] ids, String reason, Account account) {
        ObjectUtils.checkNull(ids);
        if (StringUtils.isBlank(reason)){
            PtAssert.fail("请填写退回原因");
        }
        //如果有非送样状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.ENV_PLAN_CHECK));
        if (count>0){
            PtAssert.fail("您选择的计划含有已经提交的，请确认");
        }
        if (update(new DrugSample().setStatus(SampleStatusEnum.DRAFT).setProgress(SampleStatusEnum.ENV_PLAN_CHECK_BACK),
                Wrappers.<DrugSample>query().in("id",ids))){
            drugSampleRecordService.record(account,SampleStatusEnum.ENV_PLAN_CHECK,SampleStatusEnum.DRAFT,ids,reason);
            return  true;
        }
        return false;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitEnvExecute(Long[] ids, Account account) {

        ObjectUtils.checkNull(ids);
        List<DrugItem> checkItemList = drugItemService.list(Wrappers.<DrugItem>query().select("sample_id").in("sample_id",ids).groupBy("sample_id"));
        if (checkItemList.size()!= ids.length){
            PtAssert.fail("提交的样品没有检测项目，请确认");
        }
        //如果有非样品接收状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.ENV_PLAN_EXECUTE));
        if (count>0){
            PtAssert.fail("您选择的任务含有已经接收的，请确认");
        }
        if (update(new DrugSample().setStatus(SampleStatusEnum.ENV_TEST).setProgress(SampleStatusEnum.ENV_TEST),
                Wrappers.<DrugSample>query().in("id",ids))){
            drugSampleOperationService.updateReceiveToTest(account,ids);
            drugSampleRecordService.record(account,SampleStatusEnum.ENV_PLAN_EXECUTE,SampleStatusEnum.ENV_TEST,ids,"环境监测执行提交");
            return   drugItemService.updateByCondition(ids,ItemStatusEnum.ENV_INPUT);
        }
        return false;
    }


    @Transactional(rollbackFor = Exception.class)
    public boolean addReg(DrugSampleDTO dto, Account account ,CodeTypeEnum codeTypeEnum) {
        PtAssert.fail(null==dto,"数据有误");
        ObjectUtils.checkNull(dto.getName(),"物品名称不能为空");
        DrugSample drugSample= dto.convert(DrugSample.class);

        if (StringUtils.isBlank(drugSample.getSampleCode())){
            String code= lmsCodeRuleService.getKey(codeTypeEnum,drugSample);
            drugSample.setSampleCode(code);
        }
        if (save(drugSample)){
            DrugSampleOperation operation = dto.getDrugSampleOperation();
            operation.setSampleId(drugSample.getId());
            drugSampleOperationService.save(operation);

            if (null!=dto.getCatalogueId()){
                List<DrugCatalogueItemVO> catalogueItemList =  drugCatalogueItemService.listVOByCatalogueId(dto.getCatalogueId());
                if (CollectionUtils.isNotEmpty(catalogueItemList)){

                    List<DrugItem> saveItemList = new ArrayList<>();
                    List<DrugItemOperation> saveItemOperationList = new ArrayList<>();
                    for (DrugCatalogueItemVO itemVO:catalogueItemList) {
                        DrugItem item = new DrugItem();
                        item.setAptitudeId(itemVO.getAptitudeId());
                        item.setCompareSymbol(itemVO.getCompareSymbol());
                        item.setSampleId(drugSample.getId());
                        item.setDefaultValue(itemVO.getDefaultValue());
                        item.setGroupId(itemVO.getGroupId());
                        item.setGroupName(itemVO.getGroupName());
                        item.setName(itemVO.getName());
                        item.setJudged(itemVO.getJudged());
                        item.setLimitValue(itemVO.getLimitValue());
                        item.setUnit(itemVO.getUnit());
                        item.setValidValue(itemVO.getValidValue());
                        item.setOrderBy(itemVO.getOrderBy());
                        item.setStandardId(itemVO.getStandardId());
                        item.setCode(itemVO.getCode());
                        item.setStandardName(itemVO.getStandardName());
                        item.setStatus(ItemStatusEnum.DRAFT);
                        item.setProgress(ItemStatusEnum.DRAFT);
                        item.setId(IdWorker.getId());
                        saveItemList.add(item);


                        DrugItemOperation itemOperation = new DrugItemOperation();
                        itemOperation.setItemId(item.getId());
                        saveItemOperationList.add(itemOperation);
                    }
                    drugItemService.saveBatch(saveItemList);
                    drugItemOperationService.saveBatch(saveItemOperationList);
                }
            }

        }
        return true;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addRegister(DrugSampleDTO dto, Account account) {
        PtAssert.fail(null==dto,"数据有误");
        ObjectUtils.checkNull(dto.getName(),"物品名称不能为空");
        List<DrugItem> drugItemList = dto.getDrugItemList();

        if (CollectionUtils.isEmpty(drugItemList)){
            PtAssert.fail("所检检测项目不能为空");
        }
        DrugSample drugSample= dto.convert(DrugSample.class);
        if (StringUtils.isBlank(drugSample.getSampleCode())){
            String code= lmsCodeRuleService.getKey(CodeTypeEnum.DRUG_SAMPLE,drugSample);
            drugSample.setSampleCode(code);
        }
        if (save(drugSample)){
            DrugSampleOperation operation = dto.getDrugSampleOperation();
            operation.setSampleId(drugSample.getId());
            drugSampleOperationService.save(operation);
            List<DrugItem> saveItemList = new ArrayList<>();
            List<DrugItemOperation> saveItemOperationList = new ArrayList<>();
            for (DrugItem item:drugItemList) {
                item.setSampleId(drugSample.getId());
                item.setStatus(ItemStatusEnum.DRAFT);
                item.setProgress(ItemStatusEnum.DRAFT);
                item.setId(IdWorker.getId());
                saveItemList.add(item);
                DrugItemOperation itemOperation = new DrugItemOperation();
                itemOperation.setItemId(item.getId());
                saveItemOperationList.add(itemOperation);
            }
            drugItemService.saveBatch(saveItemList);
            drugItemOperationService.saveBatch(saveItemOperationList);
        }
        return true;
        //      return   addReg(dto,account,CodeTypeEnum.DRUG_SAMPLE);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitRegister(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);

        //如果有非草稿状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.DRAFT));
        if (count>0){
            PtAssert.fail("您选择的任务含有已经下发的，请确认");
        }
       if (update(new DrugSample().setStatus(SampleStatusEnum.RECEIVE).setProgress(SampleStatusEnum.RECEIVE),
               Wrappers.<DrugSample>query().in("id",ids))){
           drugSampleOperationService.updateRegisterToMake(account,ids);
           drugSampleRecordService.record(account,SampleStatusEnum.DRAFT,SampleStatusEnum.RECEIVE,ids);
//           sysMessageService.sendMsg("/drug/sample/make","请检任务下发","新的样品制备任务",account,null);
           return  true;
       }

        return false;
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitOosExecute(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);

        //如果有非草稿状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.WAIT_RECHECK));
        if (count>0){
            PtAssert.fail("您选择的任务含有已经下发的，请确认");
        }
        if (update(new DrugSample().setStatus(SampleStatusEnum.MAKE).setProgress(SampleStatusEnum.MAKE),
                Wrappers.<DrugSample>query().in("id",ids))){
            drugSampleOperationService.updateRegisterToMake(account,ids);
            drugSampleRecordService.record(account,SampleStatusEnum.DRAFT,SampleStatusEnum.MAKE,ids);
            return  true;
        }

        return false;
    }

    @Override
    public Page<DrugSampleOosVO> pageOosRegisterHis(Page page, DrugSampleOosVO vo) {

        Page<DrugSampleOosVO> voPage = baseMapper.selectOosRegisterHis(page,vo);

        List<DrugSampleOosVO> list = voPage.getRecords();
        if (CollectionUtils.isEmpty(list)){
            return voPage;
        }
        List<Long> sampleIdList = new ArrayList<>();
        for (DrugSampleOosVO oosVO:list) {
            sampleIdList.add(oosVO.getId());
            if (null==oosVO.getOosStatus()){
                oosVO.setOosStatus(OosStatusEnum.REGISTER);
                oosVO.setOosProgress(OosStatusEnum.REGISTER);
            }
        }
        List<DrugItem> drugItemList = drugItemService.list(Wrappers.<DrugItem>query().select("sample_id").in("sample_id",sampleIdList).eq("single_judge",SingleJudgeEnum.FAIL));
        Map<Long,Integer> integerMap = new HashMap<>();
        for (DrugItem item:drugItemList) {
            if (integerMap.containsKey(item.getSampleId())){
                int num= integerMap.get(item.getSampleId());
                num=num+1;
                integerMap.put(item.getSampleId(),num);
            }else{
                integerMap.put(item.getSampleId(),1);
            }
        }
        for (DrugSampleOosVO oosVO:list) {

            if (null==integerMap){
                oosVO.setNoItemNum(1);
            }else{
                oosVO.setNoItemNum(integerMap.get(oosVO.getId()));
            }
        }

        voPage.setRecords(list);
        return voPage;
    }




    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitSend(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);
        //如果有非送样状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.SEND));
        if (count>0){
            PtAssert.fail("您选择的任务含有已经发放的，请确认");
        }
        if (update(new DrugSample().setStatus(SampleStatusEnum.RECEIVE).setProgress(SampleStatusEnum.RECEIVE),
                Wrappers.<DrugSample>query().in("id",ids))){
            drugSampleOperationService.updateSendToReceive(account,ids);
            drugSampleRecordService.record(account,SampleStatusEnum.SEND,SampleStatusEnum.RECEIVE,ids,"样品发放提交");
            return  true;
        }
        return false;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitReceive(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);
        List<DrugItem> checkItemList = drugItemService.list(Wrappers.<DrugItem>query().select("sample_id").in("sample_id",ids).groupBy("sample_id"));
        if (checkItemList.size()!= ids.length){
            PtAssert.fail("接收的样品没有检测项目，请确认");
        }
        //如果有非样品接收状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.RECEIVE));
        if (count>0){
            PtAssert.fail("您选择的任务含有已经接收的，请确认");
        }
        if (update(new DrugSample().setStatus(SampleStatusEnum.TEST).setProgress(SampleStatusEnum.TEST),
                Wrappers.<DrugSample>query().in("id",ids))){
            drugSampleOperationService.updateReceiveToTest(account,ids);
            drugSampleRecordService.record(account,SampleStatusEnum.RECEIVE,SampleStatusEnum.TEST,ids,"样品接收提交");
            return   drugItemService.updateByCondition(ids,ItemStatusEnum.ALLOCATE);
        }
        return false;
    }

    @Override
    public Page<DrugSampleVO> pageVOByItemStatus(Page page, DrugSampleVO vo) {
        return baseMapper.selectVOByItemStatusList(page,vo);
    }

    @Override
    public DrugSampleVO getSampleVO(Long id) {
      if (null == id){
          return null;
      }
       DrugSample sample=   getById(id);
        if (null!= sample){

            DrugSampleVO sampleVO = sample.convert(DrugSampleVO.class);
            List<DrugItem> itemList = drugItemService.list(Wrappers.<DrugItem>query().eq("sample_id",id));
            if (CollectionUtils.isNotEmpty(itemList)){
                sampleVO.setItemList(itemList);
            }
            return sampleVO;
        }

        return  null;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean reportGenerate(DrugSampleReportDTO dto, Account account, HttpServletResponse response) {
        PtAssert.fail(null == dto, "数据有误");
        List<DrugSample> contractSampleList = dto.getSampleList();
        PtAssert.fail(null == dto.getReportModelId(), "请选择报告模板");
        PtAssert.fail(CollectionUtils.isEmpty(contractSampleList), "报检单不能为空");

        List<Long> sampleIdList = new ArrayList<>();

        Map<Long,DrugSample> sampleMap = new HashMap();
        for (DrugSample sample : contractSampleList) {
            PtAssert.fail(null == sample.getId(), "报检单ID不能为空");
            sampleIdList.add(sample.getId());
            sampleMap.put(sample.getId(),sample);
        }

        List<DrugSampleOperation> operationList = drugSampleOperationService.list(Wrappers.<DrugSampleOperation>query().in("sample_id",sampleIdList));


        return makeReport( sampleMap, dto.getReportModelId(),sampleIdList,operationList, account, response);
    }

    @Override
    public Page<DrugSampleVO> pageVOReport(Page page, DrugSampleVO vo) {

        Page<DrugSampleVO> voPage=  baseMapper.selectVOList(page,vo);


        List<DrugSampleVO> sampleVOList = voPage.getRecords();

        List<Long> sampleIds = sampleVOList.stream().map(s->{
            return  s.getId();
        }).collect(Collectors.toList());


        if (CollectionUtils.isEmpty(sampleIds)){
            return voPage;
        }
        List<DrugSampleReport> reportList = drugSampleReportService.list(Wrappers.<DrugSampleReport>query().in("sample_id",sampleIds));

        Map<Long,Long> longMap = new HashMap<>();
        for (DrugSampleReport report:reportList) {
            longMap.put(report.getSampleId(),report.getSampleId());
        }

        for (DrugSampleVO drugSampleVO:sampleVOList) {
             if (longMap.get(drugSampleVO.getId())==null){
                 drugSampleVO.setReported("否");
             }else{
                 drugSampleVO.setReported("是");
             }
        }
        voPage.setRecords(sampleVOList);
        return voPage;
    }





    private void insertImage(List<DrugSample> list, Account account, String key, String imageKey, int i) {

        Map<String, Object> datas = new HashMap<>(16);
        SysFileSignature sysFileSignaturemy = sysFileSignatureService.getByUserId(account.getUserId());
        InputStream is = null;
        if (null != sysFileSignaturemy && org.apache.commons.lang3.StringUtils.isNotBlank(sysFileSignaturemy.getObjectKey())) {
            is = ossClient.download(sysFileSignaturemy.getObjectKey());
        }
        Date issueDate = new Date();

        datas.put(key, account.getUserName());
        if (null == is) {
            datas.put(imageKey, "");
        } else {
            datas.put(imageKey, new PictureRenderData(100, 50, ".png", BytePictureUtils.toByteArray(is)));
        }
        List<File> deleteList = new ArrayList<>();
        try {

            for (DrugSample contractSample : list) {
                DrugSampleReport  report= drugSampleReportService.getLastByContractId(contractSample.getId());


                InputStream inputStream = ossClient.download(report.getUri().split("#")[1]);
                PtAssert.fail(null == inputStream, "报告不存在");

//                if (1 == flag) {
//                    ManufactContractSampleOperation operation=manufactContractSampleOperationService.getByContractSampleId(contractSample.getId());
//                    datas.put("reportIssueDate", DateUtils.toYearMonthDay(operation.getReportIssueDate()));
//                    datas.put("reportIssueDateChinese", DateUtils.toYearMonthDayChinese(operation.getReportIssueDate()));
//                    datas.put("issueDate_point", DateUtils.dateTransfer(issueDate, "yyyy.MM.dd"));
//                }

                XWPFTemplate template = XWPFTemplate.compile(inputStream).render(datas);
                File fileNew = null;
                FileOutputStream os;
                fileNew = File.createTempFile(contractSample.getSampleCode(), ".docx");
                os = new FileOutputStream(fileNew);
                template.write(os);
                os.flush();
                os.close();
                template.close();
                inputStream.close();
                drugSampleReportService.uploadSampleGenerateDocx(contractSample,account,"报告编制提交",fileNew);
                deleteList.add(fileNew);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
                FileUtils.deleteFiles(deleteList);
            }catch (Exception e){
                log.error(e.getMessage(),e);
            }

        }
    }


    @Override
    public List<DrugSample> getListByIds(Long[] ids) {
        return  super.list(Wrappers.<DrugSample>query().in("id",ids));
    }





    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean stopTest(Long[] ids, Account account) {
        PtAssert.fail(ArrayUtils.isEmpty(ids),"请选择待中止的数据");
        //如果有非草稿状态的说明已经提交过无法再次提交
        int count= count(Wrappers.<DrugSample>query().in("id",ids).ne("status", SampleStatusEnum.DRAFT));
        if (count>0){
            PtAssert.fail("请选择草稿状态的");
        }
        drugSampleRecordService.record(account, SampleStatusEnum.DRAFT,
                SampleStatusEnum.STOP, ids, "中止检测");
        return super.update(new DrugSample().setStatus(SampleStatusEnum.STOP).
                setProgress(SampleStatusEnum.STOP), Wrappers.<DrugSample>query().in("id", ids));
    }




    private boolean makeReport(Map<Long,DrugSample> sampleMap, Long reportModelId,List<Long> sampleIdList, List<DrugSampleOperation> operationList,Account account, HttpServletResponse response) {
        SysFileTemplate sysFileTemplate = sysFileTemplateService.getById(reportModelId);
        PtAssert.fail(null == sysFileTemplate, "选择的报告模板不存在");

        List<DrugSample> dbList = list(Wrappers.<DrugSample>query().in("id",sampleIdList));


        for (DrugSample dbSample:dbList) {
            DrugSample sample = sampleMap.get(dbSample.getId());
            InputStream io = ossClient.download(sysFileTemplate.getObjectKey());

            DrugSampleOperation operation = null;
            for (DrugSampleOperation sampleOperation:operationList) {
                if (sampleOperation.getSampleId().equals(dbSample.getId())){
                    operation= sampleOperation;
                    break;
                }
            }
            if (null == operation){
                operation = new DrugSampleOperation();
            }

            if (StringUtils.isBlank(sample.getReportCode())){
               String reportCode= lmsCodeRuleService.getKey(CodeTypeEnum.DRUG_REPORT,dbSample);
                dbSample.setReportCode(reportCode);
            }else{
                String reportCode= sample.getReportCode();
                dbSample.setReportCode(reportCode);
            }

            Map<String, Object> contractMap = new HashMap<>();
            contractMap.put("s", dbSample);
            contractMap.put("o", operation);


            List<DrugItem> itemList = drugItemService.list(Wrappers.<DrugItem>query().eq("sample_id",dbSample.getId()));


            List<DrugItemVO> itemVOList=new ArrayList<>();
            for (DrugItem item:itemList) {
                DrugItemVO itemVO= item.convert(DrugItemVO.class);
                itemVO.setSampleCode(sample.getSampleCode());
                itemVOList.add(itemVO);
            }


            StringBuffer sbTestBasis=new StringBuffer();

            StringBuffer testNameSb=new StringBuffer();
            for (DrugItemVO vo:itemVOList) {
                String testBasis=StringHandleUtils.getString(vo.getCode())+" "+StringHandleUtils.getString(vo.getStandardName());
                if (StringUtils.isNotBlank(testBasis)){
                    if (!sbTestBasis.toString().contains(testBasis)){
                        sbTestBasis.append(testBasis).append("\n");
                    }

                }
                if (!testNameSb.toString().contains(vo.getName())){
                    testNameSb.append(vo.getName()).append("、");
                }
            }
            contractMap.put("testBasisAndName",sbTestBasis.toString());
            contractMap.put("itemNames",StringHandleUtils.getExcepLastOne(testNameSb.toString()));
            List<Long> itemIds=itemList.stream().map(i->{
                return i.getId();
            }).collect(Collectors.toList());

            List<DrugItemRelEquip> itemRelEquipList=drugItemRelEquipService.list(Wrappers.<DrugItemRelEquip>query().in("item_id",itemIds));

            String testEquips="";
            String testEquipAndNos="";

            if (CollectionUtils.isNotEmpty(itemRelEquipList)){
                testEquips=StringHandleUtils.join(itemRelEquipList.stream().map(e->{
                    return e.getEquipName();
                }).collect(Collectors.toList()));

                testEquipAndNos=StringHandleUtils.join(itemRelEquipList.stream().map(e->{
                    return e.getEquipName()+" "+StringHandleUtils.getString(e.getEquipNum());
                }).collect(Collectors.toList()));

            }
            contractMap.put("testEquips", testEquips);
            contractMap.put("testEquipAndNos", testEquipAndNos);


            XWPFTemplate xwpfTemplate = null;
            try {
                xwpfTemplate = XWPFTemplate.compile(io).setDefaultValue("/").render(contractMap);


            } catch (Exception e) {
                log.error("生成报告失败", e);
                PtAssert.fail("报告生成失败:" + e.getMessage());
            }
            XWPFDocument baseDoc = xwpfTemplate.getXWPFDocument();

            List<XWPFTable> tableList = baseDoc.getTables();
            for (XWPFTable xwpfTable : tableList) {
                String text = xwpfTable.getText();
                if (StringHandleUtils.containsString(text, "{name}", "{standardRequirements}","{unit}", "{sampleCode}", "{testValue}", "{singleJudge}")) {
                    //检测内容
                    reportMakeTestContent(xwpfTable, itemList.size(), 1, itemVOList);
                }
            }

            String generated = dbSample.getSampleCode();
            if (StringUtils.isBlank(generated)){
                generated=dbSample.getSampleCode();
                if (generated.contains("*")){
                    generated=generated.replace("*","xing");
                }

                if (generated.contains("#")){
                    generated=generated.replace("#","jing");
                }


                if (generated.contains("/")){
                    generated=generated.replace("/","gang");
                }
            }
            FileOutputStream os = null;
            File file = null;
            try {
                file = File.createTempFile(generated, ".docx");
                os = new FileOutputStream(file);
                baseDoc.write(os);
                os.flush();
                updateById(dbSample);
                drugSampleReportService.uploadSampleGenerateDocx(dbSample, account, "报告生成", file);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    os.close();
                    baseDoc.close();
                    io.close();
                    FileUtils.deleteFiles(file);
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }
        return true;
    }


    public void reportMakeTestContent(XWPFTable xwpfTable, int length, int index, List<?> objList) {
        //检测内容
        Map<Integer, String> map = PoiUtil2007.getCellsContent(xwpfTable, index);
        PoiUtil2007.insertTableRowAtIndex(xwpfTable, index, length);
        fillTableData(xwpfTable, map, objList, index);
    }

    public void fillTableData(XWPFTable xwpfTable, Map<Integer, String> itemCellMap, List<?> objects, int index) {
        int rowLength = 0;
        if (CollectionUtils.isNotEmpty(objects)) {
            rowLength = objects.size();
        }
        for (int i = 0; i < rowLength; i++) {
            fillTableData(xwpfTable, itemCellMap, index + i, objects.get(i));
        }
    }

    public void fillTableData(XWPFTable xwpfTable, Map<Integer, String> itemCellMap, int rowIndex, Object object) {

        List<XWPFTableCell> cellList = PoiUtil2007.getRowCells(xwpfTable, rowIndex);
        int cellLength = 0;
        if (CollectionUtils.isNotEmpty(cellList)) {
            cellLength = cellList.size();
        }
        for (int k = 0; k < cellLength; k++) {
            XWPFTableCell cell = cellList.get(k);
            if (cell.getParagraphs().size() > 0) {
                cell.removeParagraph(0);
            }

            if (object instanceof String && "${testItemThatIsNotQualified}".equals(itemCellMap.get(k))) {
                cell.setText(object.toString());
            } else if (object instanceof Date) {
                cell.setText(DateUtils.toYearMonthDay((Date) object));
            } else {
                if (org.apache.commons.lang3.StringUtils.isNotBlank(itemCellMap.get(k)) && "{sn}".equals(itemCellMap.get(k))) {
                    cell.setText("" + rowIndex);
                } else if (StringUtils.isNotBlank(itemCellMap.get(k)) && "{singleJudge}".equals(itemCellMap.get(k))) {
                    SingleJudgeEnum resultEnum =SingleJudgeEnum.valueOf(StringHandleUtils.getFieldValueByFieldName(StringHandleUtils.getObjectFromMap(itemCellMap, k), object));
                    cell.setText(resultEnum.getDisplay());
                } else {
                    cell.setText(StringHandleUtils.getFieldValueByFieldName(StringHandleUtils.getObjectFromMap(itemCellMap, k), object));
                }
            }

        }

    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitReportMake(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);
        drugSampleRecordService.record(account,SampleStatusEnum.REPORT_MAKE,SampleStatusEnum.REPORT_CHECK,ids,"报告编制提交" );

        drugSampleOperationService.updateReportMakeInfo(ids,account);
        List<DrugSample> contractSampleList=getListByIds(ids);
        insertImage(contractSampleList, account, "maker", "makerSign", 0);
        return super.update(new DrugSample().setStatus(SampleStatusEnum.REPORT_CHECK).
                setProgress(SampleStatusEnum.REPORT_CHECK), Wrappers.<DrugSample>query().in("id", ids));
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitReportCheck(Long[] ids, Account account) {
        PtAssert.fail(ArrayUtils.isEmpty(ids),"请选择待提交的数据");
        drugSampleRecordService.record(account, SampleStatusEnum.REPORT_CHECK,
                SampleStatusEnum.REPORT_ISSUE,ids,"报告审核提交" );
        List<DrugSample> contractSampleList=getListByIds(ids);

        drugSampleOperationService.updateCheckReportInfo(ids,account);
        insertImage(contractSampleList, account, "checker", "checkSign", 0);
        return super.update(new DrugSample().setStatus(SampleStatusEnum.REPORT_ISSUE).
                setProgress(SampleStatusEnum.REPORT_ISSUE),Wrappers.<DrugSample>query().in("id", ids));
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitReportIssue(Long[] ids, Account account) {
        PtAssert.fail(ArrayUtils.isEmpty(ids),"请选择待提交的数据");
        drugSampleRecordService.record(account, SampleStatusEnum.REPORT_ISSUE,
                SampleStatusEnum.END, ids, "报告签发提交");
        List<DrugSample> contractSampleList=getListByIds(ids);
        drugSampleOperationService.updateIssueReportInfo(ids,account);
        insertImage(contractSampleList, account, "issuer", "issueSign", 1);
        return super.update(new DrugSample().setStatus(SampleStatusEnum.END).
                setProgress(SampleStatusEnum.END), Wrappers.<DrugSample>query().in("id", ids));
    }




    //环境

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitReportMakeEnv(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);
        drugSampleRecordService.record(account,SampleStatusEnum.ENV_REPORT_MAKE,SampleStatusEnum.ENV_REPORT_CHECK,ids,"报告编制提交" );

        drugSampleOperationService.updateReportMakeInfo(ids,account);
        List<DrugSample> contractSampleList=getListByIds(ids);
        insertImage(contractSampleList, account, "maker", "makerSign", 0);
        return super.update(new DrugSample().setStatus(SampleStatusEnum.ENV_REPORT_CHECK).
                setProgress(SampleStatusEnum.ENV_REPORT_CHECK), Wrappers.<DrugSample>query().in("id", ids));
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitReportCheckEnv(Long[] ids, Account account) {
        PtAssert.fail(ArrayUtils.isEmpty(ids),"请选择待提交的数据");
        drugSampleRecordService.record(account, SampleStatusEnum.ENV_REPORT_CHECK,
                SampleStatusEnum.ENV_REPORT_ISSUE,ids,"报告审核提交" );
        List<DrugSample> contractSampleList=getListByIds(ids);

        drugSampleOperationService.updateCheckReportInfo(ids,account);
        insertImage(contractSampleList, account, "checker", "checkSign", 0);
        return super.update(new DrugSample().setStatus(SampleStatusEnum.ENV_REPORT_ISSUE).
                setProgress(SampleStatusEnum.ENV_REPORT_ISSUE),Wrappers.<DrugSample>query().in("id", ids));
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitReportIssueEnv(Long[] ids, Account account) {
        PtAssert.fail(ArrayUtils.isEmpty(ids),"请选择待提交的数据");
        drugSampleRecordService.record(account, SampleStatusEnum.ENV_REPORT_ISSUE,
                SampleStatusEnum.ENV_END, ids, "报告签发提交");
        List<DrugSample> contractSampleList=getListByIds(ids);
        drugSampleOperationService.updateIssueReportInfo(ids,account);
        insertImage(contractSampleList, account, "issuer", "issueSign", 1);
        return super.update(new DrugSample().setStatus(SampleStatusEnum.ENV_END).
                setProgress(SampleStatusEnum.ENV_END), Wrappers.<DrugSample>query().in("id", ids));
    }



    @Override
    public Page<DrugSampleOosVO> pageOosRegister(Page page, DrugSampleOosVO vo) {

        Page<DrugSampleOosVO> voPage = baseMapper.selectOosRegister(page,vo);

        List<DrugSampleOosVO> list = voPage.getRecords();
       if (CollectionUtils.isEmpty(list)){
           return voPage;
       }
        List<Long> sampleIdList = new ArrayList<>();
        for (DrugSampleOosVO oosVO:list) {
            sampleIdList.add(oosVO.getId());
            if (null==oosVO.getOosStatus()){
                oosVO.setOosStatus(OosStatusEnum.REGISTER);
                oosVO.setOosProgress(OosStatusEnum.REGISTER);
            }
        }
        List<DrugItem> drugItemList = drugItemService.list(Wrappers.<DrugItem>query().select("sample_id").in("sample_id",sampleIdList).eq("single_judge",SingleJudgeEnum.FAIL));
        Map<Long,Integer> integerMap = new HashMap<>();
        for (DrugItem item:drugItemList) {
            if (integerMap.containsKey(item.getSampleId())){
               int num= integerMap.get(item.getSampleId());
                num=num+1;
                integerMap.put(item.getSampleId(),num);
            }else{
                integerMap.put(item.getSampleId(),1);
            }
        }
        for (DrugSampleOosVO oosVO:list) {

            if (null==integerMap){
                oosVO.setNoItemNum(1);
            }else{
                oosVO.setNoItemNum(integerMap.get(oosVO.getId()));
            }
        }

        voPage.setRecords(list);
        return voPage;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean backOosCheck(Long[] ids, String reason, Account account) {
       ObjectUtils.checkNull(ids);
       PtAssert.fail(StringUtils.isBlank(reason),"请填写原因");
       drugSampleRecordService.record(account,SampleStatusEnum.END,SampleStatusEnum.END,ids,reason);

        DrugSampleOos oos= new DrugSampleOos();
        oos.setStatus(OosStatusEnum.SUBMIT);
        oos.setProgress(OosStatusEnum.BACK_CHECK);
        return   drugSampleOosService.update(oos,Wrappers.<DrugSampleOos>query().in("sample_id",ids));
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean submitOosCheck(Long[] ids, Account account) {
        ObjectUtils.checkNull(ids);
        int oosCount = drugSampleOosService.count(Wrappers.<DrugSampleOos>query().in("sample_id",ids).ne("status",OosStatusEnum.CHECK));
        if (oosCount>0){
            PtAssert.fail("请勿重复提交");
        }

        List<DrugSampleOos>  list= drugSampleOosService.list(Wrappers.<DrugSampleOos>query().in("sample_id",ids));


        List<Long> reCheckIds= new ArrayList<>();
        List<Long> endIds= new ArrayList<>();

        for (DrugSampleOos sampleOos:list) {
            if ("不予处理".equals(sampleOos.getSuggestion())){
                endIds.add(sampleOos.getSampleId());
            }else if ("复检".equals(sampleOos.getSuggestion())){
                reCheckIds.add(sampleOos.getSampleId());
            }
        }


        if (CollectionUtils.isNotEmpty(endIds)){
            DrugSampleOos oos= new DrugSampleOos();
            oos.setStatus(OosStatusEnum.END);
            oos.setProgress(OosStatusEnum.END);
            drugSampleOosService.update(oos,Wrappers.<DrugSampleOos>query().in("sample_id",endIds));
        }

        if (CollectionUtils.isNotEmpty(reCheckIds)){
            DrugSampleOos oos= new DrugSampleOos();
            oos.setStatus(OosStatusEnum.RECHECK);
            oos.setProgress(OosStatusEnum.RECHECK);
            drugSampleOosService.update(oos,Wrappers.<DrugSampleOos>query().in("sample_id",reCheckIds));
            generateRecheckSample(reCheckIds,account);

        }

        return true;
    }

    @Override
    public Page<DrugSampleOosVO> pageOosExecute(Page page, DrugSampleOosVO vo) {
        return baseMapper.selectOosExecute(page,vo);
    }



    private void generateRecheckSample(List<Long> reCheckIds, Account account) {

        List<DrugSample> list = super.list(Wrappers.<DrugSample>query().in("id",reCheckIds));


        List<DrugSample> saveSampleList = new ArrayList<>();
        List<DrugSampleOperation> saveSampleOperationList = new ArrayList<>();
        List<DrugItem> saveItemList = new ArrayList<>();
        List<DrugItemOperation> saveItemOperationList = new ArrayList<>();
        for (DrugSample sample:list) {
            DrugSample newSample = sample.convert(DrugSample.class);

            newSample.setId(IdWorker.getId());
            newSample.setStatus(SampleStatusEnum.WAIT_RECHECK);
            newSample.setProgress(SampleStatusEnum.WAIT_RECHECK);
            newSample.setUid(null);
            newSample.setCtime(null);
            newSample.setLid(null);
            newSample.setLtime(null);
            newSample.setReportCode(null);
            newSample.setPcPerson(null);
            newSample.setPcPersonId(null);
            newSample.setPcTime(null);
            newSample.setSampleCode(null);
            newSample.setAeTime(null);

            String code= lmsCodeRuleService.getKey(CodeTypeEnum.DRUG_SAMPLE,newSample);
            newSample.setSampleCode(code);
            newSample.setRecheckId(sample.getId());
            saveSampleList.add(newSample);



            DrugSampleOperation newOperation = new DrugSampleOperation();
            newOperation.setSampleId(newSample.getId());
            saveSampleOperationList.add(newOperation);

            List<DrugItem> itemList = drugItemService.list(Wrappers.<DrugItem>query().eq("sample_id",sample.getId()));
            for (DrugItem drugItem:itemList) {
                DrugItem newItem = drugItem.convert(DrugItem.class);
                newItem.setId(IdWorker.getId());
                newItem.setCtime(null);
                newItem.setUid(null);
                newItem.setLid(null);
                newItem.setLtime(null);
                newItem.setTestValue(null);
                newItem.setSingleJudge(SingleJudgeEnum.WAIT);
                newItem.setStatus(ItemStatusEnum.DRAFT);
                newItem.setProgress(ItemStatusEnum.DRAFT);
                newItem.setSampleId(newSample.getId());
                saveItemList.add(newItem);

                DrugItemOperation newItemOperation = new DrugItemOperation();
                newItemOperation.setItemId(newItem.getId());

                saveItemOperationList.add(newItemOperation);
            }

           if (CollectionUtils.isNotEmpty(saveSampleList)){
               saveBatch(saveSampleList);
           }
            if (CollectionUtils.isNotEmpty(saveSampleOperationList)){
                drugSampleOperationService.saveBatch(saveSampleOperationList);
            }


            if (CollectionUtils.isNotEmpty(saveItemList)){
                drugItemService.saveBatch(saveItemList);
            }
            if (CollectionUtils.isNotEmpty(saveItemOperationList)){
                drugItemOperationService.saveBatch(saveItemOperationList);
            }

        }
    }




    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean editSampleVO(DrugSampleDTO dto, Account account) {

        if (null == dto){
            return false;
        }
        if (null == dto.getId()){
            return false;
        }


        List<DrugItem> drugItemList = dto.getDrugItemList();


        if (CollectionUtils.isEmpty(drugItemList)){
            PtAssert.fail("检测项目不能为空");
        }
        //查出样品的所有检测项目

        List<DrugItem> dbList = drugItemService.list(Wrappers.<DrugItem>query().eq("sample_id",dto.getId()));

        List<Long> viewAptitudeIds = drugItemList.stream().map(i->{
            return i.getAptitudeId();
        }).collect(Collectors.toList());

        List<Long> dbAptitudeIds = dbList.stream().map(i->{
            return i.getAptitudeId();
        }).collect(Collectors.toList());



        List<DrugItem> saveItem=new ArrayList<>();

        List<Long> deleteItemIds=new ArrayList<>();

        for (DrugItem viewItem:drugItemList) {
            if (!dbAptitudeIds.contains(viewItem.getAptitudeId())){
                //数据库里面没有需要添加
                viewItem.setSampleId(dto.getId());
                saveItem.add(viewItem);
            }
        }


        for (Long dbAptitudeId:dbAptitudeIds) {
           if (!viewAptitudeIds.contains(dbAptitudeId)){
               //数据库里面有界面传过来的没有需要删除
               deleteItemIds.add(dbAptitudeId);
           }
        }

        DrugSample sample = dto.convert(DrugSample.class);
        if (super.updateById(sample)){
            if (CollectionUtils.isNotEmpty(saveItem)){
                drugItemService.saveBatch(saveItem);
            }
            if (CollectionUtils.isNotEmpty(deleteItemIds)){
                drugItemService.remove(Wrappers.<DrugItem>query().eq("sample_id",dto.getId()).in("aptitude_id",deleteItemIds));
            }

        }
        return true;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean scanSubmit(String sampleCode, int type, Account account) {
       if (StringUtils.isBlank(sampleCode)){
            PtAssert.fail("样品编号不能为空");
        }

       DrugSample sample = getOne(Wrappers.<DrugSample>query().eq("sample_code",sampleCode).last("limit 1"));
       if (null == sample){
           PtAssert.fail("样品不存在");
       }
       if (0==type){
           //样品送样
           submitSend(new Long[]{sample.getId()},account);
       }else if (1==type){
           //样品接收
           submitReceive(new Long[]{sample.getId()},account);
       }
        return true;
    }

}
