package com.fjhx.service.quality.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.base.BaseIdEntity;
import com.fjhx.entity.quality.QualityDetails;
import com.fjhx.entity.quality.QualityInfo;
import com.fjhx.entity.stock.Stock;
import com.fjhx.enums.stock.OutTypeEnum;
import com.fjhx.mapper.quality.QualityDetailsMapper;
import com.fjhx.params.quality.QualityDetailsVo;
import com.fjhx.params.stock.InStockAdd;
import com.fjhx.params.stock.StockChangeVo;
import com.fjhx.service.quality.QualityDetailsService;
import com.fjhx.service.quality.QualityInfoService;
import com.fjhx.service.stock.StockService;
import com.fjhx.utils.wrapperUtil.IWrapper;
import org.springblade.core.log.exception.ServiceException;
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.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 质检明细 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2023-02-13
 */
@Service
public class QualityDetailsServiceImpl extends ServiceImpl<QualityDetailsMapper, QualityDetails> implements QualityDetailsService {

    @Autowired
    private StockService stockService;

    @Autowired
    private QualityInfoService qualityInfoService;

    @Override
    public Page<QualityDetails> getPage(Map<String, Object> condition) {

        IWrapper<QualityDetails> wrapper = IWrapper.getWrapper(condition);

        return page(condition, wrapper);
    }

    @Override
    public void add(QualityDetailsVo qualityDetailsVo) {
        save(qualityDetailsVo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public synchronized void edit(List<QualityDetails> qualityDetailsList) {
        List<Long> idList = qualityDetailsList.stream().map(BaseIdEntity::getId).collect(Collectors.toList());
        List<QualityDetails> oldQualityDetailsList = listByIds(idList);
        Map<Long, QualityDetails> oldMap = oldQualityDetailsList.stream().collect(Collectors.toMap(BaseIdEntity::getId, item -> item));

        // 出库id
        Long warehouseId = oldQualityDetailsList.get(0).getWarehouseId();
        // 质检id
        Long qualityInfoId = oldQualityDetailsList.get(0).getQualityInfoId();
        // map<产品id,库存变更数量>
        Map<Long, BigDecimal> map = new HashMap<>();
        // 不合格出库逻辑列表
        List<InStockAdd.InStockAddDetails> list = new ArrayList<>();
        // 是否完成质检标记
        boolean qualityFlag = true;
        // 质检结果标记
        boolean resultTypeFlag = true;

        for (QualityDetails qualityDetails : qualityDetailsList) {
            QualityDetails oldQualityDetails = oldMap.get(qualityDetails.getId());
            Long productInfoId = oldQualityDetails.getProductInfoId();

            // 改变不合格数量
            BigDecimal disqualificationQuantity = qualityDetails.getDisqualificationQuantity();
            if (disqualificationQuantity.compareTo(BigDecimal.ZERO) > 0) {
                InStockAdd.InStockAddDetails inStockAddDetails = new InStockAdd.InStockAddDetails();
                inStockAddDetails.setBusinessId(oldQualityDetails.getId());
                inStockAddDetails.setWarehouseId(oldQualityDetails.getWarehouseId());
                inStockAddDetails.setGoodsId(productInfoId);
                inStockAddDetails.setChangeQuantity(disqualificationQuantity);
                list.add(inStockAddDetails);
            }

            // 改变合格数量
            BigDecimal qualifiedQuantity = qualityDetails.getQualifiedQuantity();
            if (qualifiedQuantity.compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal bigDecimal = ObjectUtil.defaultIfNull(map.get(productInfoId), BigDecimal.ZERO);
                map.put(productInfoId, bigDecimal.add(qualifiedQuantity));
            }
            qualityDetails.setQualifiedQuantity(oldQualityDetails.getQualifiedQuantity().add(qualityDetails.getQualifiedQuantity()));
            qualityDetails.setDisqualificationQuantity(oldQualityDetails.getDisqualificationQuantity().add(qualityDetails.getDisqualificationQuantity()));
            int compareTo = qualityDetails.getQualifiedQuantity().add(qualityDetails.getDisqualificationQuantity()).compareTo(qualityDetails.getTotalQuantity());
            if (compareTo > 0) {
                throw new ServiceException("合格数量加不合格数量不能大于需要质检的总数量");
            }
            if (oldQualityDetails.getDisqualificationQuantity().compareTo(BigDecimal.ZERO) > 0) {
                resultTypeFlag = false;
            }
            if (compareTo != 0) {
                qualityFlag = false;
            }
        }
        // 修改质检未完成状态
        QualityInfo qualityInfo = new QualityInfo();
        qualityInfo.setId(qualityInfoId);
        qualityInfo.setStatus(qualityFlag ? 3 : 2);
        qualityInfo.setResultType(resultTypeFlag ? 1 : 2);
        qualityInfoService.updateById(qualityInfo);

        // 质检不合格数量走出库,减少锁定库存
        if (list.size() > 0) {
            StockChangeVo stockChangeVo = new StockChangeVo();
            stockChangeVo.setTypeEnum(OutTypeEnum.UNQUALIFIED_QUALITY_INSPECTION);
            stockChangeVo.setDefaultRemarks("质检不合格出库");
            stockChangeVo.setChangeDetailsList(list);
            stockService.changeQuantity(stockChangeVo);
        }

        // 质检合格减少锁定库存,增加库存
        if (map.size() > 0) {
            List<Stock> stockList = stockService.list(q -> q.eq(Stock::getWarehouseId, warehouseId).in(Stock::getGoodsId, map.keySet()));
            for (Stock stock : stockList) {
                // 产品id
                Long goodsId = stock.getGoodsId();
                // 改变数量
                BigDecimal bigDecimal = map.get(goodsId);
                // 新增库存数量
                stock.setQuantity(stock.getQuantity().add(bigDecimal));
                // 减少锁定库存数量
                stock.setFrozenQuantity(stock.getFrozenQuantity().subtract(bigDecimal));
            }
            stockService.updateBatchById(stockList);
        }
        updateBatchById(qualityDetailsList);
    }

    @Override
    public void delete(QualityDetailsVo qualityDetailsVo) {
        removeById(qualityDetailsVo.getId());
    }

}
