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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.reagent.dto.ComplianceCheckDTO;
import digital.laboratory.platform.reagent.dto.OutgoingContentsDTO;
import digital.laboratory.platform.reagent.entity.*;
import digital.laboratory.platform.reagent.mapper.DeliveryRegistrationFormMapper;
import digital.laboratory.platform.reagent.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * (试剂耗材出库登记表)服务实现类
 *
 * @author Zhang Xiaolong created at  2023-03-10
 * @describe (试剂耗材出库登记表) 服务实现类
 */
@Service
public class DeliveryRegistrationFormServiceImpl extends ServiceImpl<DeliveryRegistrationFormMapper, DeliveryRegistrationForm> implements DeliveryRegistrationFormService {

    @Autowired
    private ApplicationForUseService applicationForUseService;

    @Autowired
    private ReagentConsumablesSetService reagentConsumablesSetService;

    @Autowired
    private ReagentConsumablesService reagentConsumablesService;

    @Autowired
    private OutgoingContentsService outgoingContentsService;

    @Autowired
    private DeliveryRegistrationFormService deliveryRegistrationFormService;

    @Autowired
 private ComplianceCheckService complianceCheckService;

    @Autowired
    private StandardMaterialApplicationService standardMaterialApplicationService;

    @Autowired
    private RequisitionRecordService requisitionRecordService;

    @Autowired
    private ReagentConsumableInventoryService reagentConsumableInventoryService;

    @Override
    @Transactional//创建出库任务
    public DeliveryRegistrationForm addFrom(String applicationForUseId) {

        ApplicationForUse byId = applicationForUseService.getById(applicationForUseId);

        DeliveryRegistrationForm deliveryRegistrationForm = new DeliveryRegistrationForm();

        deliveryRegistrationForm.setDeliveryRegistrationFormId(IdWorker.get32UUID().toUpperCase());
        deliveryRegistrationForm.setOutgoingApplicantId(byId.getRecipientId());

        byId.setDeliveryRegistrationFormId(deliveryRegistrationForm.getDeliveryRegistrationFormId());

        LambdaQueryWrapper<ReagentConsumablesSet> reagentConsumablesSetLambdaQueryWrapper = new LambdaQueryWrapper<>();

        reagentConsumablesSetLambdaQueryWrapper.eq(ReagentConsumablesSet::getApplicationForUseId, byId.getApplicationForUseId());

        List<ReagentConsumablesSet> list = reagentConsumablesSetService.list(reagentConsumablesSetLambdaQueryWrapper);

        List<OutgoingContents> outgoingContentsList = new ArrayList<>();

        for (ReagentConsumablesSet reagentConsumablesSet : list) {

            OutgoingContents outgoingContents = new OutgoingContents();

            ReagentConsumables one = reagentConsumablesService.getById(reagentConsumablesSet.getReagentConsumableId());

            outgoingContents.setOutgoingContentsId(IdWorker.get32UUID().toUpperCase());
            outgoingContents.setDeliveryRegistrationFormId(deliveryRegistrationForm.getDeliveryRegistrationFormId());
            outgoingContents.setQuantity(reagentConsumablesSet.getQuantity());
            outgoingContents.setRemarks(reagentConsumablesSet.getRemarks());
            outgoingContents.setOutboundUse(reagentConsumablesSet.getPurpose());
            outgoingContents.setReagentConsumableId(reagentConsumablesSet.getReagentConsumableId());
            outgoingContents.setReagentConsumableType(one.getCategory());

            outgoingContentsList.add(outgoingContents);

        }
        if (deliveryRegistrationFormService.save(deliveryRegistrationForm) && outgoingContentsService.saveBatch(outgoingContentsList)&
        applicationForUseService.updateById(byId)) {

            return deliveryRegistrationForm;
        } else throw new RuntimeException(String.format("创建出库任务失败"));
    }

    @Override//提交出库登记表
    @Transactional
    public DeliveryRegistrationForm commitForm(List<OutgoingContentsDTO> outgoingContentsDTOS, DLPUser dlpUser) {
        //得到出库登记表
        DeliveryRegistrationForm byId = deliveryRegistrationFormService.getById(outgoingContentsDTOS.get(0).getDeliveryRegistrationFormId());

        byId.setDepositorId(dlpUser.getId());

        LambdaQueryWrapper<OutgoingContents> outgoingContentsLambdaQueryWrapper = new LambdaQueryWrapper<>();

        outgoingContentsLambdaQueryWrapper.eq(OutgoingContents::getDeliveryRegistrationFormId, byId.getDeliveryRegistrationFormId());
        //删除修改之前的内容(防止领用为X种，但实际出库只有n种，导致领用出库不一致)
        outgoingContentsService.removeBatchByIds(outgoingContentsService.list(outgoingContentsLambdaQueryWrapper));

        List<StandardMaterialApplication> standardMaterialApplications = new ArrayList<>();

        List<OutgoingContents> outgoingContentsList= new ArrayList<>();

        LambdaQueryWrapper<ApplicationForUse> applicationForUseLambdaQueryWrapper = new LambdaQueryWrapper<>();

        applicationForUseLambdaQueryWrapper.eq(ApplicationForUse::getDeliveryRegistrationFormId,byId.getDeliveryRegistrationFormId());
        //查询领用申请表
        ApplicationForUse one = applicationForUseService.getOne(applicationForUseLambdaQueryWrapper);

        for (OutgoingContentsDTO outgoingContentsDTO : outgoingContentsDTOS) {

            OutgoingContents outgoingContents = new OutgoingContents();

            BeanUtils.copyProperties(outgoingContentsDTO, outgoingContents);

            outgoingContents.setOutgoingContentsId(IdWorker.get32UUID().toUpperCase());

            ReagentConsumables reagentConsumables = reagentConsumablesService.getById(outgoingContents.getReagentConsumableId());

            outgoingContents.setReagentConsumableType(reagentConsumables.getCategory());

            outgoingContents.setDeliveryRegistrationFormId(byId.getDeliveryRegistrationFormId());

            if (reagentConsumables.getCategory().equals("标准物质") | reagentConsumables.getCategory().equals("标准储备溶液")) {
                //生成标准物质领用/归还登记表
                StandardMaterialApplication standardMaterialApplication = new StandardMaterialApplication();

                standardMaterialApplication.setStandardMaterialApplicationId(IdWorker.get32UUID().toUpperCase());

                standardMaterialApplication.setPurpose(outgoingContents.getOutboundUse());

                standardMaterialApplication.setDateOfClaim(LocalDateTime.now());

                standardMaterialApplication.setRecipientId(one.getRecipientId());

                standardMaterialApplication.setReferenceMaterialNumber(outgoingContentsDTO.getNumber());

                standardMaterialApplication.setReferenceSubstanceId(reagentConsumables.getReagentConsumableId());

                standardMaterialApplication.setSpecification(reagentConsumables.getSpecificationAndModel());

                standardMaterialApplication.setRequisitionedQuantity(outgoingContents.getQuantity());

                standardMaterialApplication.setSpecification(reagentConsumables.getSpecificationAndModel());

                standardMaterialApplication.setApplicationForUseId(one.getApplicationForUseId());

                standardMaterialApplications.add(standardMaterialApplication);

                standardMaterialApplication.setStatus(0);
            } else {
                RequisitionRecord requisitionRecord = requisitionRecordService.addRecord(outgoingContents);

                requisitionRecord.setDateOfClaim(LocalDateTime.now());
                requisitionRecord.setRecipientId(one.getRecipientId());

                requisitionRecordService.updateById(requisitionRecord);
            }

            if (outgoingContents.getOutboundUse() == 0) {
                ComplianceCheckDTO complianceCheckDTO = new ComplianceCheckDTO();
                complianceCheckDTO.setBrand(reagentConsumables.getBrand());
                complianceCheckDTO.setReagentConsumableId(reagentConsumables.getReagentConsumableId());
                complianceCheckDTO.setSpecificationAndModel(reagentConsumables.getSpecificationAndModel());
                complianceCheckDTO.setComplianceCheckId(IdWorker.get32UUID().toUpperCase());
                complianceCheckDTO.setReagentConsumableNumber(outgoingContentsDTO.getNumber());
                complianceCheckService.addCheck(complianceCheckDTO, dlpUser);
            }
            ReagentConsumableInventory reagentConsumableInventory = reagentConsumableInventoryService.reduceById(outgoingContents.getReagentConsumableId(), outgoingContents.getQuantity());

            if (reagentConsumableInventory.getTotalQuantity()<0){

                throw new RuntimeException(String.format("领用数量不能超过库存量"));
            }

            outgoingContentsList.add(outgoingContents);

        }
        if (outgoingContentsService.saveBatch(outgoingContentsList)&&standardMaterialApplicationService.saveBatch(standardMaterialApplications)){
            return byId;
        }else throw new RuntimeException(String.format("提交失败"));
    }
}
