package digital.laboratory.platform.imr.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.imr.dto.ApplyDTO;
import digital.laboratory.platform.imr.entity.SampleApply;
import digital.laboratory.platform.imr.entity.SampleApplyDetailed;
import digital.laboratory.platform.imr.enums.ApplyStatus;
import digital.laboratory.platform.imr.feign.TransferFeignService;
import digital.laboratory.platform.imr.mapper.SampleApplyDetailedMapper;
import digital.laboratory.platform.imr.mapper.SampleApplyMapper;
import digital.laboratory.platform.imr.service.SampleApplyService;
import digital.laboratory.platform.imr.vo.ApplySampleVO;
import digital.laboratory.platform.imr.vo.SampleApplyVO;
import digital.laboratory.platform.imr.vo.StatusSampleVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 检材申请实体类服务实现类
 *
 * @author Zhang Xiaolong created at  2023-03-17
 * @describe 检材申请实体类 服务实现类
 */
@Service
@RequiredArgsConstructor
public class SampleApplyServiceImpl extends ServiceImpl<SampleApplyMapper, SampleApply> implements SampleApplyService {


    private final SampleApplyMapper asMapper;

    private final SampleApplyDetailedMapper detailedMapper;


    private final TransferFeignService transferFeignService;


    /**
     * 创建并保存
     * @param dto
     * @param dlpUser
     * @return
     */
    @Override
    @Transactional
    public SampleApplyVO createAndSave(ApplyDTO dto, DLPUser dlpUser) {

        SampleApply apply = new SampleApply();
        apply.setId(IdWorker.get32UUID().toUpperCase());//id
        apply.setApplyType(dto.getApplyType());//类型
        apply.setApplyQuantity(dto.getSampleId().size());//数量
        apply.setApplicationStatus(ApplyStatus.TO_BE_SUBMITTED);//保存是待提交状态
        apply.setReason(dto.getReason());//原因
        apply.setApplicationDate(LocalDateTime.now());
        apply.setApplicantId(dlpUser.getId());//申请人id
        //添加数据
        asMapper.insert(apply);

        //创建副表
        for (String sampleId :dto.getSampleId()) {
            SampleApplyDetailed detailed = new SampleApplyDetailed();
            detailed.setApplyId(apply.getId());
            detailed.setSampleId(sampleId);
            detailed.setStatus(0);//待审核审批
            //数据存储
            detailedMapper.insert(detailed);
            //远程调用修改状态
            //transferFeignService.updateStatus(sampleId,12);//申请中
        }

        return this.getDetail(apply.getId());
    }

    /**
     * 查询单个申请详情
     * @param id
     * @return
     */
    @Override
    public SampleApplyVO getDetail(String id) {

        SampleApplyVO sampleApplyVO = asMapper.getSampleApply(id);//查询单个申请详情

        sampleApplyVO.setStatusCode(sampleApplyVO.getApplicationStatus().getStatus());

        List<ApplySampleVO> sampleVO = detailedMapper.getDetail(id);//详情

        for (ApplySampleVO sample:sampleVO) {
            if(sample.getStatus()==0){
                sample.setDescribeStatus("待审核审批");
            } else if (sample.getStatus()==1) {
                sample.setDescribeStatus("通过");
            }else if (sample.getStatus()==-1) {
                sample.setDescribeStatus("未通过");
            }
        }
        sampleApplyVO.setSampleVO(sampleVO);//设置样本信息

        return sampleApplyVO;
    }

    /**
     * 创建并提交
     * @param dto
     * @param dlpUser
     * @return
     */
    @Override
    public SampleApplyVO createAndSubmit(ApplyDTO dto, DLPUser dlpUser) {

        SampleApply apply = new SampleApply();
        apply.setId(IdWorker.get32UUID().toUpperCase());//id
        apply.setApplyType(dto.getApplyType());//类型
        apply.setApplyQuantity(dto.getSampleId().size());//数量
        if(dto.getApplyType()==1){
            apply.setApplicationStatus(ApplyStatus.FIRST_LEVEL);//待一级审核
        }else {
            apply.setApplicationStatus(ApplyStatus.PENDING_APPROVAL);//待审批
        }
        apply.setReason(dto.getReason());//原因
        apply.setApplicationDate(LocalDateTime.now());
        apply.setApplicantId(dlpUser.getId());//申请人id
        //添加数据
        asMapper.insert(apply);

        //创建副表
        for (String sampleId :dto.getSampleId()) {
            SampleApplyDetailed detailed = new SampleApplyDetailed();
            detailed.setApplyId(apply.getId());
            detailed.setSampleId(sampleId);
            detailed.setStatus(0);//待审核审批
            //数据存储
            detailedMapper.insert(detailed);
            //远程调用修改状态
            transferFeignService.updateStatus(sampleId,12);//申请中
        }



        //消息发送


        return this.getDetail(apply.getId());
    }


    /**
     * 单个提交
     * @param id
     * @return
     */
    @Override
    public SampleApplyVO submitApplyOne(String id) {

        SampleApply apply = asMapper.selectById(id);
        if(apply == null){
            throw new RuntimeException(String.format("当前数据不存在"));
        } else if (apply.getApplicationStatus()!=ApplyStatus.TO_BE_SUBMITTED && apply.getApplicationStatus()!=ApplyStatus.WITHDRAWN) {//外带申请
            throw new RuntimeException(String.format("当前申请不是待提交状态"));
        }

        List<SampleApplyDetailed> detaileds = detailedMapper.selectList(Wrappers.<SampleApplyDetailed>query().eq("apply_id", id));


        //判断当前准备提交申请中样本是否是在别的申请提交了
        for (SampleApplyDetailed detail : detaileds) {
            StatusSampleVO sampleVO =  asMapper.getSampleInfo(detail.getSampleId());
            if(sampleVO.getStatus() == 12){
                throw new RuntimeException(String.format("名称为:"+sampleVO.getName()+"的样本已在别的申请中提交;请勿重复提交"));
            }
        }

        //判断申请类型
        if(apply.getApplyType()==1){//外带
            apply.setApplicationStatus(ApplyStatus.FIRST_LEVEL);
        }else {
            apply.setApplicationStatus(ApplyStatus.PENDING_APPROVAL);
        }
        //修改数据
        asMapper.updateById(apply);

        for (SampleApplyDetailed detail : detaileds) {
            //远程调用修改状态
            transferFeignService.updateStatus(detail.getSampleId(),12);//申请中
        }
        return this.getDetail(id);
    }

    /**
     * 分页查询
     * @param qw
     * @return
     */
    @Override
    public IPage<SampleApplyVO> getApplyPage(Page<SampleApply> page,QueryWrapper<SampleApply> qw) {
        IPage<SampleApplyVO> vo = asMapper.getApplyPage(page, qw);
        List<SampleApplyVO> records = vo.getRecords();

        for (SampleApplyVO record :records) {
            record.setStatusCode(record.getApplicationStatus().getStatus());
        }

        return vo;
    }

    /**
     * 单个撤回
     * @param id
     * @return
     */
    @Override
    public SampleApplyVO withdrawalOne(String id) {
        SampleApply apply = asMapper.selectById(id);
        if(apply == null){
            throw new RuntimeException(String.format("当前数据不存在"));
        } else if (apply.getApplicationStatus()!=ApplyStatus.FIRST_LEVEL && apply.getApplyType()==1) {//外带申请
            throw new RuntimeException(String.format("当前外带申请状态为"+apply.getApplicationStatus().getDescription()+"不可撤回"));
        }else if (apply.getApplicationStatus()!=ApplyStatus.PENDING_APPROVAL && apply.getApplyType()==2) {//外带申请
            throw new RuntimeException(String.format("当前销毁申请状态为"+apply.getApplicationStatus().getDescription()+"不可撤回"));
        }
        //撤回数据
        apply.setApplicationStatus(ApplyStatus.WITHDRAWN);
        //修改数据
        asMapper.updateById(apply);

        List<SampleApplyDetailed> detaileds = detailedMapper.selectList(Wrappers.<SampleApplyDetailed>query().eq("apply_id", id));

        for (SampleApplyDetailed detail : detaileds) {
            //远程调用修改状态
            if(apply.getApplyType()==1){//外带申请为出库状态
                transferFeignService.updateStatus(detail.getSampleId(),1);//出库
            }else {
                transferFeignService.updateStatus(detail.getSampleId(),2);//销毁申请是在仓库里面
            }
            //申请中
        }

        return this.getDetail(id);
    }

    /**
     * 单个删除
     * @param id
     */
    @Override
    @Transactional
    public void deleteOne(String id) {

        SampleApply apply = asMapper.selectById(id);


        if(apply==null){
            throw new RuntimeException(String.format("当前数据不存在"));
        } else if (apply.getApplicationStatus()!=ApplyStatus.WITHDRAWN && apply.getApplicationStatus()!=ApplyStatus.TO_BE_SUBMITTED) {
            throw new RuntimeException(String.format("当前状态不可删除"));
        }
        //删除副表
        QueryWrapper<SampleApplyDetailed> wrapper = new QueryWrapper<>();
        wrapper.eq("apply_id", id);
        detailedMapper.delete(wrapper);
        //删除主表
        asMapper.deleteById(id);

    }

    /**
     * 修改并提交
     * @param dto
     * @param dlpUser
     * @return
     */
    @Override
    public SampleApplyVO updateAndSubmit(ApplyDTO dto, DLPUser dlpUser) {

        SampleApply sampleApply = asMapper.selectById(dto.getId());
        if(sampleApply==null){
            throw new RuntimeException(String.format("当前数据不存在"));
        } else if (sampleApply.getApplicationStatus()!=ApplyStatus.WITHDRAWN && sampleApply.getApplicationStatus()!=ApplyStatus.TO_BE_SUBMITTED) {
            throw new RuntimeException(String.format("当前状态不可修改"));
        }

        //修改主表
        sampleApply.setReason(dto.getReason());//销毁原因
        sampleApply.setApplyQuantity(dto.getSampleId().size());//样本数量
        if(sampleApply.getApplyType()==1){
            sampleApply.setApplicationStatus(ApplyStatus.FIRST_LEVEL);//待一级审核
        }else {
            sampleApply.setApplicationStatus(ApplyStatus.PENDING_APPROVAL);//待审批
        }
        sampleApply.setApplicationDate(LocalDateTime.now());
        asMapper.updateById(sampleApply);

        QueryWrapper<SampleApplyDetailed> wrapper = new QueryWrapper<>();
        wrapper.eq("apply_id", sampleApply.getId());

        //样本还原状态
        List<SampleApplyDetailed> list = detailedMapper.selectList(wrapper);
        for (SampleApplyDetailed detailed:list) {
            if(sampleApply.getApplyType()==1){//外带申请
                transferFeignService.updateStatus(detailed.getSampleId(),1);
            }else {//销毁
                transferFeignService.updateStatus(detailed.getSampleId(),2);
            }
        }
        //删除副表

        detailedMapper.delete(wrapper);

        //创建副表
        for (String sampleId :dto.getSampleId()) {
            SampleApplyDetailed detailed = new SampleApplyDetailed();
            detailed.setApplyId(sampleApply.getId());
            detailed.setSampleId(sampleId);
            detailed.setStatus(0);//待审核审批
            //数据存储
            detailedMapper.insert(detailed);
            //远程调用修改状态
            transferFeignService.updateStatus(sampleId,12);//申请中
        }

        return this.getDetail(sampleApply.getId());
    }


    /**
     * 修改并保存
     * @param dto
     * @param dlpUser
     * @return
     */
    public SampleApplyVO updateAndSave(ApplyDTO dto, DLPUser dlpUser) {

        SampleApply sampleApply = asMapper.selectById(dto.getId());
        if(sampleApply==null){
            throw new RuntimeException(String.format("当前数据不存在"));
        } else if (sampleApply.getApplicationStatus()!=ApplyStatus.WITHDRAWN && sampleApply.getApplicationStatus()!=ApplyStatus.TO_BE_SUBMITTED) {
            throw new RuntimeException(String.format("当前状态不可修改"));
        }

            //修改主表
        sampleApply.setReason(dto.getReason());//销毁原因
        sampleApply.setApplyQuantity(dto.getSampleId().size());//样本数量

        sampleApply.setApplicationStatus(ApplyStatus.TO_BE_SUBMITTED);//

        sampleApply.setApplicationDate(LocalDateTime.now());
        asMapper.updateById(sampleApply);


        QueryWrapper<SampleApplyDetailed> wrapper = new QueryWrapper<>();
        wrapper.eq("apply_id", sampleApply.getId());

        //样本还原状态
        List<SampleApplyDetailed> list = detailedMapper.selectList(wrapper);
        for (SampleApplyDetailed detailed:list) {
            if(sampleApply.getApplyType()==1){//外带申请
                transferFeignService.updateStatus(detailed.getSampleId(),1);
            }else {//销毁
                transferFeignService.updateStatus(detailed.getSampleId(),2);
            }
        }
        //删除副表

        detailedMapper.delete(wrapper);

        //创建副表
        for (String sampleId :dto.getSampleId()) {
            SampleApplyDetailed detailed = new SampleApplyDetailed();
            detailed.setApplyId(sampleApply.getId());
            detailed.setSampleId(sampleId);
            detailed.setStatus(0);//待审核审批
            //数据存储
            detailedMapper.insert(detailed);
        }

        return this.getDetail(sampleApply.getId());
    }
}
