package digital.laboratory.platform.imr.controller;


import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
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.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.plugin.table.LoopRowTableRenderPolicy;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.log.annotation.SysLog;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.common.oss.service.OssFile;
import digital.laboratory.platform.common.security.annotation.Inner;
import digital.laboratory.platform.common.security.util.SecurityUtils;
import digital.laboratory.platform.imr.dto.*;
import digital.laboratory.platform.imr.entity.SampleApply;
import digital.laboratory.platform.imr.entity.SampleInboundRecord;
import digital.laboratory.platform.imr.entity.SampleOutWarehouseApply;
import digital.laboratory.platform.imr.entity.SampleStorage;
import digital.laboratory.platform.imr.mapper.SampleApplyMapper;
import digital.laboratory.platform.imr.mapper.SampleInboundAndOutboundTableMapper;
import digital.laboratory.platform.imr.mapper.SampleOutWarehouseApplyMapper;
import digital.laboratory.platform.imr.mapper.SampleStorageMapper;
import digital.laboratory.platform.imr.service.SamplePutInStorageService;
import digital.laboratory.platform.imr.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.Principal;
import java.time.LocalDate;
import java.util.*;


/**
 * @author Zhang Xiaolong created at  2023-03-21
 * @describe 前端控制器
 * <p>
 * 这是与表示层的接口, 不应该接业务逻辑写在这里, 业务逻辑应该写在 service 中
 * 这里写什么:
 * 为前端提供数据, 接受前端的数据
 * 为前端提供的数据, 从 service 取得后, 可以做一些适当的加工, 这种加工不是业务层面的, 只能是数据格式上, 为方便前端处理
 * 接受前端的数据, 每一个函数的参数可以先做一些整理后, 再调用 service 中的函数。这里对参数的整理, 应该只是格式上的, 而不能是业务上的
 * 数据层在 mapper 中, 数据层不涉及业务, 只管技术上的 对象<->表 之间的转换
 */


/**
 * 样本入库controller
 * 入库相关接口
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/sample_put_in_storage")
@Api(value = "sample_inbound_or_outbound", tags = "样本入库管理")
public class SamplePutInStorageController {

    private final SamplePutInStorageService samplePutInStorageService;

    private final SampleStorageMapper storageMapper;

    private final SampleApplyMapper asMapper;

    private final OssFile ossFile;

    private final SampleOutWarehouseApplyMapper outWarehouseApplyMapper;

    private final SampleInboundAndOutboundTableMapper tableMapper;

    /**
     * 获取已录入仓库样本(分页)
     */
    @ApiOperation(value = "获取已录入仓库样本(分页)", notes = "获取已录入仓库样本(分页)")
    @GetMapping("/repositorySample/page")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_get')")
    public R<IPage<RepositorySampleVO>> getSampleVOList(QuerySampleDTO dto) {

        Page<SampleStorage> page = new Page<>(dto.getCurrent(), dto.getSize());
        IPage<RepositorySampleVO> sampleVOIPage = samplePutInStorageService.getSampleVOList(page, Wrappers.<SampleStorage>query()
                .like(StrUtil.isNotEmpty(dto.getName()), "storage.name", dto.getName())
                .eq(StrUtil.isNotEmpty(dto.getSampleType()), "storage.sample_type", dto.getSampleType())
                .eq("storage.status", dto.getStatus())
                .between(dto.getBeginDate() != null && dto.getFinishDate() != null, "in_repository_date", dto.getBeginDate(), dto.getFinishDate())
                .orderByDesc("create_time")
        );
        return R.ok(sampleVOIPage, "查询成功");
    }

    /**
     * 入库样本记录分页
     */
    @ApiOperation(value = "入库样本记录分页", notes = "入库样本记录分页")
    @GetMapping("/inboundRecord/page")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_get')")
    public R<IPage<InboundRecordVO>> inboundRecord(QuerySampleDTO dto) {
        Page<SampleInboundRecord> page = new Page<>(dto.getCurrent(), dto.getSize());
        IPage<InboundRecordVO> sampleVOIPage = samplePutInStorageService.inboundRecord(page, Wrappers.<SampleInboundRecord>query()
                .like(StrUtil.isNotEmpty(dto.getName()), "inbound.name", dto.getName())
                .orderByDesc("create_time")
        );
        return R.ok(sampleVOIPage, "查询成功");
    }


    /**
     * 待销毁样本预警
     */
    @ApiOperation(value = "待销毁样本预警", notes = "待销毁样本预警")
    @GetMapping("/destructionWarning/page")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_get')")
    public R destructionWarning(QuerySampleDTO dto) {
        Page<SampleStorage> page = new Page<>(dto.getCurrent(), dto.getSize());
        IPage<RepositorySampleVO> sampleVOIPage = samplePutInStorageService.getDestructionVO(page, Wrappers.<SampleStorage>query()
                .like(StrUtil.isNotEmpty(dto.getName()), "storage.name", dto.getName())
                .eq("early_warning", 1)
                .eq("storage.status", 2)//只能查看当前入库的
                .orderByDesc("create_time")
        );
        return R.ok(sampleVOIPage, "查询成功");
    }


    /**
     * 查询单个存放样本信息
     * sample信息+详情(出入库登记表)
     */
    @ApiOperation(value = "查询单个存放样本信息--这个id不是样本id", notes = "查询单个存放样本信息")
    @GetMapping("/detailed")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_get')")
    public R<RepositorySampleVO> getSampleDetailed(String id) {

        if (StrUtil.isEmpty(id)) {
            throw new RuntimeException("查询id不能为空");
        }

        RepositorySampleVO sampleVO = samplePutInStorageService.getSampleDetailed(id);

        return R.ok(sampleVO, "查询成功");
    }


    /**
     * 根据样本编号获取主要信息
     * (扫码枪扫描)
     */
    @ApiOperation(value = "根据样本编号获取主要信息(入库)", notes = "根据样本编号获取主要信息(入库)")
    @GetMapping("/getSampleInfoByNo")
    @Inner(value = false)
    //@PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_get')" )
    public R<List<OutSampleVO>> getSampleInfoByNo(String sampleNo) {

        if (sampleNo == null || "".equals(sampleNo)) {
            return R.failed(null);
        }

        List<OutSampleVO> vo = samplePutInStorageService.getSampleListByNo(sampleNo);

        if (!vo.isEmpty()) {
            return R.ok(vo, "查询成功");
        } else {
            return R.failed(vo, String.format("编号为" + sampleNo + "的样本不存在请重试"));
        }
    }


    @ApiOperation(value = "修改sample质量", notes = "修改sample质量")
    @PostMapping("/updateSampleQuality")
    public R<String> updateSampleQuality(String sampleId, double sampleQuality) {

        if (StrUtil.isEmpty(sampleId)) {
            throw new RuntimeException("id不能为空");
        }

        //查询并修改
        samplePutInStorageService.updateSampleQuality(sampleId, sampleQuality);

        return R.ok(null, "修改质量成功");
    }


    /**
     * 扫码入库查看详情信息
     */
    @ApiOperation(value = "获取sample主要的详情信息", notes = "获取sample主要的详情信息")
    @GetMapping("/getSampleDetailInfo")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_get')")
    public R<BaseSampleDetail> getSampleDetailInfo(String id) {

        if (id == null || "".equals(id)) {
            return R.failed(null);
        }

        BaseSampleDetail sampleDetail = storageMapper.getSampleDetailInfo(id);

        if (sampleDetail != null) {
            if (sampleDetail.getSource().equals("entrustment") && sampleDetail.getQuantity() == 0) {
                sampleDetail.setQuantity(storageMapper.getQuality(sampleDetail.getId()));
            }
            return R.ok(sampleDetail, "查询成功");
        } else {
            return R.failed("查询失败");
        }
    }


    /**
     * 默认没有仓库样本表
     * 外部关联一张样本存储表格
     * (接口2)(不考虑样本入库质量)
     * 根据检材样本编号录入仓库(入库)
     * 确认入库按钮
     */
    @ApiOperation(value = "根据编号录入仓库(入库)--不考虑质量", notes = "根据编号录入仓库(入库)--不考虑质量")
    @PostMapping("/sampleEntryRepository")
    //@PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound')" )
    public R sampleEntryRepository(@RequestBody List<String> sampleNos, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        if (sampleNos != null) {
            throw new RuntimeException("入库样本编号不能为空");
        }

        List<OutSampleVO> vo = samplePutInStorageService.sampleEntryRepository(sampleNos, dlpUser);
        if (vo != null) {
            return R.ok(vo, "样本入库成功,本次入库样本数为" + sampleNos.size() + "份");
        } else {
            return R.failed("入库失败");
        }
    }


    /**
     * 默认没有仓库样本表
     * 外部关联一张样本存储表格
     * (接口3)
     * 根据检材样本编号录入仓库(入库)
     * <p>
     * 这里需要手动填写入库时的质量和计量单位(流转)
     * <p>
     * 确认入库按钮
     */
    @ApiOperation(value = "根据样本编号录入仓库(入库)--考虑质量", notes = "根据样本编号录入仓库(入库)--考虑质量")
    @PostMapping("/sampleInRepository")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_add')")
    public R sampleInRepository(@RequestBody List<InRepositoryDTO> sample, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        if (sample == null) {
            throw new RuntimeException("入库样本编号不能为空");
        }

        List<OutSampleVO> vo = samplePutInStorageService.sampleInRepository(sample, dlpUser);
        if (vo != null) {
            return R.ok(vo, "样本入库成功,本次入库样本数为" + sample.size() + "份");
        } else {
            return R.failed("入库失败");
        }
    }


    /**
     * 待存放样本查询
     */
    @ApiOperation(value = "待存放样本查询", notes = "待存放样本查询")
    @GetMapping("/getToBeStoredSample")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_get')")
    public R<IPage<RepositorySampleVO>> getToBeStoredSample(QueryDTO dto) {


        Page<SampleStorage> page = new Page<>(dto.getCurrent(), dto.getSize());

        IPage<RepositorySampleVO> sampleVOS = storageMapper.getToBeStoredSample(page, Wrappers.<SampleStorage>query()
                .like(StrUtil.isNotEmpty(dto.getName()), "storage.name", dto.getName())
                .eq("storage.status", 1)
        );


        return R.ok(sampleVOS, "查询成功");
    }


    /**
     * 检材存放
     */
    @ApiOperation(value = "选择样本存放到格子(存放)", notes = "选择样本存放到格子(存放)")
    @PostMapping("/sampleDepositRepository")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_edit')")
    public R sampleDepositRepository(@RequestBody DepositDTO dto) {
        if (dto.getIds() == null) {
            return R.failed("样本不能为空");
        }
        if (StrUtil.isEmpty(dto.getCellId())) {
            return R.failed("存放位置不能为空");
        }

        List<OutSampleVO> vo = samplePutInStorageService.sampleDepositRepository(dto);

        return R.ok(vo, "已成功存入" + vo.get(0).getStorageLocation());
    }


    /**
     * 点击存放格子时展示对应内部的存放样本信息
     */

    @ApiOperation(value = "通过样本id获取格子中存放的样本信息", notes = "通过样本id获取格子中存放的样本信息")
    @GetMapping("/getStoredSample")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_get')")
    public R<List<OutSampleVO>> getStoredSample(String cellId) {


        if (cellId == null || "".equals(cellId)) {
            throw new RuntimeException("格子id不能为空");
        }

        ArrayList<OutSampleVO> outSampleVOS = new ArrayList<>();
        QueryWrapper<SampleStorage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("storage_cell_id", cellId);
        queryWrapper.eq("status", 2);//已经入库的
        List<SampleStorage> storages = storageMapper.selectList(queryWrapper);
        for (SampleStorage storage : storages) {
            OutSampleVO sampleVO = storageMapper.getSampleById(storage.getSampleId());
            if (sampleVO != null) {
                outSampleVOS.add(sampleVO);
            }
        }
        Collections.sort(outSampleVOS, new Comparator<OutSampleVO>() {
            @Override
            public int compare(OutSampleVO o1, OutSampleVO o2) {
                String[] split1 = o1.getSampleNo().split("-");
                String[] split2 = o2.getSampleNo().split("-");
                // 先比较年份
                int yearComparison = split2[0].compareTo(split1[0]);
                if (yearComparison != 0) {
                    return yearComparison;
                }
                // 再比较序号
                int num1 = Integer.parseInt(split2[1]);
                int num2 = Integer.parseInt(split1[1]);
                if (num1 - num2 != 0) {
                    return num1 - num2;
                }

                // 再比较尾号
                int num3 = Integer.parseInt(split1[2]);
                int num4 = Integer.parseInt(split2[2]);
                return num3 - num4;
            }
        });
        if (!outSampleVOS.isEmpty()) {
            return R.ok(outSampleVOS, "查询成功");
        } else {
            return R.failed("当前格子未存放样本");
        }
    }


    /**
     * 修改存储期限
     */

    @ApiOperation(value = "修改存储期限", notes = "修改存储期限")
    @PutMapping("/updateStorageDate")
    @PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_edit')")
    public R updateStorageLocation(@RequestBody UpdateStorageDateDTO dto) {

        if (dto.getStorageDate().isBefore(LocalDate.now())) {
            throw new RuntimeException("请选择正确的时间");
        }

        UpdateWrapper<SampleStorage> wrapper = new UpdateWrapper<>();
        wrapper.eq("id", dto.getId());
        wrapper.set("storage_date", dto.getStorageDate());
        wrapper.set("early_warning", 0);//销毁预警为0
        storageMapper.update(null, wrapper);
        return R.ok("修改成功");
    }


    /**
     * 销毁预警角标
     */

    @ApiOperation(value = "销毁预警角标", notes = "销毁预警角标")
    @GetMapping("/destroyed/count")
    //@PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_edit')" )
    public R<List<IconDTO>> getIconCount() {
        //查询当前待销毁检材数量
        QueryWrapper<SampleStorage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("early_warning", 1);
        queryWrapper.eq("status", 2);//只能查看当前入库的
        Long count = storageMapper.selectCount(queryWrapper);

        IconDTO destroyed = new IconDTO(count, 1, "destroyed");

        ArrayList<IconDTO> iconDTOS = new ArrayList<>();
        iconDTOS.add(destroyed);
        return R.ok(iconDTOS, "查询成功");

    }


    //待存放检材角标(--检材存放提示角标)
	/*@ApiOperation(value = "待存放检材角标", notes = "待存放检材角标")
	@GetMapping("/getToBeStoredIcon/count" )
	//@PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound_edit')" )
	public R<List<IconDTO>> getToBeStoredIcon() {
		//查询当前待存放检材的数量
		QueryWrapper<SampleStorage> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("status",1);//只能查看当前入库的
		Long count = storageMapper.selectCount(queryWrapper);

		IconDTO toBeStored = new IconDTO(count, 1, "toBeStored");

		ArrayList<IconDTO> iconDTOS = new ArrayList<>();
		iconDTOS.add(toBeStored);
		return R.ok(iconDTOS,"查询成功");

	}*/

    //----------------------------------------------------------


    /*

     */
    @ApiOperation(value = "一个检材入库时的可选检材列表", notes = "一个检材入库时的可选检材列表")
    @GetMapping("/choseSampleList")
    public R<Map<String, List<OutSampleVO>>> choseSampleList(String keyWords) {
        Map<String, List<OutSampleVO>> map = samplePutInStorageService.choseSampleList(keyWords);
        return R.ok(map, "查询成功");
    }

    @ApiOperation(value = "临时入库接口，修改检材状态")
    @PutMapping("/tempSampleIn")
    public R temporaryProcessSampleIn(@RequestBody List<OutSampleVO> vos) {
        samplePutInStorageService.temporaryProcessSampleIn(vos, SecurityUtils.getUser());
        return R.ok();
    }


    /**
     * 生成出入库登记表
     *
     * @param
     */
    @ApiOperation(value = "生成出入库单个登记表", notes = "生成出入库单个登记表。如果还没有创建, 立即创建: 根据鉴定申请信息内容的内容创建PDF格式的鉴定委托书, 并保存到 MinIO 存储中")
    @SysLog("生成出入库登记表")
    @GetMapping("/print/inAndOutTable")
//	@PreAuthorize("@pms.hasPermission('EntrustmentEdit')")
    public R bizGetPDFSampleInAndOutTable(String sampleId, HttpServletRequest theHttpServletRequest, HttpServletResponse httpServletResponse) {
        System.out.println("bizApplyWord.................");
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();


        //查询数据
        BaseSampleDetail sampleDetailInfo = storageMapper.getSampleDetailInfo(sampleId);
        if (sampleDetailInfo == null) {
            throw new RuntimeException("没有找到检材相关信息");
        }

        List<InAndOutInfos> inAndOutInfos = tableMapper.getInandOutTableInfo(sampleId);
        if (inAndOutInfos == null || inAndOutInfos.size() == 0) {
            throw new RuntimeException("没有找到检材出入库相关信息");
        }

        String id = IdWorker.get32UUID().toUpperCase();

        String applyFileName = "检材出入库登记表-" + id;
        String pdfFilePath = "document" + "/" + "repository" + "/" + id + "/" + applyFileName + ".docx";

        try {
            //直接调用生成
            GenerateSampleApplyTablePDF(inAndOutInfos, id, theHttpServletRequest, httpServletResponse);
            return R.ok(pdfFilePath);
//            ossFile.fileGet(pdfFilePath, httpServletResponse.getOutputStream());
//            httpServletResponse.setContentType(applyFileName);
        } catch (Exception e) {
            System.out.printf("minioFile objectExist() Exception. %s%n", e.getLocalizedMessage());
            e.printStackTrace();
            return R.failed("生成失败!");
        }
    }


    private void GenerateSampleApplyTablePDF(List<InAndOutInfos> inAndOutInfos, String id, HttpServletRequest theHttpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        System.out.println("GenerateSampleApplyTablePDF.................");

        //-----------------------------
        // 生成 word 版本的 鉴定委托书

        String applyFileName = "检材出入库登记表-" + id;

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ossFile.fileGet("template" + "/" + "检材样本出入库登记表模板.docx", bos);

        byte[] templateArray = bos.toByteArray();

        ByteArrayInputStream bis = new ByteArrayInputStream(templateArray);
        bos.close();

        for (int i = 0; i < inAndOutInfos.size(); i++) {
            InAndOutInfos table = inAndOutInfos.get(i);
            table.setNumber(i + 1);
            if (inAndOutInfos.get(i).getSampleType().equals("A")) {
                inAndOutInfos.get(i).setSampleType("分析样");
            } else {
                inAndOutInfos.get(i).setSampleType("留存样");
            }
        }
//        int size = inAndOutInfos.size();
//        int index = 0;
//        if (size < 12) {
//            index = 12 - size;
//            for (int i = 0; i < index; i++) {
//                InAndOutInfos inAndOutInfos1 = new InAndOutInfos();
//                inAndOutInfos1.setSampleType("");
//                inAndOutInfos1.setSampleNo("");
//                inAndOutInfos1.setNumber(null);
//                inAndOutInfos1.setWarehousingDate(null);
//                inAndOutInfos1.setAppraiserName("");
//                inAndOutInfos1.setReturnTime(null);
//                inAndOutInfos1.setImName(null);
//                inAndOutInfos1.setRemarks("");
//                inAndOutInfos.add(inAndOutInfos1);
//            }
//        } else if (size > 12) {
//            index = size % 12;
//            if (index != 0) {
//                for (int i = 0; i < index; i++) {
//                    InAndOutInfos inAndOutInfos1 = new InAndOutInfos();
//                    inAndOutInfos1.setSampleType("");
//                    inAndOutInfos1.setSampleNo("");
//                    inAndOutInfos1.setNumber(null);
//                    inAndOutInfos1.setWarehousingDate(null);
//                    inAndOutInfos1.setAppraiserName("");
//                    inAndOutInfos1.setReturnTime(null);
//                    inAndOutInfos1.setImName(null);
//                    inAndOutInfos1.setRemarks("");
//                    inAndOutInfos.add(inAndOutInfos1);
//                }
//            }
//        }
//

        LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();

        Configure config = Configure.builder().
                bind("inAndOutInfos", policy).build();
        /**
         * 循环表格
         */
        XWPFTemplate template = XWPFTemplate.compile(bis, config).render(
                new HashMap<String, Object>() {{
                    put("inAndOutInfos", inAndOutInfos);
                    put("year", LocalDateTimeUtil.format(LocalDate.now(), "yyyy"));//将年份设置为编号
                }}
        );
        bis.close();

        ByteArrayOutputStream fosWord = new ByteArrayOutputStream();
        template.write(fosWord);
        template.close();

        //------------
        ByteArrayInputStream fisWord = new ByteArrayInputStream(fosWord.toByteArray());
        fosWord.close();
        boolean ret = ossFile.fileSave("document" + "/" + "repository" + "/" + id + "/" + applyFileName + ".docx", fisWord);
        if (ret) {
            System.out.println("生成word成功~~~~~~~~~~~~~~~~~~~~~~" + "document" + "/" + "repository" + "/" + id + "/" + applyFileName + ".docx");
        } else {
            System.out.println("生成word失败~~~~~~~~~~~~~~~~~~~~~~");
        }
        //MockMultipartFile mockMultipartFile = new MockMultipartFile("file", entrustmentLetterFileName + ".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", fisWord);
//        MockMultipartFile mockMultipartFile = new MockMultipartFile("file", applyFileName + ".docx", "image/jpg", fisWord);
//        Response response = remoteWord2PDFService.word2pdf(mockMultipartFile);
//        fisWord.close();
//
//
//        ByteArrayOutputStream outPDF = new ByteArrayOutputStream();
//        IoUtil.copy(response.body().asInputStream(), outPDF, IoUtil.DEFAULT_MIDDLE_BUFFER_SIZE);
//        ByteArrayInputStream isPDF = new ByteArrayInputStream(outPDF.toByteArray());
//        outPDF.close();

//        isPDF.close();
//
//
//        System.out.println("转换为 PDF 结束");
    }


    /**
     * 返回当前样本管理中所存在的委托/任务列表
     */
    @ApiOperation(value = "返回任务/委托列表", notes = "返回任务/委托列表")
    @GetMapping("/event/list")
    public R<List<BaseEvent>> eventList(String name) {

        ArrayList<BaseEvent> baseEvents = new ArrayList<>();
        //查询毛发
        List<String> hairJobIds = tableMapper.queryHairJob();
        //查询相关事件信息
        if (hairJobIds != null) {
            for (String id : hairJobIds) {
                BaseEvent baseEvent = new BaseEvent();
                String hairJobName = tableMapper.getHairJobName(id, name);
                if (hairJobName != null) {
                    baseEvent.setEventId(id);
                    baseEvent.setEventName(hairJobName);
                    baseEvent.setSource("hairJob");
                    baseEvents.add(baseEvent);
                }
            }
        }
        //查询污水
        List<String> sewageJobIds = tableMapper.querySewageJob();
        if (sewageJobIds != null) {
            for (String id : sewageJobIds) {
                BaseEvent baseEvent = new BaseEvent();
                String sewageJobName = tableMapper.getSewageJobName(id, name);
                if (sewageJobName != null) {
                    baseEvent.setEventId(id);
                    baseEvent.setEventName(sewageJobName);
                    baseEvent.setSource("sewageJob");
                    baseEvents.add(baseEvent);
                }
            }
        }
        //查询委托
        List<String> entrustmentIds = tableMapper.queryEntrustment();
        if (entrustmentIds != null) {
            for (String id : entrustmentIds) {
                BaseEvent baseEvent = new BaseEvent();
                String entrustmentName = tableMapper.getEntrustmentName(id, name);
                if (entrustmentName != null) {
                    baseEvent.setEventId(id);
                    baseEvent.setEventName(entrustmentName);
                    baseEvent.setSource("entrustment");
                    baseEvents.add(baseEvent);
                }
            }
        }
        //查询事件
        List<String> eventIds = tableMapper.queryEvent();
        if (eventIds != null) {
            for (String id : eventIds) {
                BaseEvent baseEvent = new BaseEvent();
                String eventName = tableMapper.getEventName(id, name);
                if (eventName != null) {
                    baseEvent.setEventId(id);
                    baseEvent.setEventName(eventName);
                    baseEvent.setSource("Event");
                    baseEvents.add(baseEvent);
                }
            }
        }
        //查询特征分析
        List<String> featureIds = tableMapper.queryFeature();
        if (featureIds != null) {
            for (String id : featureIds) {
                BaseEvent baseEvent = new BaseEvent();
                String eventName = tableMapper.getFeatureName(id, name);
                if (eventName != null) {
                    baseEvent.setEventId(id);
                    baseEvent.setEventName(eventName);
                    baseEvent.setSource("feature");
                    baseEvents.add(baseEvent);
                }
            }
        }

        return R.ok(baseEvents, "查询成功");
    }


    /**
     * 按照时间段来生成出入库登记表
     */
    @ApiOperation(value = "按时间/委托段生成登记表", notes = "按时间/委托段生成登记表。如果还没有创建, 立即创建: 根据鉴定申请信息内容的内容创建PDF格式的鉴定委托书, 并保存到 MinIO 存储中")
    @SysLog("生成出入库登记表")
    @GetMapping("/print/inAndOutTableByDateOrEvent")
//	@PreAuthorize("@pms.hasPermission('EntrustmentEdit')")
    public R bizGetPDFSampleInAndOutTableByDate(PrintTableDTO dto, HttpServletRequest theHttpServletRequest, HttpServletResponse httpServletResponse) {
        System.out.println("bizApplyWord.................");

        List<InAndOutInfos> inAndOutInfos = new ArrayList<>();
        List<String> sampleIds = null;
        if (dto.getType() == 1) {
            //委托/任务
            switch (dto.getSource()) {
                case "entrustment":
                    //委托(对应样本表中所有检材样本id)
                    sampleIds = tableMapper.getSampleIdsByEw(dto.getEventId());
                    break;
                case "hairJob":
                    //毛发
                    sampleIds = tableMapper.getSampleIdsByHj(dto.getEventId());
                    break;
                case "sewageJob":
                    //污水
                    sampleIds = tableMapper.getSampleIdsBySj(dto.getEventId());
                    break;
                case "Event":
                    //事件
                    sampleIds = tableMapper.getSampleIdsByTy(dto.getEventId());
                    break;
                default:
                    //特征分析
                    sampleIds = tableMapper.getSampleIdsByTz(dto.getEventId());
                    break;
            }

            if (sampleIds != null) {
                for (String sampleId : sampleIds) {
                    List<InAndOutInfos> inAndOutTableInfo = tableMapper.getInandOutTableInfo(sampleId);
                    if (inAndOutTableInfo != null) {
                        inAndOutInfos.addAll(inAndOutTableInfo);
                    }
                }
            }

        } else {
            //根据时间
            inAndOutInfos = tableMapper.getInandOutTableInfoByDate(dto.getBeginDate(), dto.getFinishDate());
        }

        //查询数据

        if (inAndOutInfos.size() == 0) {
            throw new RuntimeException("没有找到检材出入库相关信息");
        }

        String id = IdWorker.get32UUID().toUpperCase();

        String applyFileName = "检材出入库登记表-" + id;
        ;
        String pdfFilePath = "document" + "/" + "repository" + "/" + id + "/" + applyFileName + ".docx";
        ;

        try {
            //直接调用生成
            GenerateSampleApplyTablePDF(inAndOutInfos, id, theHttpServletRequest, httpServletResponse);
            return R.ok(pdfFilePath);
        } catch (Exception e) {
            System.out.println(String.format("minioFile objectExist() Exception. %s", e.getLocalizedMessage()));
            e.printStackTrace();
        }
        return R.ok(pdfFilePath);
    }

    /**
     * 检材管理首页子模块所有角标
     * 一.检材流转
     * 1.待接收+2.待见证
     * 二.入库管理
     * 1.销毁预警
     * 三.出库管理
     * 1.待确认出库申请+2.待归还
     * 四.审核审批
     * 1.待审核/待审批
     */
    @ApiOperation(value = "检材管理首页子模块所有角标", notes = "检材管理首页子模块所有角标")
    @SysLog("检材管理首页子模块所有角标")
    @GetMapping("/getAllModuleIcon")
    //@PreAuthorize("@pms.hasPermission('imr_inbound_or_outbound')")
    public R<List<IconDTO>> getAllModuleIcon(HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

		/*Set<String> permissions = dlpUser.getPermissions();
		if(permissions.contains("imr_sample_apply_first_audit")){
			//一级审核

		} else if (permissions.contains("imr_sample_apply_secondary_audit")) {
			//二级审核
		} else if (permissions.contains("imr_sample_apply_approval")) {
			//审批
		}*/

        ArrayList<IconDTO> iconDTOS = new ArrayList<>();

        //1.检材流转
        IconDTO count1 = samplePutInStorageService.getTransferIconCount(dlpUser.getId());
        if (count1 != null) {
            iconDTOS.add(count1);
        }

        //入库管理--销毁预警
        QueryWrapper<SampleStorage> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.eq("early_warning", 1);
        queryWrapper1.eq("status", 2);//只能查看当前入库的
        Long destroyed = storageMapper.selectCount(queryWrapper1);
        IconDTO count2 = null;
        if (destroyed != 0) {
            count2 = new IconDTO(destroyed, 3, "inbound");
            iconDTOS.add(count2);
        }


        //出库管理--待归还+待确认
        Long countReturn = storageMapper.selectCount(Wrappers.<SampleStorage>query()
                .eq("status", 3)
                .eq("is_return", 1)//需要归还
        );

        //出库申请
        Long countConfirm = outWarehouseApplyMapper.selectCount(Wrappers.<SampleOutWarehouseApply>query()
                .eq("status", 1)//待确认
        );
        IconDTO count3 = null;
        if (countReturn + countConfirm != 0) {
            count3 = new IconDTO(countReturn + countConfirm, 4, "outbound");
            iconDTOS.add(count3);
        }
        //审核/审批

        return R.ok(iconDTOS, "查询成功");
    }

    /*
    getExternalModuleIcon
    获取部分模块的角标
     */
    @ApiOperation(value = "获取部分模块的角标", notes = "获取部分模块的角标")
    @GetMapping("/getExternalModuleIcon")
    public R<List<IconVO>> getExternalModuleIcon(HttpServletRequest theHttpServletRequest) {

        ArrayList<IconVO> list = new ArrayList<>();

        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        Set<String> permissions = dlpUser.getPermissions();

        //流转(imt_sample_transfer_get)
        if (permissions.contains("imt_sample_transfer_get")) {

            int count = storageMapper.queryTransfer(dlpUser.getId());
            if (count != 0) {
                IconVO iconVO = new IconVO("sample-circulation", true);
                list.add(iconVO);
            }
        }
        if (permissions.contains("imr_sample_out_warehouse_apply_get")) {
            //出库申请申请人是自己并且待操作的数据
            QueryWrapper<SampleOutWarehouseApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("status", 2);//已经创建待使用
            queryWrapper.eq("applicant_id", dlpUser.getId());

            Long count = outWarehouseApplyMapper.selectCount(queryWrapper);
            if (count != 0) {
                IconVO iconVO = new IconVO("outapplication", true);
                list.add(iconVO);
            }
        }
        if (permissions.contains("imr_inbound_or_outbound")) {
            //出库 待操作的数据 出库申请+领用待归还的

            QueryWrapper<SampleStorage> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("is_return", 1);//只查询需要归还的
            wrapper1.eq("status", 3);

            Long count1 = storageMapper.selectCount(wrapper1);


            QueryWrapper<SampleOutWarehouseApply> wrapper2 = new QueryWrapper<>();
            wrapper2.eq("status", 1);//待确定的数据
            Long count2 = outWarehouseApplyMapper.selectCount(wrapper2);

            if (count1 + count2 != 0) {
                IconVO iconVO = new IconVO("outbound-management", true);
                list.add(iconVO);
            }
        }
        if (permissions.contains("imr_inbound_or_outbound")) {
            //入库
            QueryWrapper<SampleStorage> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("early_warning", 1);
            wrapper1.eq("status", 2);//只能查看当前入库的

            Long count1 = storageMapper.selectCount(wrapper1);

            if (count1 != 0) {
                IconVO iconVO = new IconVO("warehousing-management", true);
                list.add(iconVO);
            }

        }

        //审核审批
        if (permissions.contains("imr_sample_apply_first_audit")) {
            //一级审核员
            QueryWrapper<SampleApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("application_status", 1);
            Long count1 = asMapper.selectCount(queryWrapper);

            if (count1 != 0) {
                IconVO iconVO = new IconVO("review-approval", true);
                list.add(iconVO);
            }

        } else if (permissions.contains("imr_sample_apply_secondary_audit")) {
            //二级审核员
            QueryWrapper<SampleApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("application_status", 2);
            Long count1 = asMapper.selectCount(queryWrapper);

            if (count1 != 0) {
                IconVO iconVO = new IconVO("review-approval", true);
                list.add(iconVO);
            }
        } else if (permissions.contains("imr_sample_apply_approval")) {
            //审批人
            QueryWrapper<SampleApply> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("application_status", 3);
            Long count1 = asMapper.selectCount(queryWrapper);

            if (count1 != 0) {
                IconVO iconVO = new IconVO("review-approval", true);
                list.add(iconVO);
            }
        }
        if (list.size() > 0) {
            return R.ok(list, "查询成功");
        } else {
            return R.failed("暂无数据");
        }
    }


}
