package com.fjhx.wms.service.stock.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.common.utils.Assert;
import com.fjhx.item.entity.product.po.ProductInfo;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.wms.entity.stock.dto.StockWaitDetailsDto;
import com.fjhx.wms.entity.stock.dto.StockWaitDetailsSelectDto;
import com.fjhx.wms.entity.stock.dto.StockWaitDto;
import com.fjhx.wms.entity.stock.po.StockWait;
import com.fjhx.wms.entity.stock.po.StockWaitDetails;
import com.fjhx.wms.entity.stock.vo.StockWaitDetailsVo;
import com.fjhx.wms.mapper.stock.StockWaitDetailsMapper;
import com.fjhx.wms.service.stock.StockWaitDetailsService;
import com.fjhx.wms.service.stock.StockWaitService;
import com.obs.services.internal.ServiceException;
import com.ruoyi.common.utils.wrapper.IWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 待出入库明细 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-13
 */
@Service
public class StockWaitDetailsServiceImpl extends ServiceImpl<StockWaitDetailsMapper, StockWaitDetails> implements StockWaitDetailsService {
    @Autowired
    private ProductInfoService productInfoService;
    @Autowired
    private StockWaitService stockWaitService;
//    @Autowired
//    private StockJournalService stockJournalService;
//    @Autowired
//    private StockJournalDetailsService stockJournalDetailsService;
//    @Autowired
//    private StockService stockService;
//    @Autowired
//    private WmsService wmsService;
//    @Autowired
//    private StockFrozenService stockFrozenService;

    @Override
    public Page<StockWaitDetailsVo> getPage(StockWaitDetailsSelectDto dto) {
        IWrapper<StockWaitDetails> wrapper = getWrapper();
        wrapper.orderByDesc("swd", StockWaitDetails::getId);
        wrapper.eq("sw", StockWait::getType, dto.getType());
        if (ObjectUtil.isNotEmpty(dto.getKeyword())) {
            wrapper.and(q -> q.like(StockWaitDetails::getQuantity, dto.getKeyword()).or().like(StockWaitDetailsVo::getBusinessCode, dto.getKeyword()));
        }
        wrapper.eq("sw", StockWait::getBusinessType, dto.getBusinessType());
        wrapper.eq("sw", StockWait::getStatus, dto.getStatus());
        Page<StockWaitDetailsVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        List<StockWaitDetailsVo> records = page.getRecords();
        for (StockWaitDetailsVo record : records) {
            if (ObjectUtil.isEmpty(record.getReceiptQuantity())) {
                record.setReceiptQuantity(BigDecimal.ZERO);
            }
        }
        // 赋值产品属性
        productInfoService.attributeAssign(records, StockWaitDetailsVo::getProductId, (item, productInfo) -> {
            item.setProductCode(productInfo.getCode());
            item.setProductUnit(productInfo.getUnit());
            item.setProductType(productInfo.getType());
            item.setProductName(productInfo.getName());
            item.setProductSpec(productInfo.getSpec());
            item.setProductDefinition(productInfo.getDefinition());
            item.setProductCustomCode(productInfo.getCustomCode());
        });
        return page;
    }

    @Override
    public StockWaitDetailsVo detail(Long id) {
        StockWaitDetails StockWaitDetails = this.getById(id);
        StockWaitDetailsVo result = BeanUtil.toBean(StockWaitDetails, StockWaitDetailsVo.class);
        //查询待入库信息
        StockWait stockWait = stockWaitService.getById(result.getStockWaitId());
        if (ObjectUtil.isEmpty(stockWait)) {
            throw new ServiceException("无法查询到待入库信息,待入库id" + result.getStockWaitId());
        }
        result.setBusinessType(stockWait.getBusinessType());
        result.setBusinessCode(stockWait.getBusinessCode());
        ProductInfo byId = productInfoService.getById(StockWaitDetails.getProductId());
        if (ObjectUtil.isEmpty(byId)) {
            throw new ServiceException("无法查询到产品信息,产品id" + StockWaitDetails.getProductId());
        }
        result.setProductName(byId.getName());
        return result;
    }

    @Override
    @DSTransactional
    public void add(StockWaitDetailsDto stockWaitDetailsDto) {
//        //修改待出库状态
//        changeStockWaitStatus(stockWaitDetailsDto);
//        StockWaitDetails stockWaitDetails = getById(stockWaitDetailsDto.getId());
//        StockWait byId = stockWaitService.getById(stockWaitDetails.getStockWaitId());
//        Integer businessType = byId.getBusinessType();
//
//        if (StockWaitType.SALE_ORDER_OUT.getDetailType().equals(businessType)) {
//            //销售订单出库
//            wmsService.outbound(stockWaitDetailsDto);
//        }
//        if (StockWaitType.PRODUCTION_TASK_OUT.getDetailType().equals(businessType)) {
//            //生产任务待出库
//            //减少冻结库存
//            StockFrozen stockFrozen = stockFrozenService.getOne(q -> q.eq(StockFrozen::getProductId, stockWaitDetails.getProductId()));
//            BigDecimal subtract = stockFrozen.getFrozenQuantity().subtract(stockWaitDetailsDto.getQuantity());
//            stockFrozen.setFrozenQuantity(subtract);
//            stockFrozenService.updateById(stockFrozen);
//        }
//
//        //创建出入库记录
//        StockJournal stockJournal = new StockJournal();
//        stockJournal.setOpType(byId.getType());
//        //根据待入库业务类型创建待出入库记录
//        stockJournal.setType(stockWaitService.getStockJournalType(businessType));
//        stockJournal.setCode(byId.getType() == 1 ? CodeEnum.SIN_CODE.getCode() : CodeEnum.SOUT_CODE.getCode());
//        stockJournal.setWarehouseId(stockWaitDetailsDto.getWarehouseId());
//        stockJournal.setBusinessId(byId.getId());
//        //保存出入库记录
//        stockJournalService.save(stockJournal);
//        //操作库存
//        Stock stock = new Stock();
//        stock.setQuantity(stockWaitDetailsDto.getQuantity());
//        stock.setProductId(stockWaitDetails.getProductId());
//        List<StockJournalDetails> stockJournalDetailsList = stockService.ModifyInventory(stockJournal.getId(), byId.getType(), Arrays.asList(stock), stockWaitDetailsDto.getWarehouseId());
//        //保存出入库明细
//        stockJournalDetailsService.saveBatch(stockJournalDetailsList);

        //优化
        StockWaitDetails stockWaitDetails = this.getById(stockWaitDetailsDto.getId());
        Assert.notEmpty(stockWaitDetails, "查询不到待出库明细信息");
        StockWaitDto stockWaitDto = BeanUtil.copyProperties(stockWaitDetailsDto, StockWaitDto.class);
        stockWaitDto.setId(stockWaitDetails.getStockWaitId());
        stockWaitDto.setStockWaitDetailsList(Collections.singletonList(BeanUtil.copyProperties(stockWaitDetailsDto, StockWaitDetails.class)));
        stockWaitService.addByWdly(stockWaitDto);
    }


    /**
     * 更新待出入库状态
     */
    @Override
    public void changeStockWaitStatus(StockWaitDto stockWaitDto) {
        List<StockWaitDetails> stockWaitDetailsDtoList = stockWaitDto.getStockWaitDetailsList();
        List<StockWaitDetailsDto> stockWaitDetailsDtoList1 = BeanUtil.copyToList(stockWaitDetailsDtoList, StockWaitDetailsDto.class);

        //获取待入库明细信息
        List<Long> swdIds = stockWaitDetailsDtoList.stream().map(StockWaitDetails::getId).collect(Collectors.toList());
        Map<Long, StockWaitDetails> stockWaitDetailsMap = this.mapKEntity(StockWaitDetails::getId, q -> q.in(StockWaitDetails::getId, swdIds));

        for (StockWaitDetailsDto stockWaitDetailsDto : stockWaitDetailsDtoList1) {
            //更新已入库数量 根据明细id
            StockWaitDetails stockWaitDetails = stockWaitDetailsMap.get(stockWaitDetailsDto.getId());
            if (ObjectUtil.isEmpty(stockWaitDetails)) {
                throw new ServiceException("无法查询到明细信息");
            }
            BigDecimal receiptQuantity = stockWaitDetails.getReceiptQuantity();
            receiptQuantity = ObjectUtil.isEmpty(receiptQuantity) ? BigDecimal.ZERO : receiptQuantity;
            stockWaitDetails.setReceiptQuantity(receiptQuantity.add(stockWaitDetailsDto.getQuantity()));
//            if (stockWaitDetails.getReceiptQuantity().compareTo(stockWaitDetails.getQuantity()) > 0) {
//                throw new ServiceException("出库数量+已出库数量不能大于待出库数量");
//            }
            updateById(stockWaitDetails);
        }

        //更新待出库记录状态
        int statusFlag = 0;
        List<StockWaitDetails> stockWaitDetailsList = list(q -> q.eq(StockWaitDetails::getStockWaitId, stockWaitDto.getId()));
        for (StockWaitDetails waitDetails : stockWaitDetailsList) {
            //计算已经完全出库的数量
            BigDecimal receiptQuantity1 = ObjectUtil.isEmpty(waitDetails.getReceiptQuantity()) ? BigDecimal.ZERO : waitDetails.getReceiptQuantity();
            if (receiptQuantity1.compareTo(waitDetails.getQuantity()) >= 0) {
                statusFlag++;
            }
        }
        StockWait byId = stockWaitService.getById(stockWaitDto.getId());
        if (statusFlag == stockWaitDetailsList.size()) {
            byId.setStatus(2);//入库完成
        } else {
            byId.setStatus(1);//部分入库
        }
        stockWaitService.updateById(byId);
    }

    @Override
    public void edit(StockWaitDetailsDto stockWaitDetailsDto) {
        this.updateById(stockWaitDetailsDto);
    }

    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

}
