package com.patzn.lims.consume.service.impl;

import com.patzn.cloud.commons.toolkit.BigDecimalUtils;
import com.patzn.lims.consume.entity.LmsChemical;
import com.patzn.lims.consume.entity.LmsChemicalClassify;
import com.patzn.lims.consume.entity.LmsChemicalRelClassify;
import com.patzn.lims.consume.mapper.LmsChemicalClassifyMapper;
import com.patzn.lims.consume.service.ILmsChemicalClassifyService;
import com.patzn.lims.consume.service.ILmsChemicalRelClassifyService;
import com.patzn.lims.consume.service.ILmsChemicalService;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.core.web.LoginHelper;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 试验耗材归类表 服务实现类
 * </p>
 *
 * @author wwd
 * @since 2020-03-25
 */
@Service
public class LmsChemicalClassifyServiceImpl extends BaseServiceImpl<LmsChemicalClassifyMapper, LmsChemicalClassify> implements ILmsChemicalClassifyService {

    @Autowired
    private ILmsChemicalService lmsChemicalService;
    @Autowired
    private ILmsChemicalRelClassifyService lmsChemicalRelClassifyService;

    @Override
    public Page<LmsChemicalClassify> page(Page<LmsChemicalClassify> page, LmsChemicalClassify lmsChemicalClassify) {
        QueryWrapper<LmsChemicalClassify> wrapper = Wrappers.<LmsChemicalClassify>query(lmsChemicalClassify);
        return this.page(page, wrapper);
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveRelChemical(Long classifyId, List<Long> chemicalIds) {
        // 检查是否允许归类
        LmsChemicalClassify chemicalClassify = super.getById(classifyId);
        if (StringUtils.isEmpty(chemicalClassify.getUnit())) {
            PtAssert.fail("该耗材归类单位不存在，请先设置。");
        }
        List<LmsChemical> chemicalList = lmsChemicalService.listByIdList(chemicalIds);
        BigDecimal tempStock = BigDecimal.ZERO;
        if (CollectionUtils.isNotEmpty(chemicalList)) {
            for (LmsChemical chemical : chemicalList) {
                if (!chemicalClassify.getUnit().equals(chemical.getExunit())) {
                    PtAssert.fail("选择耗材转换库存单位与该归类不一致，请重新选择。");
                }
                if (null != chemical.getExstock()) {
                    tempStock = BigDecimalUtils.add(tempStock, chemical.getExstock());
                }
            }
        }
        // 1、设置耗材已归类
        if (!lmsChemicalService.saveClassified(chemicalIds)) {
            PtAssert.fail("归类【" + classifyId + "】不存在或者设置耗材归类失败，请联系管理员！");
        }
        // 2、更新归类库存量
        LmsChemicalClassify cc = new LmsChemicalClassify();
        cc.setId(classifyId);
        cc.setUnit(chemicalClassify.getUnit());
        cc.setStock(BigDecimalUtils.add(tempStock, chemicalClassify.getStock()));
        if (!super.updateById(cc)) {
            PtAssert.fail("归类【" + classifyId + "】增加归类库存量失败，请联系管理员！");
        }
        // 3、设置归类关联
        List<LmsChemicalRelClassify> relList = new ArrayList<>();
        for (Long chemicalId : chemicalIds) {
            relList.add(new LmsChemicalRelClassify().setChemicalId(chemicalId).setClassifyId(classifyId));
        }
        return lmsChemicalRelClassifyService.saveBatch(relList);
    }


    /**
     * <p>
     * 移除归类耗材 1、减去归类库存  2、移除关联归类
     * </p>
     *
     * @param classifyId  归类 ID
     * @param chemicalIds 耗材 ID
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean removeRelChemical(Long classifyId, List<Long> chemicalIds) {
        // 1、减去归类库存
        LmsChemicalClassify chemicalClassify = super.getById(classifyId);
        if (null == chemicalClassify || null == chemicalClassify.getStock()) {
            PtAssert.fail("归类【" + classifyId + "】不存在或者库存异常，请联系管理员！");
        }
        LmsChemicalClassify cc = new LmsChemicalClassify();
        cc.setId(classifyId);
        BigDecimal classifyStock = chemicalClassify.getStock();
        List<LmsChemical> chemicalList = lmsChemicalService.listByIdList(chemicalIds);
        for (LmsChemical chemical : chemicalList) {
            if (null != chemical.getExstock()) {
                classifyStock = BigDecimalUtils.sub(classifyStock, chemical.getExstock());
            }
        }
        cc.setStock(classifyStock);
        if (!super.updateById(cc)) {
            PtAssert.fail("归类【" + classifyId + "】减去归类库存量失败，请联系管理员！");
        }
        // 2、移除关联归类
        return lmsChemicalRelClassifyService.deleteRelChemical(classifyId, chemicalIds);
    }



    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addStockByChemicalId(Long chemicalId, BigDecimal stock, boolean add) {
        List<LmsChemicalClassify> chemicalClassifyList = listByChemicalId(chemicalId);
        if (CollectionUtils.isEmpty(chemicalClassifyList)) {
            // 不存关联，逻辑上也是成功
            return true;
        }
        Account account = LoginHelper.getAccount();

        return super.updateBatchById(chemicalClassifyList.stream().map(e -> {
            LmsChemicalClassify cc = new LmsChemicalClassify();
            cc.setId(e.getId());
            if (add) {
                // 增加
                cc.setStock(BigDecimalUtils.add(e.getStock(), stock));
            } else {
                // 减少
                cc.setStock(BigDecimalUtils.sub(e.getStock(), stock));
                // 开启报警通知，库存低于预警值发送报警消息
                if (e.getInform() == 1 && BigDecimalUtils.lessThan(cc.getStock(), e.getWarning())) {
                    e.setStock(cc.getStock());
                    sendWarningMsg(e, account);
                }
            }
            return cc;
        }).collect(Collectors.toList()));
    }


    public void sendWarningMsg(LmsChemicalClassify chemicalClassify, Account account) {
//        try {
//            StringBuilder content = new StringBuilder();
//            StringBuilder title = new StringBuilder();
//            title.append("# 存库报警 # 耗材归类：").append(chemicalClassify.getName());
//            content.append(" 现有库存量：").append(chemicalClassify.getStock()).append(chemicalClassify.getUnit());
//            content.append(" ，预警值：").append(chemicalClassify.getWarning()).append(chemicalClassify.getUnit());
//            content.append(" 请及时补充库存，最近一次触发存库报警人：").append(account.getUserName());
//            MqMsg mqMsg = new MqMsg();
//            mqMsg.setUid(account.getUserId());
//            mqMsg.setCompanyId(account.getCompanyId());
//            mqMsg.setSender(account.getUserName());
//            mqMsg.setTitle(title.toString());
//            mqMsg.setContent(content.toString());
//            // 报警消息
//            mqMsg.setType(1);
//            amqpTemplate.convertAndSend(mqProperties.getTopic().getChemicalClassifyWarning(), mqMsg);
//        } catch (AmqpException e) {
//            logger.error("耗材归类：%s 报警MQ消息发送失败。", chemicalClassify.getName(), e);
//        }
    }


    @Override
    public List<LmsChemicalClassify> listByChemicalId(Long chemicalId) {
        return baseMapper.selectListByChemicalId(chemicalId);
    }
}
