package digital.laboratory.platform.imr.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.imr.dto.CombinationOut;
import digital.laboratory.platform.imr.dto.OutWarehouseApplyDTO;
import digital.laboratory.platform.imr.dto.QueryDTO;
import digital.laboratory.platform.imr.entity.SampleOutWarehouseApply;
import digital.laboratory.platform.imr.entity.SampleStorage;
import digital.laboratory.platform.imr.mapper.SampleStorageMapper;
import digital.laboratory.platform.imr.service.SampleOutWarehouseApplyService;
import digital.laboratory.platform.imr.vo.OutSampleVO;
import digital.laboratory.platform.imr.vo.RepositorySampleVO;
import digital.laboratory.platform.imr.vo.SampleOutWarehouseApplyVO;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 样本出库申请实体类
 *
 * @author Zhang Xiaolong created at  2023-03-17
 * @describe 样本出库申请实体类 前端控制器
 * <p>
 * 这是与表示层的接口, 不应该接业务逻辑写在这里, 业务逻辑应该写在 service 中
 * 这里写什么:
 * 为前端提供数据, 接受前端的数据
 * 为前端提供的数据, 从 service 取得后, 可以做一些适当的加工, 这种加工不是业务层面的, 只能是数据格式上, 为方便前端处理
 * 接受前端的数据, 每一个函数的参数可以先做一些整理后, 再调用 service 中的函数。这里对参数的整理, 应该只是格式上的, 而不能是业务上的
 * 数据层在 mapper 中, 数据层不涉及业务, 只管技术上的 对象<->表 之间的转换
 */
@RestController
@RequiredArgsConstructor
@RequestMapping("/sample_out_warehouse_apply")
@Api(value = "sample_out_warehouse_apply", tags = "领用出库申请管理")
public class SampleOutWarehouseApplyController {

    private final SampleOutWarehouseApplyService sampleOutWarehouseApplyService;

    private final SampleStorageMapper storageMapper;

    /**
     * 通过id查询样本出库申请实体类
     *
     * @param id id
     * @return R
     */
    @ApiOperation(value = "通过id查询", notes = "通过id查询")
    @GetMapping("/{id}")
    @PreAuthorize("@pms.hasPermission('imr_sample_out_warehouse_apply_get')")
    public R<SampleOutWarehouseApplyVO> getById(@PathVariable("id") String id, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        SampleOutWarehouseApplyVO outWarehouseApplyVO = sampleOutWarehouseApplyService.getOutWarehouseDetailedById(id);
        if (outWarehouseApplyVO != null) {
            return R.ok(outWarehouseApplyVO, "查询成功");
        } else {
            return R.failed("查询失败");
        }
    }

    /**
     * 分页查询
     *
     * @param dto 查询参数
     * @return
     */
    @ApiOperation(value = "分页查询", notes = "分页查询")
    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('imr_sample_out_warehouse_apply_get')")
    public R<IPage<SampleOutWarehouseApplyVO>> getSampleOutWarehouseApplyPage(QueryDTO dto, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        QueryWrapper<SampleOutWarehouseApply> query = Wrappers.<SampleOutWarehouseApply>query();
        query.eq("applicant_id", dlpUser.getId());
        query.between(dto.getBeginDate() != null && dto.getFinishDate() != null, "application_date", dto.getBeginDate(), dto.getFinishDate());
        query.orderByDesc("create_time");

        if (dto.getStatus() == 0) {//返回待审核和待使用的数据
            ArrayList<Integer> integers = new ArrayList<>();
            integers.add(1);
            integers.add(2);
            query.in("status", integers);
        } else if (dto.getStatus() == 1) {
            query.eq("status", 1);
        } else if (dto.getStatus() == 2) {
            query.eq("status", 2);
        } else if (dto.getStatus() == 3) {
            query.eq("status", 3);
        }

        if (dto.getStatus() == 4) {//全部数据--出库模块备用
            ArrayList<Integer> integers = new ArrayList<>();
            integers.add(1);
            integers.add(2);
            integers.add(3);
            query.in("status", integers);
        }

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

        IPage<SampleOutWarehouseApplyVO> thisPage = sampleOutWarehouseApplyService.getSampleOutWarehouseApplyVOPage(page, query);
        return R.ok(thisPage, "查询出库申请成功");
    }

    @ApiOperation(value = "列表查询", notes = "列表查询")
    @GetMapping("/list")
    @PreAuthorize("@pms.hasPermission('imr_sample_out_warehouse_apply_list')")
    public R<IPage<SampleOutWarehouseApply>> getSampleOutWarehouseApplyList(Page<SampleOutWarehouseApply> page, SampleOutWarehouseApply sampleOutWarehouseApply, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        IPage<SampleOutWarehouseApply> thisList = sampleOutWarehouseApplyService.getSampleOutWarehouseApplyVOList(Wrappers.<SampleOutWarehouseApply>query()
                .eq("applicant_id", dlpUser.getId())
                .eq(sampleOutWarehouseApply.getStatus() != null, "status", sampleOutWarehouseApply.getStatus())
                .orderByDesc("create_time")
        );
        return R.ok(thisList, "查询出库申请成功");
    }


    /**
     * 查询当前已经存入仓库的样本信息(全部查询)
     */

    @ApiOperation(value = "创建领用申请时的查询样本接口--分页", notes = "创建领用申请时的查询样本接口--分页")
    @GetMapping("/getSampleInfo")
    @PreAuthorize("@pms.hasPermission('imr_sample_out_warehouse_apply_list')")
    public R getSampleInfo(QueryDTO dto) {

        List<String> sampleIds = Arrays.asList(dto.getSampleIds().split(","));

        if (dto.getType() == 1) {//任务
            IPage<OutSampleVO> sampleVOIPage2 = new Page<>();
            List<OutSampleVO> records1 = new ArrayList<>();

            if (dto.getType() == 1) {
                Integer begin = (dto.getCurrent() - 1) * dto.getSize();
                CombinationOut combinationOut = new CombinationOut(sampleIds, begin, dto.getSize(), dto.getName());
                //获取仓库现有样本;并进行事件分类
                //1.委托
                List<OutSampleVO> vo1 = storageMapper.getWTSample(combinationOut);
                if (!vo1.isEmpty()) {
                    records1.addAll(vo1);
                }

                List<OutSampleVO> vo2 = storageMapper.getWSSample(combinationOut);
                if (!vo2.isEmpty()) {
                    records1.addAll(vo2);
                }
                List<OutSampleVO> vo3 = storageMapper.getMFSample(combinationOut);
                if (!vo3.isEmpty()) {
                    records1.addAll(vo3);
                }
                List<OutSampleVO> vo4 = storageMapper.getSJSample(combinationOut);
                if (!vo4.isEmpty()) {
                    records1.addAll(vo4);
                }
                List<OutSampleVO> vo5 = storageMapper.getTZSample(combinationOut);
                if (!vo5.isEmpty()) {
                    records1.addAll(vo5);
                }
            }

            if (records1.size() == 0) {
                return R.ok(sampleVOIPage2, "暂无数据");
            }
            Collections.sort(records1, new Comparator<OutSampleVO>() {
                @Override
                public int compare(OutSampleVO o1, OutSampleVO o2) {
                    return o1.getRoomNo().compareTo(o2.getSampleNo());
                }
            });
            List<OutSampleVO> records2 = new ArrayList<>();
            sampleVOIPage2.setSize(dto.getSize());
            int pageCurrent = (dto.getCurrent() - 1) * dto.getSize();
            int pageTotal = 0;
            if (records1.size() % dto.getSize() == 0) {
                pageTotal = records1.size() / dto.getSize();
            } else {
                pageTotal = records1.size() / dto.getSize() + 1;
            }
            if (pageCurrent + dto.getSize() <= records1.size()) {
                records2 = records1.subList(pageCurrent, pageCurrent + dto.getSize());
            } else if (records1.size() % dto.getSize() > sampleIds.size() - 1) {
                records2 = records1.subList(pageCurrent, records1.size());
            } else if (dto.getCurrent() > pageTotal) {
                records2 = records1.subList(pageCurrent - dto.getSize(), records1.size());
            } else {
                records2 = records1.subList(pageCurrent, records1.size());
            }
            sampleVOIPage2.setTotal(records1.size());//不分页总数
            sampleVOIPage2.setRecords(records2);
            return R.ok(sampleVOIPage2, "查询成功");

        } else {
//            int size = sampleIds.size();
//            if ("".equals(dto.getSampleIds())) {
//                size = sampleIds.size() - 1;
//            }
//            if (dto.getTotal() != 0) {
//                int num = 0;//去重后目前能分的页数
//
//                if ((dto.getTotal() - size) % 8 == 0) {
//                    num = (dto.getTotal() - size) / 8;
//                } else {
//                    num = (dto.getTotal() - size) / 8 + 1;
//                }
//
//
//                if (dto.getCurrent() > num) {
//                    //求余数
//                    int a = dto.getTotal() % 8;//求最后一页的剩余条数
//                    if (a == 0) {
//                        a = 8;
//                    }
//                    if (sampleIds.size() >= a) {
//                        dto.setCurrent(num);
//                    }
//                }
//            }
//            Page<SampleStorage> page = new Page<>(dto.getCurrent(), dto.getSize());

            List<OutSampleVO> sampleVOList = storageMapper.getSampleInfoList(Wrappers.<SampleStorage>query()
                    .and(StringUtils.isNotBlank(dto.getName()), qw -> qw
                            .like("storage.name", dto.getName())
                            .or()
                            .like("sample_no", dto.getName()))
                    .notIn(!sampleIds.isEmpty(), "storage.sample_id", sampleIds)//去重数组sampleIds
                    .eq("storage.status", 2)  //只能查找存入仓库的样本数据
                    .eq("s.status", 2)//并且sample实际状态为2
                    .like(StringUtils.isNotBlank(dto.getRoomNo()), "storage.room_no", dto.getRoomNo())
                    .orderByDesc("sample_no")
            );
            for (OutSampleVO vo : sampleVOList) {
                vo.setSampleId(vo.getId());
                String eventName = "";
                //entrustment/hairJob/sewageJob
                if (vo.getSource().equals("entrustment")) {
                    //委托
                    eventName = storageMapper.getEntrustmentName(vo.getSampleId());
                } else if (vo.getSource().equals("hairJob")) {
                    //毛发
                    eventName = storageMapper.getHairJobName(vo.getSampleId());
                } else if (vo.getSource().equals("sewageJob")) {
                    //污水
                    eventName = storageMapper.getSewageJobName(vo.getSampleId());
                } else if (vo.getSource().contains("Event")) {//通用事件
                    //内部录入
                    eventName = storageMapper.getEventName(vo.getSampleId());
                } else {
                    //特征分析
                    eventName = storageMapper.getFeatureName(vo.getSampleId());
                }
                vo.setEventName(eventName);
            }
            Map<String, List<OutSampleVO>> map = sampleVOList.stream().collect(Collectors.groupingBy(item -> item.getSource()));
            List<OutSampleVO> entrustmentSampleList = map.get("entrustment");
            List<OutSampleVO> outSampleVOS = new ArrayList<>();
            if (entrustmentSampleList != null && entrustmentSampleList.size() > 0) {
                sampleVOList.removeAll(entrustmentSampleList);
                Collections.sort(entrustmentSampleList, 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;

                    }
                });
                outSampleVOS.addAll(entrustmentSampleList);
            }
            outSampleVOS.addAll(sampleVOList);
            return R.ok(outSampleVOS, "查询成功");
        }
    }


    /**
     * 查询当前已经存入仓库的样本信息(根据当前登录人查询对应部门的sample信息)
     */


    /**
     * 新增样本出库申请实体类
     *
     * @param dto 样本出库申请实体类
     * @return R
     */
    @ApiOperation(value = "新增样本出库申请实体类", notes = "新增样本出库申请实体类")
    @SysLog("新增样本出库申请实体类")
    @PostMapping("/addOutApply")
    @PreAuthorize("@pms.hasPermission('imr_sample_out_warehouse_apply_add')")
    public R<SampleOutWarehouseApply> postAddOutApply(@RequestBody OutWarehouseApplyDTO dto, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        //数据校验
        if (dto.getSampleIds() == null || dto.getSampleIds().size() == 0) {
            throw new RuntimeException("申请出库检材不能为空");
        }
        if (dto.getReturnDate() == null) {
            throw new RuntimeException("归还时间不能为空");
        }
        if ("".equals(dto.getAppraiserId()) || dto.getAppraiserId().isEmpty()) {
            throw new RuntimeException("鉴定人不能为空");
        }

        SampleOutWarehouseApplyVO vo = sampleOutWarehouseApplyService.createOutApply(dto, dlpUser);
        if (vo != null) {
            return R.ok(vo, "创建出库申请成功");
        } else {
            return R.failed("创建出库申请失败");
        }
    }


    /**
     * 创建样本出库申请(接口2)
     *
     * @param dto
     * @param theHttpServletRequest
     * @return
     */
    @ApiOperation(value = "创建样本出库申请(老版本)", notes = "创建样本出库申请(老版本)")
    @SysLog("创建样本出库申请")
    @PostMapping("/createOutRepositoryApply")
    @PreAuthorize("@pms.hasPermission('imr_sample_out_warehouse_apply_add')")
    public R createOutRepositoryApply(@RequestBody OutWarehouseApplyDTO dto, HttpServletRequest theHttpServletRequest) {
        Principal principal = theHttpServletRequest.getUserPrincipal();
        DLPUser dlpUser = (DLPUser) ((OAuth2Authentication) principal).getUserAuthentication().getPrincipal();

        //数据校验
        if (dto.getSampleIds().isEmpty()) {
            throw new RuntimeException("申请检材不能为空");
        }
        if (dto.getReturnDate() == null) {
            throw new RuntimeException("归还时间不能为空");
        }
        if ("".equals(dto.getAppraiserId()) || dto.getAppraiserId().isEmpty()) {
            throw new RuntimeException("鉴定人不能为空");
        }

        SampleOutWarehouseApplyVO vo = sampleOutWarehouseApplyService.createOutRepositoryApply(dto, dlpUser);
        if (vo != null) {
            return R.ok(vo, "创建出库申请成功");
        } else {
            return R.failed("创建出库申请失败");
        }
    }


    @ApiOperation(value = "取检条码打印",
            notes = "取检条码打印")
    @SysLog("检材条码打印")
    @GetMapping("/print_QR_code")
    public String printgetSampleQRCode(String code) {

        return sampleOutWarehouseApplyService.buildEventImLabelContent(code);
    }


    /**
     * 以下为新创建接口----------------------------------------------------------------------
     */

    @GetMapping("/testQuery")
    public R testQuery(QueryDTO dto) {

        List<String> sampleIds = Arrays.asList(dto.getSampleIds().split(","));
        IPage<OutSampleVO> sampleVOIPage2 = new Page<>();
        List<OutSampleVO> records1 = new ArrayList<>();
        int total = 0;

        if (dto.getType() == 1) {
            Integer begin = (dto.getCurrent() - 1) * dto.getSize();
            CombinationOut combinationOut = new CombinationOut(sampleIds, begin, dto.getSize(), dto.getName());
            //获取仓库现有样本;并进行事件分类
            //1.委托
            List<OutSampleVO> vo1 = storageMapper.getWTSample(combinationOut);
            if (!vo1.isEmpty()) {
                total = total + vo1.size();
                records1.addAll(vo1);
            }

            //2.污水
            List<OutSampleVO> vo2 = storageMapper.getWSSample(combinationOut);
            if (!vo2.isEmpty()) {
                total = total + vo2.size();
                records1.addAll(vo2);
            }
            //3.毛发
            List<OutSampleVO> vo3 = storageMapper.getMFSample(combinationOut);
            if (!vo3.isEmpty()) {
                total = total + vo3.size();
                records1.addAll(vo3);
            }
            //4.事件
            List<OutSampleVO> vo4 = storageMapper.getSJSample(combinationOut);
            if (!vo4.isEmpty()) {
                total = total + vo4.size();
                records1.addAll(vo4);
            }
        }

        sampleVOIPage2.setTotal(total);
        sampleVOIPage2.setRecords(records1);
        return R.ok(sampleVOIPage2, "查询成功");
    }



	/*if(pageCurrent<records1.size()){
		if(pageCurrent+dto.getSize()<=records1.size()){
			records2 = records1.subList(pageCurrent,pageCurrent+dto.getSize());
		}else {
			if(records1.size()%dto.getSize()>sampleIds.size()-1){
				records2 = records1.subList(pageCurrent,records1.size());
			}else {
				if(dto.getCurrent()>=2){
					records2 = records1.subList(pageCurrent-dto.getSize(),records1.size());
				}else {
					records2 = records1.subList(0,records1.size());
				}
			}
		}
	}*/

					/*if(records1.size()%dto.getSize()>sampleIds.size()-1){
					records2 = records1.subList(pageCurrent,records1.size());
				}else {
					if (dto.getCurrent() > Math.ceil((float)records1.size()/dto.getSize())) {
						records2 = records1.subList(pageCurrent - dto.getSize(), records1.size());
					} else {
						records2 = records1.subList(pageCurrent, records1.size());
					}
				}*/


}
