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

import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
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.AuditAndApproveDTO;
import digital.laboratory.platform.reagent.dto.PurchasingPlanDTO;
import digital.laboratory.platform.reagent.entity.*;
import digital.laboratory.platform.reagent.mapper.PurchasingPlanMapper;
import digital.laboratory.platform.reagent.service.*;
import digital.laboratory.platform.reagent.vo.ProcurementContentVO;
import digital.laboratory.platform.reagent.vo.PurchasingPlanVO;
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 PurchasingPlanServiceImpl extends ServiceImpl<PurchasingPlanMapper, PurchasingPlan> implements PurchasingPlanService {

    @Autowired
    private PurchasingPlanService purchasingPlanService;
    @Autowired
    private ProcurementContentService procurementContentService;

    @Autowired
    private DetailsOfCentralizedService detailsOfCentralizedService;

    @Autowired
    private ReagentConsumablesService reagentConsumablesService;

    @Autowired
    private CentralizedRequestService requestService;
    @Override//分页
    public IPage<PurchasingPlanVO> getPurchasingPlanVOPage(IPage<PurchasingPlan> page, QueryWrapper<PurchasingPlan> qw) {
        IPage<PurchasingPlanVO> purchasingPlanVOPage = baseMapper.getPurchasingPlanVOPage(page, qw);
        return purchasingPlanVOPage;
    }

    @Override//列表
    public List<PurchasingPlanVO> getPurchasingPlanVOList(QueryWrapper<PurchasingPlan> qw) {
        return baseMapper.getPurchasingPlanVOList(qw);
    }

    @Override//通过ID查询
    public PurchasingPlanVO getPurchasingPlanVO(String purchasingPlanId) {

        PurchasingPlanVO purchasingPlanVO = baseMapper.getPurchasingPlanVO(purchasingPlanId);

        if (purchasingPlanVO == null) {

            throw new RuntimeException(String.format("信息不存在"));
        }

        List<ProcurementContentVO> procurementContentVOList = procurementContentService.getProcurementContentVOList(purchasingPlanId);

        purchasingPlanVO.setProcurementContentVOList(procurementContentVOList);

        return purchasingPlanVO;
    }

    @Transactional
    @Override//创建计划
    public PurchasingPlanVO addById(List<PurchasingPlanDTO> purchasingPlanDTOList, DLPUser user) {

        PurchasingPlan purchasingPlan = new PurchasingPlan();

        purchasingPlan.setPurchasingPlanId(IdWorker.get32UUID().toUpperCase());

        purchasingPlan.setCreateId(user.getId());

        purchasingPlan.setStatus(0);

        purchasingPlan.setCreateName(user.getName());

        purchasingPlan.setOrgName(user.getOrgName());

        List<ProcurementContent> list = new ArrayList<>();//需要整合的集合

        boolean flag = true;

        for (PurchasingPlanDTO purchasingPlanDTO : purchasingPlanDTOList) {
            //将列入计划的集中采购申请状态变为2
            String detailsOfCentralizedId = purchasingPlanDTO.getDetailsOfCentralizedId();

            DetailsOfCentralized byId2 = detailsOfCentralizedService.getById(detailsOfCentralizedId);

            CentralizedRequest byId3 = requestService.getById(byId2.getCentralizedRequestId());

            byId3.setStatus(2);

            requestService.updateById(byId3);

            flag = true;

//            if (!(purchasingPlanDTO.getUnitPrice() > 0 &
//                    purchasingPlanDTO.getUnitPrice() < 1000000 &
//                    purchasingPlanDTO.getQuantity() > 0 &
//                    purchasingPlanDTO.getQuantity() < 1000 &
//                    purchasingPlanDTO.getReagentConsumableId() != null)) {
//                throw new RuntimeException(String.format("您输入的值有误，请重新输入"));
//            }

            if (list.size() != 0) {

                for (int i = 0; i < list.size(); i++) {

                    if (list.get(i).getReagentConsumableId().equals(purchasingPlanDTO.getReagentConsumableId())) {

                        ReagentConsumables byId1 = reagentConsumablesService.getById(list.get(i).getReagentConsumableId());

                        list.get(i).setUnitPrice(byId1.getUnitPrice());

                        list.get(i).setQuantityPurchased(list.get(i).getQuantityPurchased()+purchasingPlanDTO.getNumberOfApplications());

                        list.get(i).setSubtotal(list.get(i).getNumberOfApplications()*list.get(i).getUnitPrice());

                        DetailsOfCentralized byId = detailsOfCentralizedService.getById(purchasingPlanDTO.getDetailsOfCentralizedId());

                        byId.setProcurementContentId(list.get(i).getProcurementContentId());

                        detailsOfCentralizedService.updateById(byId);

                        flag = false;

                    }
                }
                if (flag) {
                    ProcurementContent procurementContent = new ProcurementContent();

                    BeanUtils.copyProperties(purchasingPlanDTO, procurementContent);

                    procurementContent.setProcurementContentId(IdWorker.get32UUID().toUpperCase());

                    procurementContent.setPurchasingPlanId(purchasingPlan.getPurchasingPlanId());

                    DetailsOfCentralized byId = detailsOfCentralizedService.getById(purchasingPlanDTO.getDetailsOfCentralizedId());

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

                    procurementContent.setUnitPrice(reagentConsumables.getUnitPrice());

                    byId.setProcurementContentId(procurementContent.getProcurementContentId());

                    detailsOfCentralizedService.updateById(byId);

                    list.add(procurementContent);

                }

            } else {
                ProcurementContent procurementContent = new ProcurementContent();

                BeanUtils.copyProperties(purchasingPlanDTO, procurementContent);

                DetailsOfCentralized byId = detailsOfCentralizedService.getById(purchasingPlanDTO.getDetailsOfCentralizedId());

                procurementContent.setProcurementContentId(IdWorker.get32UUID().toUpperCase());

                procurementContent.setPurchasingPlanId(purchasingPlan.getPurchasingPlanId());

                procurementContent.setQuantityPurchased(procurementContent.getNumberOfApplications());

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

                procurementContent.setUnitPrice(reagentConsumables.getUnitPrice());

                byId.setProcurementContentId(procurementContent.getProcurementContentId());

                detailsOfCentralizedService.updateById(byId);

                list.add(procurementContent);
            }
        }
        double x = 0;
        for (
                ProcurementContent procurementContent : list) {

                x = x + procurementContent.getNumberOfApplications() * procurementContent.getUnitPrice();

        }

        purchasingPlan.setAppropriationBudget(x);
        if (purchasingPlanService.save(purchasingPlan) & procurementContentService.saveBatch(list)) {

            PurchasingPlanVO purchasingPlanVO = purchasingPlanService.getPurchasingPlanVO(purchasingPlan.getPurchasingPlanId());
            return purchasingPlanVO;
        } else throw new RuntimeException(String.format("保存失败"));
    }

    @Override
    public ProcurementContent addContent(PurchasingPlanDTO purchasingPlanDTO) {

        ProcurementContent procurementContent = new ProcurementContent();

        BeanUtils.copyProperties(purchasingPlanDTO, procurementContent);

        if (procurementContentService.save(procurementContent)) {
            return procurementContent;
        } else {
            return null;
        }
    }

    @Override
    @Transactional
    public ProcurementContent editById(PurchasingPlanDTO purchasingPlanDTO) {

        ProcurementContent byId = procurementContentService.getById(purchasingPlanDTO.getProcurementContentId());

        BeanUtils.copyProperties(purchasingPlanDTO, byId);

        LambdaQueryWrapper<DetailsOfCentralized> detailsOfCentralizedLambdaQueryWrapper = new LambdaQueryWrapper<>();

        detailsOfCentralizedLambdaQueryWrapper.eq(DetailsOfCentralized::getDetailsOfCentralizedId, byId.getDetailsOfCentralizedId());

        DetailsOfCentralized detailsOfCentralized = detailsOfCentralizedService.getOne(detailsOfCentralizedLambdaQueryWrapper);

        detailsOfCentralized.setQuantityPurchased(byId.getQuantityPurchased());

        procurementContentService.updateById(byId);

        detailsOfCentralizedService.updateById(detailsOfCentralized);

        calculatedAmount(byId.getPurchasingPlanId());

        return byId;

    }


    @Override//修改整合的采购计划明细中的申请明细

    public ProcurementContent editDetails(PurchasingPlanDTO purchasingPlanDTO) {

        ProcurementContent byId = procurementContentService.getById(purchasingPlanDTO.getProcurementContentId());

        DetailsOfCentralized detailsOfCentralized = detailsOfCentralizedService.getById(purchasingPlanDTO.getDetailsOfCentralizedId());

        if (detailsOfCentralized.getQuantityPurchased() == null) {

            byId.setQuantityPurchased(byId.getQuantityPurchased() - detailsOfCentralized.getNumberOfApplications() + purchasingPlanDTO.getQuantityPurchased());

        } else {

            byId.setQuantityPurchased(byId.getQuantityPurchased() - detailsOfCentralized.getQuantityPurchased() + purchasingPlanDTO.getQuantityPurchased());
        }
        detailsOfCentralized.setQuantityPurchased(purchasingPlanDTO.getQuantityPurchased());

        if (procurementContentService.updateById(byId) && detailsOfCentralizedService.updateById(detailsOfCentralized)) {

            calculatedAmount(byId.getPurchasingPlanId());

            return byId;

        } else throw new RuntimeException(String.format("修改失败"));
    }


    @Override
    @Transactional
    public Boolean delContentById(String procurementContentId) {

        ProcurementContent byId = procurementContentService.getById(procurementContentId);

        LambdaQueryWrapper<DetailsOfCentralized> detailsOfCentralizedLambdaQueryWrapper = new LambdaQueryWrapper<>();

        detailsOfCentralizedLambdaQueryWrapper.eq(DetailsOfCentralized::getProcurementContentId, procurementContentId);

        List<DetailsOfCentralized> list = detailsOfCentralizedService.list(detailsOfCentralizedLambdaQueryWrapper);

        for (DetailsOfCentralized detailsOfCentralized : list) {

            detailsOfCentralized.setQuantityPurchased(0);
        }


        if (purchasingPlanService.getById(byId.getPurchasingPlanId()).getStatus() == 0
                && detailsOfCentralizedService.updateBatchById(list) && procurementContentService.removeById(procurementContentId)) {

            calculatedAmount(byId.getPurchasingPlanId());

            return true;
        } else {
            return null;
        }
    }

    @Override
    public ProcurementContent replacementById(PurchasingPlanDTO purchasingPlanDTO) {

        String replacementReagentConsumableId = purchasingPlanDTO.getReplacementReagentConsumableId();

        ProcurementContent byId = procurementContentService.getById(purchasingPlanDTO.getProcurementContentId());
        //将换货信息补充至采购计划明细
        byId.setReplacementReagentConsumableId(replacementReagentConsumableId);
        byId.setReplacementQuantity(purchasingPlanDTO.getReplacementQuantity());
        byId.setReplacementPrice(purchasingPlanDTO.getReplacementPrice());

        LambdaQueryWrapper<DetailsOfCentralized> detailsOfCentralizedLambdaQueryWrapper = new LambdaQueryWrapper<>();

        detailsOfCentralizedLambdaQueryWrapper.eq(DetailsOfCentralized::getDetailsOfCentralizedId, byId.getDetailsOfCentralizedId());

        DetailsOfCentralized detailsOfCentralized = detailsOfCentralizedService.getOne(detailsOfCentralizedLambdaQueryWrapper);
        //将换货信息补充至集中采购申请明细
        detailsOfCentralized.setReplacementReagentConsumableId(replacementReagentConsumableId);
        detailsOfCentralized.setReplacementQuantity(purchasingPlanDTO.getReplacementQuantity());

        if (procurementContentService.updateById(byId) && detailsOfCentralizedService.updateById(detailsOfCentralized)) {

            return byId;

        } else throw new RuntimeException(String.format("换货失败"));


    }

    @Override
    @Transactional
    public PurchasingPlan commitById(String purchasingPlanId ) {

        PurchasingPlan byId = purchasingPlanService.getById(purchasingPlanId);

        byId.setStatus(1);

        if (purchasingPlanService.updateById(byId)) {
                calculatedAmount(byId.getPurchasingPlanId());
                return byId;
            } else throw new RuntimeException(String.format("提交失败"));

        }


    @Override
    public PurchasingPlan auditById(AuditAndApproveDTO auditAndApproveDto, DLPUser dlpUser) {

        PurchasingPlan purchasingPlan = purchasingPlanService.getById(auditAndApproveDto.getUuId());

        if (purchasingPlan.getStatus() != 1) {
            throw new RuntimeException(String.format("当前状态不可审核"));
        }
        purchasingPlan.setAuditResultOfPrimary(auditAndApproveDto.getAuditResult());

        purchasingPlan.setAuditOpinionOfPrimary(auditAndApproveDto.getAuditOpinion());

        purchasingPlan.setAuditTimeOfPrimary(LocalDateTime.now());

        purchasingPlan.setPrimaryAuditorId(dlpUser.getId());

        purchasingPlan.setStatus(2);

        if (purchasingPlanService.updateById(purchasingPlan)) {
            return purchasingPlan;
        } else {
            return null;
        }
    }

    @Override
    public PurchasingPlan approveById(AuditAndApproveDTO auditAndApproveDto, DLPUser dlpUser) {

        PurchasingPlan purchasingPlan = purchasingPlanService.getById(auditAndApproveDto.getUuId());

        if (purchasingPlan.getStatus() != 2) {
            throw new RuntimeException(String.format("当前状态不可审批"));
        }
        purchasingPlan.setApprovalResult(auditAndApproveDto.getApproveResult());

        purchasingPlan.setApprovalOpinion(auditAndApproveDto.getApproveOpinion());

        purchasingPlan.setApprovalTime(LocalDateTime.now());

        purchasingPlan.setStatus(3);

        purchasingPlan.setApproverId(dlpUser.getId());

        if (purchasingPlanService.updateById(purchasingPlan)) {
            return purchasingPlan;
        } else {
            return null;
        }
    }

    @Override
    public PurchasingPlan releaseById(String purchasingPlanId) {

        PurchasingPlan byId = purchasingPlanService.getById(purchasingPlanId);

        if (byId.getStatus() != 3) {
            throw new RuntimeException(String.format("当前状态无法发布"));
        }
        byId.setStatus(4);

        if (purchasingPlanService.updateById(byId)) {
            return byId;
        } else {
            return null;
        }
    }

    public PurchasingPlan calculatedAmount(String purchasingPlanId) {

        PurchasingPlan purchasingPlan = purchasingPlanService.getById(purchasingPlanId);

        LambdaQueryWrapper<ProcurementContent> procurementContentLambdaQueryWrapper = new LambdaQueryWrapper<>();

        procurementContentLambdaQueryWrapper.eq(ProcurementContent::getPurchasingPlanId, purchasingPlan.getPurchasingPlanId());

        List<ProcurementContent> list = procurementContentService.list(procurementContentLambdaQueryWrapper);

        double x = 0;
        for (
                ProcurementContent procurementContent : list) {

            x = x + procurementContent.getQuantityPurchased() * procurementContent.getUnitPrice();
        }
        purchasingPlan.setAppropriationBudget(x);

        if (purchasingPlanService.updateById(purchasingPlan)) {
            return purchasingPlan;
        } else throw new RuntimeException(String.format("计算失败"));
    }
}
