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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.extension.service.impl.ServiceImpl;
import digital.laboratory.platform.common.mybatis.security.service.DLPUser;
import digital.laboratory.platform.reagent.dto.ApplicationForUseDTO;
import digital.laboratory.platform.reagent.dto.ComplianceCheckDTO;
import digital.laboratory.platform.reagent.entity.*;
import digital.laboratory.platform.reagent.mapper.ApplicationForUseMapper;
import digital.laboratory.platform.reagent.service.*;
import digital.laboratory.platform.reagent.vo.ApplicationForUseVO;
import digital.laboratory.platform.reagent.vo.ReagentConsumablesSetVO;
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 (试剂耗材领用申请表) 服务实现类
 */
@SuppressWarnings("all")
@Service
public class ApplicationForUseServiceImpl extends ServiceImpl<ApplicationForUseMapper, ApplicationForUse> implements ApplicationForUseService {

    @Autowired
    private ReagentConsumablesSetService reagentConsumablesSetService;

    @Autowired
    private ApplicationForUseService applicationForUseService;

    @Autowired
    private ReagentConsumablesService reagentConsumablesService;

    @Autowired
    private ReferenceMaterialService referenceMaterialService;

    @Autowired
    private StandardMaterialApplicationService standardMaterialApplicationService;

    @Autowired
    private ComplianceCheckService complianceCheckService;

    @Autowired
    private DeliveryRegistrationFormService deliveryRegistrationFormService;

    @Autowired
    private ReagentConsumableInventoryService reagentConsumableInventoryService;

    @Override//通过ID查询领用申请表
    public ApplicationForUseVO getApplicationForUseVO(String applicationForUseId) {

        ApplicationForUseVO applicationForUseVO = baseMapper.getApplicationForUseVO(applicationForUseId);

        List<ReagentConsumablesSetVO> list = reagentConsumablesSetService.getList(applicationForUseId);

        applicationForUseVO.setReagentConsumablesSetVOList(list);

        return applicationForUseVO;

    }

    @Override//分页查询
    public IPage<ApplicationForUseVO> getApplicationForUseVOPage(IPage<ApplicationForUse> page, QueryWrapper<ApplicationForUse> qw) {
        return baseMapper.getApplicationForUseVOPage(page, qw);
    }

    @Override//列表查询
    public List<ApplicationForUseVO> getApplicationForUseVOList(QueryWrapper<ApplicationForUse> qw) {
        return baseMapper.getApplicationForUseVOList(qw);
    }

    @Transactional
    @Override//创建领用申请表(试剂耗材领用、标准物质领用、标准溶液领用)
    public ApplicationForUse addApplication(List<ApplicationForUseDTO> applicationForUseDTOList, DLPUser dlpUser) {
        //录入领用申请表
        ApplicationForUse applicationForUse = new ApplicationForUse();

        applicationForUse.setApplicationForUseId(IdWorker.get32UUID().toUpperCase());

        applicationForUse.setStatus(0);

        applicationForUse.setRecipientId(dlpUser.getId());

        LambdaQueryWrapper<ReagentConsumableInventory> reagentConsumableInventoryLambdaQueryWrapper = new LambdaQueryWrapper<>();

        List<ReagentConsumablesSet> reagentConsumablesSets = new ArrayList<>();

        LambdaQueryWrapper<ReferenceMaterial> reagentConsumableLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //录入领用申请内容
        for (ApplicationForUseDTO applicationForUseDTO : applicationForUseDTOList) {
            //生成领用登记表集合
            ReagentConsumablesSet reagentConsumablesSet = new ReagentConsumablesSet();

            BeanUtils.copyProperties(applicationForUseDTO, reagentConsumablesSet);

            reagentConsumablesSet.setReagentConsumablesSetId(IdWorker.get32UUID().toUpperCase());

            reagentConsumablesSet.setApplicationForUseId(applicationForUse.getApplicationForUseId());

            reagentConsumablesSets.add(reagentConsumablesSet);

            reagentConsumableInventoryLambdaQueryWrapper.eq(ReagentConsumableInventory::getReagentConsumableId,reagentConsumablesSet.getReagentConsumableId());


            Integer totalQuantity = reagentConsumableInventoryService.getOne(reagentConsumableInventoryLambdaQueryWrapper).getTotalQuantity();
            if (reagentConsumablesSet.getQuantity()>totalQuantity){

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

        }
        if (applicationForUseService.save(applicationForUse) & reagentConsumablesSetService.saveBatch(reagentConsumablesSets)
        ) {
            return applicationForUse;
        } else return null;
    }

    @Transactional
    @Override//修改领用申请表
    public ApplicationForUse editApplication(List<ApplicationForUseDTO> applicationForUseDTOList, DLPUser dlpUser) {

        ApplicationForUse applicationForUse = applicationForUseService.getById(applicationForUseDTOList.get(0).getApplicationForUseId());

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

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

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

        //删除领用申请明细
        reagentConsumablesSetService.removeBatchByIds(list);

        ArrayList<ReagentConsumablesSet> reagentConsumablesSets = new ArrayList<>();

        LambdaQueryWrapper<ReferenceMaterial> reagentConsumableLambdaQueryWrapper = new LambdaQueryWrapper<>();
        //录入领用申请内容
        for (ApplicationForUseDTO applicationForUseDTO : applicationForUseDTOList) {
            //生成领用登记表集合
            ReagentConsumablesSet reagentConsumablesSet = new ReagentConsumablesSet();

            BeanUtils.copyProperties(applicationForUseDTO, reagentConsumablesSet);

            reagentConsumablesSet.setReagentConsumablesSetId(IdWorker.get32UUID().toUpperCase());

            reagentConsumablesSet.setApplicationForUseId(applicationForUse.getApplicationForUseId());

            reagentConsumablesSets.add(reagentConsumablesSet);

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


        }
        if (applicationForUseService.updateById(applicationForUse) & reagentConsumablesSetService.saveBatch(reagentConsumablesSets)
        ) {
            return applicationForUse;
        } else return null;
    }

    @Override//提交领用申请记录

    public ApplicationForUse commitApplication(List<ApplicationForUseDTO> applicationForUseDTOList, DLPUser dlpUser) {

        if (applicationForUseDTOList.get(0).getApplicationForUseId() == null) {

            ApplicationForUse applicationForUse = applicationForUseService.addApplication(applicationForUseDTOList, dlpUser);

            applicationForUse.setStatus(1);

            String random = "" + Math.random();
            //领取码
            applicationForUse.setClaimCode(random.substring(random.length() - 4));

            applicationForUse.setDateOfCollection(LocalDateTime.now());

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

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

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

            LambdaQueryWrapper<ReagentConsumables> reagentConsumablesLambdaQueryWrapper = new LambdaQueryWrapper<>();

            applicationForUseService.updateById(applicationForUse);

            deliveryRegistrationFormService.addFrom(applicationForUse.getApplicationForUseId());

            return applicationForUse;
        } else {
            LambdaQueryWrapper<ApplicationForUse> applicationForUseLambdaQueryWrapper = new LambdaQueryWrapper<>();

            applicationForUseLambdaQueryWrapper.eq(ApplicationForUse::getApplicationForUseId, applicationForUseDTOList.get(0).getApplicationForUseId());

            ApplicationForUse applicationForUse = applicationForUseService.getOne(applicationForUseLambdaQueryWrapper);

            applicationForUse.setStatus(1);

            applicationForUse.setDateOfCollection(LocalDateTime.now());

            String random = "" + Math.random();

            applicationForUse.setClaimCode(random.substring(random.length() - 4));

            applicationForUseService.updateById(applicationForUse);

            deliveryRegistrationFormService.addFrom(applicationForUse.getApplicationForUseId());

            return applicationForUse;
        }
    }

    @Override//通过ID删除领用申请表（标准物质领用/归还登记表）
    public Boolean delApplication(String applicationForUseId) {

        ApplicationForUse applicationForUse = applicationForUseService.getById(applicationForUseId);

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

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

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

        LambdaQueryWrapper<StandardMaterialApplication> standardMaterialApplicationLambdaQueryWrapper = new LambdaQueryWrapper<>();

        standardMaterialApplicationLambdaQueryWrapper.eq(StandardMaterialApplication::getApplicationForUseId, applicationForUse.getApplicationForUseId());

        List<StandardMaterialApplication> list1 = standardMaterialApplicationService.list(standardMaterialApplicationLambdaQueryWrapper);

        return reagentConsumablesSetService.removeBatchByIds(list) & standardMaterialApplicationService.removeBatchByIds(list1) & applicationForUseService.removeById(applicationForUse);

    }
}
