package com.jwipc.order.logic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jwipc.api.constant.RestCode;
import com.jwipc.constant.DelFlag;
import com.jwipc.order.constant.DeliveryStatus;
import com.jwipc.order.constant.PoSapClient;
import com.jwipc.order.constant.PurchaseOrderStatus;
import com.jwipc.order.dto.AppointmentQuantityResposeDTO;
import com.jwipc.order.dto.AppointmentQuantitySapDTO;
import com.jwipc.order.entity.PurchaseOrderDetail;
import com.jwipc.order.logic.PurchaseOrderCountLogic;
import com.jwipc.order.service.IDeliveryOrderDetailService;
import com.jwipc.order.service.IPurchaseOrderDetailService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class PurchaseOrderCountLogicImpl implements PurchaseOrderCountLogic {
    private final IDeliveryOrderDetailService deliveryOrderDetailService;
    private final IPurchaseOrderDetailService purchaseOrderDetailService;
    private final PoSapClient poSapClient;
    //采购订单数量分配,按照单个供应商分配
    //1.取出sap的数量
    //2.统计总的在途数量
    //3.得到的数量再进行分配到订单行的可送数量上面,不能超过订单行的总数

    /**
     * 1、订单行/计划行收货完成不允许修改
     * 2、计划行有收货数量不允许删除
     * 3、计划行数量不允许修改小于已收货数量
     * 4、总量-在途；每一行的分配逻辑：订单行未清数量-行在途数量
     *
     * @param params
     */
    @Override
    public Map<Long, BigDecimal> allocateOrderQuantity(List<AppointmentQuantitySapDTO.Item> params) {
        Map<Long, BigDecimal> result = Maps.newHashMap();
        Map<String, BigDecimal> resultMap = getMaterialQuantity(params);
        for (String s : resultMap.keySet()) {
            //获取料号和工厂
            final String[] split = s.split(StrUtil.AT + StrUtil.AT);
            String materialCode = split[0];
            String factory = split[1];
            //可分配的数量
            BigDecimal subtract = resultMap.get(s);
            //需要把这个数量分配到订单的可送数量,并且需要考虑送货单的在途数量
            //查询需要分配的订单明细行
            List<PurchaseOrderDetail> purchaseOrderDetails = Lists.newArrayList();
            List<PurchaseOrderDetail> purchaseOrderDetails1 =
                    purchaseOrderDetailService.findByMaterialCodeAndFactoryWithStatus(
                            materialCode, factory,
                            Lists.newArrayList(PurchaseOrderStatus.CONFIRMATION_COMPLETED.getStatus()),
                            DelFlag.NORMAL.getStatus(), "replay_require_date");
            if (CollUtil.isNotEmpty(purchaseOrderDetails1)) {
                purchaseOrderDetails.addAll(purchaseOrderDetails1);
            }
            List<PurchaseOrderDetail> purchaseOrderDetails2 =
                    purchaseOrderDetailService.findByMaterialCodeAndFactoryWithStatus(
                            materialCode, factory,
                            Lists.newArrayList(PurchaseOrderStatus.CONFIRMATION_COMPLETED.getStatus()),
                            DelFlag.NORMAL.getStatus(), "create_time");
            if (CollUtil.isNotEmpty(purchaseOrderDetails2)) {
                purchaseOrderDetails.addAll(purchaseOrderDetails2);
            }
            for (PurchaseOrderDetail purchaseOrderDetail : purchaseOrderDetails) {
                //需要未清 - 已发货送货单的数量
                final BigDecimal noClearNum = purchaseOrderDetail.getNoClearNum();
                BigDecimal shippedCount = deliveryOrderDetailService.findCountByPurchaseDetail(
                        purchaseOrderDetail.getOrderCode(), purchaseOrderDetail.getOrderRow(),
                        DeliveryStatus.SHIPPED.getStatus(), DelFlag.NORMAL.getStatus());
                BigDecimal enableCount = noClearNum.subtract(shippedCount);
                if (enableCount.compareTo(subtract) >= 0) {
                    enableCount = subtract;
                }
                if (enableCount.compareTo(BigDecimal.ZERO) >= 0) {
                    purchaseOrderDetail.setEnableNum(enableCount);
                } else {
                    enableCount = BigDecimal.ZERO;
                    purchaseOrderDetail.setEnableNum(BigDecimal.ZERO);
                }
                result.put(purchaseOrderDetail.getId(), enableCount);
                purchaseOrderDetailService.update(new LambdaUpdateWrapper<PurchaseOrderDetail>()
                        .eq(PurchaseOrderDetail::getId, purchaseOrderDetail.getId())
                        .eq(PurchaseOrderDetail::getFactoryCode, purchaseOrderDetail.getFactoryCode())
                        .set(PurchaseOrderDetail::getEnableNum, purchaseOrderDetail.getEnableNum()));
                subtract = subtract.subtract(enableCount);
            }
        }
        return result;
    }

    /**
     * 取出当前的可用数量
     *
     * @param params
     * @return
     */
    @Override
    public Map<String, BigDecimal> getMaterialQuantity(List<AppointmentQuantitySapDTO.Item> params) {
        // 如果没有参数，则不调用 SAP
        if (CollUtil.isEmpty(params)) {
            return Maps.newHashMap();
        }
        AppointmentQuantitySapDTO sapDTO = new AppointmentQuantitySapDTO();
        final AppointmentQuantitySapDTO.Item1 item1 = new AppointmentQuantitySapDTO.Item1();
        item1.setItem(params);
        sapDTO.setIT_HEAD(item1);
        final AppointmentQuantityResposeDTO appointmentQuantity = poSapClient.getAppointmentQuantity(sapDTO);
        if (appointmentQuantity.getES_RET().getCODE().equals(RestCode.SAP_SUCCESS.getCode())) {
            final AppointmentQuantityResposeDTO.Item1 itItem = appointmentQuantity.getIT_ITEM();
            final List<AppointmentQuantityResposeDTO.Item2> item = itItem.getItem();
            // 使用 Lambda 表达式将 List 转换为 Map
            Map<String, BigDecimal> resultMap1 = item.stream()
                    .collect(Collectors.toMap(
                            a -> a.getMATNR() + StrUtil.AT + StrUtil.AT + a.getWERKS(), // 以MATNR+WERKS作为key
                            b -> new BigDecimal(b.getZQLSL())
                    ));
            Map<String, BigDecimal> resultMap = Maps.newHashMap();
            for (String s : resultMap1.keySet()) {
                final String[] split = s.split(StrUtil.AT + StrUtil.AT);
                String materialCode = split[0];
                String factory = split[1];
                final BigDecimal bigDecimal = resultMap1.get(s);
                //需要取这个物料的已发货送货单的总数量
                BigDecimal count = deliveryOrderDetailService.findCountByMaterialCodeAndFactory(materialCode, factory,
                        DeliveryStatus.SHIPPED.getStatus(), DelFlag.NORMAL.getStatus());
                //可分配的数量
                BigDecimal subtract = bigDecimal.subtract(count);
                resultMap.put(s, subtract);
            }
            return resultMap;
        }
        return Maps.newHashMap();
    }
}