package com.jwipc.order.logic.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jwipc.api.constant.RestCode;
import com.jwipc.api.dto.SapReposeCostDTO;
import com.jwipc.api.dto.SapResposeBody;
import com.jwipc.exception.DaoException;
import com.jwipc.order.constant.PoSapClient;
import com.jwipc.order.dto.CreateDeliveryToSapDTO;
import com.jwipc.order.dto.DevPlanToSapDTO;
import com.jwipc.order.entity.DeliveryOrder;
import com.jwipc.order.entity.DeliveryOrderDetail;
import com.jwipc.order.entity.PurchaseOrder;
import com.jwipc.order.logic.DeliveryOrderPushMesLogic;
import com.jwipc.order.logic.DeliveryOrderPushSapLogic;
import com.jwipc.order.service.IDeliveryOrderDetailService;
import com.jwipc.order.service.IDeliveryOrderService;
import com.jwipc.order.service.IPurchaseOrderService;
import com.jwipc.security.LoginUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author shenyang.ou
 * @date 2025/12/23 15:24
 * @desc
 */
@Service
@RequiredArgsConstructor
public class DeliveryOrderPushSapLogicImpl implements DeliveryOrderPushSapLogic {
    private final PoSapClient poSapClient;
    private final IDeliveryOrderService deliveryOrderService;
    private final IDeliveryOrderDetailService deliveryOrderDetailService;
    private final IPurchaseOrderService purchaseOrderService;

    @Override
    @Transactional(noRollbackFor = DaoException.class )
    public void pushDeliveryToSap(Long deliveryOrderId,String otpType) {
        DeliveryOrder deliveryOrder = deliveryOrderService.getById(deliveryOrderId);

        final CreateDeliveryToSapDTO createDeliveryToSapDTO = new CreateDeliveryToSapDTO();
        final CreateDeliveryToSapDTO.IS_HEAD head = new CreateDeliveryToSapDTO.IS_HEAD();
        final CreateDeliveryToSapDTO.ItItem itItem = new CreateDeliveryToSapDTO.ItItem();
        head.setZORDER_CODE(deliveryOrder.getOrderCode());
        head.setZTYPE(otpType);
        createDeliveryToSapDTO.setIS_HEAD(head);
        List<DeliveryOrderDetail> deliveryOrderDetails = deliveryOrderDetailService.list(new LambdaQueryWrapper<>(DeliveryOrderDetail.class)
                .eq(DeliveryOrderDetail::getOrderId, deliveryOrderId).eq(DeliveryOrderDetail::getDelFlag, otpType.equals("D")?1:0));
        if (CollUtil.isNotEmpty(deliveryOrderDetails)){
            PurchaseOrder purchaseOrder = purchaseOrderService.getOne(new LambdaQueryWrapper<PurchaseOrder>().eq(PurchaseOrder::getOrderCode, deliveryOrderDetails.get(0).getPurchaseOrderCode()));
            if (ObjectUtil.isNull(purchaseOrder)){
                deliveryOrderService.update(new LambdaUpdateWrapper<>(DeliveryOrder.class)
                        .set(DeliveryOrder::getShipmentSapStatus, 1).eq(DeliveryOrder::getId, deliveryOrderId));
                return;
            }
            if (!purchaseOrder.getOrderTypeCode().equals("Z009")&&!purchaseOrder.getOrderTypeCode().equals("Z004")){
                deliveryOrderService.update(new LambdaUpdateWrapper<>(DeliveryOrder.class)
                        .set(DeliveryOrder::getShipmentSapStatus, 1).eq(DeliveryOrder::getId, deliveryOrderId));
                return;
            }
            if (!purchaseOrder.getCurrencyCode().equals("USD")){
                deliveryOrderService.update(new LambdaUpdateWrapper<>(DeliveryOrder.class)
                        .set(DeliveryOrder::getShipmentSapStatus, 1).eq(DeliveryOrder::getId, deliveryOrderId));
                return;
            }
            List<CreateDeliveryToSapDTO.Item> items = new ArrayList<>();
            for (DeliveryOrderDetail deliveryOrderDetail : deliveryOrderDetails){
                CreateDeliveryToSapDTO.Item item = new CreateDeliveryToSapDTO.Item();
                item.setZORDER_ROW(deliveryOrderDetail.getOrderRow());
                item.setEBELN(deliveryOrderDetail.getPurchaseOrderCode());
                item.setEBELP(deliveryOrderDetail.getPurchaseOrderRow());
                item.setMENGE(deliveryOrderDetail.getNum().toString());
                items.add(item);
            }
            itItem.setItem(items);
            createDeliveryToSapDTO.setIT_ITEM(itItem);
        }
        SapResposeBody sapResposeBody = poSapClient.createDelivery(createDeliveryToSapDTO);
        if (!sapResposeBody.getES_RET().getCODE().equals(RestCode.SAP_SUCCESS.getCode())) {
            deliveryOrderService.update(new LambdaUpdateWrapper<>(DeliveryOrder.class)
                    .set(DeliveryOrder::getShipmentSapStatus, 3)
                    .set(DeliveryOrder::getShipmentSapMsg, sapResposeBody.getES_RET().getMSG())
                    .eq(DeliveryOrder::getId, deliveryOrderId));
            throw new DaoException("SAP接口报错："+sapResposeBody.getES_RET().getMSG());
        }
        if (otpType.equals("C")){
            List<SapReposeCostDTO.Item> itemList = sapResposeBody.getIT_RESULT().getItem();
            if (CollUtil.isNotEmpty(itemList)){
                itemList.forEach(item -> {
                    deliveryOrderDetails.forEach(deliveryOrderDetail -> {
                        if (deliveryOrderDetail.getOrderCode().equals(item.getZORDER_CODE())&&deliveryOrderDetail.getOrderRow().equals(item.getZORDER_ROW())){
                            deliveryOrderDetail.setShipmentNo(item.getVBELN());
                            deliveryOrderDetail.setShipmentRowNo(item.getPOSNR());
                            deliveryOrderDetailService.updateById(deliveryOrderDetail);
                        }
                    });
                });
            }
        }
        deliveryOrderService.update(new LambdaUpdateWrapper<>(DeliveryOrder.class)
                .set(DeliveryOrder::getShipmentSapStatus, 2)
                .eq(DeliveryOrder::getId, deliveryOrderId));

    }

    @Override
    public void pushDeleteDeliveryToSap(List<String> detailIdList) {
        List<DeliveryOrderDetail> deliveryOrderDetails = deliveryOrderDetailService.list(new LambdaQueryWrapper<>(DeliveryOrderDetail.class).in(DeliveryOrderDetail::getId, detailIdList));
        DeliveryOrder deliveryOrder = deliveryOrderService.getById(deliveryOrderDetails.get(0).getOrderId());
        if (deliveryOrder.getShipmentSapStatus()==0||deliveryOrder.getShipmentSapStatus()==1){
            return;
        }
        final CreateDeliveryToSapDTO createDeliveryToSapDTO = new CreateDeliveryToSapDTO();
        final CreateDeliveryToSapDTO.IS_HEAD head = new CreateDeliveryToSapDTO.IS_HEAD();
        final CreateDeliveryToSapDTO.ItItem itItem = new CreateDeliveryToSapDTO.ItItem();
        head.setZORDER_CODE(deliveryOrder.getOrderCode());
        head.setZTYPE("D");
        createDeliveryToSapDTO.setIS_HEAD(head);
        if (CollUtil.isNotEmpty(deliveryOrderDetails)){
            List<CreateDeliveryToSapDTO.Item> items = new ArrayList<>();
            for (DeliveryOrderDetail deliveryOrderDetail : deliveryOrderDetails){
                CreateDeliveryToSapDTO.Item item = new CreateDeliveryToSapDTO.Item();
                item.setZORDER_ROW(deliveryOrderDetail.getOrderRow());
                item.setEBELN(deliveryOrderDetail.getPurchaseOrderCode());
                item.setEBELP(deliveryOrderDetail.getPurchaseOrderRow());
                item.setMENGE(deliveryOrderDetail.getNum().toString());
                items.add(item);
            }
            itItem.setItem(items);
            createDeliveryToSapDTO.setIT_ITEM(itItem);
        }
        SapResposeBody sapResposeBody = poSapClient.createDelivery(createDeliveryToSapDTO);
        if (!sapResposeBody.getES_RET().getCODE().equals(RestCode.SAP_SUCCESS.getCode())) {
            throw new DaoException("SAP接口报错："+sapResposeBody.getES_RET().getMSG());
        }
    }
}
