package digital.laboratory.platform.entrustment.controller;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import digital.laboratory.platform.common.core.util.R;
import digital.laboratory.platform.common.log.annotation.SysLog;
import digital.laboratory.platform.entrustment.entity.*;
import digital.laboratory.platform.entrustment.mapper.EntrustmentMapper;
import digital.laboratory.platform.entrustment.service.EntrustmentIdentificationMaterialService;
import digital.laboratory.platform.entrustment.service.SampleBoxService;
import digital.laboratory.platform.entrustment.service.SampleService;
import digital.laboratory.platform.entrustment.vo.SampleBoxLiteVO;
import digital.laboratory.platform.entrustment.vo.SampleBoxVO;
import digital.laboratory.platform.sewage.entity.SewageJob;
import digital.laboratory.platform.sys.entity.entrustment.Sample;
import digital.laboratory.platform.sys.entity.entrustment.SampleBox;
import digital.laboratory.platform.sewage.feign.RemoteSewageJobService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 受理时样品重新包装的容器
 *
 * @author Zhang Xiaolong created at  2022-07-06
 * @describe 受理时检材重新包装的容器 前端控制器
 */
@RestController
@RequestMapping("/papp/entrustment/sample_box")
@Api(value = "sample_box", tags = "005-受理时样品重新包装的容器管理")
public class SampleBoxController {

    @Resource
    private SampleBoxService sampleBoxService;

    @Resource
    private SampleService sampleService;

    @Resource
    private EntrustmentIdentificationMaterialService entrustmentIdentificationMaterialService;

    @Resource
    private EntrustmentMapper entrustmentMapper;

    @Resource
    private RemoteSewageJobService remoteSewageJobService;

    /**
     * 通过id查询受理时样品重新包装的容器
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}")
//	@PreAuthorize("@pms.hasPermission('entrustment_sample_box_get')" )
    public R<SampleBox> getSampleBoxById(@PathVariable("id") String id) {
        return R.ok(sampleBoxService.getById(id));
    }

    /**
     * 分页查询
     *
     * @param page      分页对象
     * @param sampleBox 受理时样品重新包装的容器
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page")
//    @PreAuthorize("@pms.hasPermission('entrustment_sample_box_get')" )
    public R getSampleBoxPage(Page page, SampleBox sampleBox) {
        return R.ok(sampleBoxService.page(page, Wrappers.query(sampleBox)));
    }

    /**
     * 列表查询
     *
     * @param sampleBox 受理时样品重新包装的容器
     * @return
     */
    @ApiOperation(value = "列表查询", notes = "列表查询")
    @GetMapping("/list")
//    @PreAuthorize("@pms.hasPermission('entrustment_sample_box_get')" )
    public R<List<SampleBoxVO>> getSampleBoxList(SampleBox sampleBox) {
//		List<String> boxIds=new ArrayList<>();
//		List<SampleBox> list = sampleBoxService.list(Wrappers.query(sampleBox));
//		list.forEach(item->{
//			//查询盒子中的样本数量
//			boxIds.add(item.getId());
//		});

        return R.ok(sampleBoxService.getSampleBoxList(sampleBox));
    }


    /**
     * 新增受理时样品重新包装的容器
     *
     * @param sampleBox 受理时样品重新包装的容器
     * @return R
     */
    @ApiOperation(value = "新增受理时样品重新包装的容器", notes = "新增受理时样品重新包装的容器")
    @SysLog("新增受理时样品重新包装的容器")
    @PostMapping
//    @PreAuthorize("@pms.hasPermission('entrustment_sample_box_add')" )
    public R post_CreateNewSampleBox(@RequestBody SampleBox sampleBox) {
        if (StrUtil.equalsIgnoreCase(sampleBox.getSource(), "entrustment")) {
            if (sampleBox.getEntrustmentId() == null) {
                throw new RuntimeException("样本盒必须与某个委托关联, 缺少 entrustmentId");
            }
            Entrustment entrustment = entrustmentMapper.selectById(sampleBox.getEntrustmentId());
            if (entrustment == null) {
                throw new RuntimeException(String.format("不存在 id 为 %s 的委托", sampleBox.getEntrustmentId()));
            }

            if (StrUtil.isBlank(sampleBox.getBoxNo())) {
                sampleBox.setBoxNo(sampleBoxService.getNewBoxNoForEntrustment(entrustment.getEntrustmentNo()));
            }
        } else if (StrUtil.equalsIgnoreCase(sampleBox.getSource(), "sewageJob")) {
            if (sampleBox.getJobId() == null) {
                throw new RuntimeException("样本盒必须与某个污水任务关联, 缺少 jobId");
            }
            SewageJob sewageJob = remoteSewageJobService.getSewageJobById(sampleBox.getJobId()).getData();
            if (sewageJob == null) {
                throw new RuntimeException(String.format("不存在 id 为 %s 的污水任务", sampleBox.getJobId()));
            }

            if (StrUtil.isBlank(sampleBox.getBoxNo())) {
                sampleBox.setBoxNo(sampleBoxService.getNewBoxNoForSewageJob(sewageJob.getJobNo()));
            }
        }

        sampleBox.setId(sampleBoxService.getOrderIdBy16UUId());

        if (sampleBoxService.save(sampleBox)) {
            return R.ok(sampleBox, "新增样本盒成功");
        } else {
            return R.failed(sampleBox, "新增样本盒失败");
        }

    }

    /**
     * 修改受理时样品重新包装的容器
     *
     * @param sampleBox 受理时样品重新包装的容器
     * @return R
     */
    @ApiOperation(value = "修改受理时样品重新包装的容器", notes = "修改受理时样品重新包装的容器")
    @SysLog("修改受理时样品重新包装的容器")
    @PutMapping
//    @PreAuthorize("@pms.hasPermission('entrustment_sample_box_edit')" )
    public R put_UpdateById(@RequestBody SampleBox sampleBox) {
        return R.ok(sampleBoxService.updateById(sampleBox));
    }

    /**
     * 通过id删除受理时样品重新包装的容器
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id删除受理时样品重新包装的容器", notes = "通过id删除受理时样品重新包装的容器")
    @SysLog("通过id删除受理时样品重新包装的容器")
    @DeleteMapping("/{id}")
//    @PreAuthorize("@pms.hasPermission('entrustment_sample_box_del')" )
    public R deleteById(@PathVariable String id) {

        // 受理期间的样本, 还未受理完成
        SampleBoxLiteVO sblv = sampleBoxService.getSampleBoxLiteVOById(id);
        if (sblv == null) {
            throw new RuntimeException(String.format("没有这个样本盒, id=%s", id));
        }
        if (sblv.getSampleNoList().size() > 0) {
            throw new RuntimeException(String.format("这个样本盒中还有样品, 你必须清除其中的样品后才能删除它"));
        }

        // 受理结束后的样本
        SampleBoxVO sbv = sampleBoxService.getSampleBoxVOById(id);
        if (sbv == null) {
            throw new RuntimeException(String.format("没有这个样本盒, id=%s", id));
        }
        if (sbv.getSampleList().size() > 0) {
            throw new RuntimeException(String.format("这个样本盒中还有样品, 你必须清除其中的样品后才能删除它"));
        }

        // 盒子中没有东西了，可以删除之
        if (sampleBoxService.removeById(id)) {
            return R.ok(sbv, "案件删除成功");
        } else {
            return R.failed(sbv, "案件删除失败");
        }
    }

    /**
     * 添加样本到盒子中
     *
     * @param boxId    盒子的 Id
     * @param sampleId 样本的 Id
     * @return R
     */
    @ApiOperation(value = "添加样本到盒子中", notes = "添加样本到盒子中")
    @SysLog("添加样本到盒子中")
    @PutMapping(value = "/{boxId}/add_sample")
//    @PreAuthorize("@pms.hasPermission('entrustment_sample_box_edit')" )
    public R put_AddSampleToBox(@PathVariable String boxId, String sampleId) {
        SampleBox box = sampleBoxService.getById(boxId);
        if (box == null) {
            throw new RuntimeException(String.format("不存在这个样本盒, Id=%s", boxId));
        }
        Sample sample = sampleService.getById(sampleId);
        if (sample == null) {
            throw new RuntimeException(String.format("不存在这个样本, Id=%s", sampleId));
        }

        sample.setBoxId(boxId);

        if (sampleService.updateById(sample)) {
            return R.ok(sample, "添加检材中的样本到盒子中成功");
        } else {
            return R.failed(sample, "添加检材中的样本到盒子失败");
        }

    }

    /**
     * 添加检材中的样本到盒子中
     *
     * @param boxId                              盒子的 Id
     * @param IdentificationMaterialId           检材的 Id
     * @param IdentificationMaterialSampleSerial 检材中的样本序号
     * @return R
     */
    @ApiOperation(value = "添加检材中的样本到盒子中", notes = "添加检材中的样本到盒子中")
    @SysLog("添加检材中的样本到盒子中")
    @PutMapping(value = "/{boxId}/add_im_sample")
//    @PreAuthorize("@pms.hasPermission('entrustment_sample_box_edit')" )
    public R put_AddIMSampleToBox(@PathVariable String boxId, String IdentificationMaterialId, int IdentificationMaterialSampleSerial) {
        SampleBox box = sampleBoxService.getById(boxId);
        if (box == null) {
            throw new RuntimeException(String.format("不存在这个样本盒, Id=%s", boxId));
        }

        EntrustmentIdentificationMaterial im = entrustmentIdentificationMaterialService.getById(IdentificationMaterialId);
        if (im == null) {
            throw new RuntimeException(String.format("不存在这个检材, Id=%s", IdentificationMaterialId));
        }
        if (IdentificationMaterialSampleSerial == 1) {
            im.setSample1BoxId(boxId);
        } else if (IdentificationMaterialSampleSerial == 2) {
            im.setSample2BoxId(boxId);
        } else {
            throw new RuntimeException(String.format("一个检材只能分为2个样, 不会有样本序号不会大于2"));
        }


        if (entrustmentIdentificationMaterialService.updateById(im)) {
            return R.ok(im, "添加检材中的样本到盒子中成功");
        } else {
            return R.failed(im, "添加检材中的样本到盒子失败");
        }


    }


    //=====================================================================================
    // 测试, 创建 100 个案件
    @ApiOperation(value = "测试用: 创建 10 个样本盒子", notes = "创建 10 个样本盒子")
    @GetMapping("/create100")
    public R xxx_TestCreate100() {
        for (int i = 0; i < 10; i++) {
            SampleBox box = new SampleBox();
            box.setBoxType(RandomUtil.randomEle(new String[]{"小盒", "中盒", "大盒", "小箱", "中箱", "大箱", "文件盒", "特殊"}));
            box.setId(IdWorker.get32UUID().toUpperCase());
            sampleBoxService.save(box);
        }
        return R.ok("100 of SampleBox ware Created");
    }

    @ApiOperation(value = "打印包装袋条码,参数：id:包装袋ID\n" +
            "type：（ 0:小标签条码，1：大标签条码）")
    @GetMapping("/print")
    public String printBoxSmallLabel(@RequestParam(value = "id", required = false) String id, @RequestParam(value = "type", required = false) Integer type) {
        return sampleBoxService.printBoxLabel(id, type);
    }

    @PostMapping("/add/box/{opCode}")
    public R<SampleBox> controlsSampleBox(@PathVariable(value = "opCode") Integer opCode, @RequestBody SampleBox sampleBox) {
        SampleBox box = sampleBoxService.controlsSampleBox(sampleBox, opCode);
        return R.ok(box);
    }

    @ApiOperation(value = "打印包装袋条码,参数：boxId:包装袋ID\n" +
            "type：（ 0:小标签条码，1：大标签条码）")
    @GetMapping("/print/other/{boxId}/{type}")
    public String printLabelForOther(@PathVariable(value = "boxId") String boxId, @PathVariable(value = "type") Integer type) {
        return sampleBoxService.printLabelForOther(boxId, type);

    }

    @GetMapping("/get/for/job_id/{jobId}")
    @ApiOperation(value = "通过任务ID，查询该任务下的所有包装袋",notes = "通过任务ID，查询该任务下的所有包装袋")
    public R<List<SampleBox>> getSampleBoxForOther(@PathVariable(value = "jobId") String jobId) {
        return R.ok(sampleBoxService.list(new LambdaQueryWrapper<SampleBox>().eq(SampleBox::getJobId, jobId)));
    }

}
