package com.jwipc.order.api.logic.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.common.collect.Maps;
import com.jwipc.api.constant.RestCode;
import com.jwipc.api.dto.ApiResult;
import com.jwipc.log.annotation.ApiOperateLog;
import com.jwipc.log.constant.ApiDirection;
import com.jwipc.log.constant.ThirdSysType;
import com.jwipc.order.api.dto.UpdateDevPlanDTO;
import com.jwipc.order.api.logic.UpdateDevPlanLogic;
import com.jwipc.order.entity.PurchaseOrderDetail;
import com.jwipc.order.entity.PurchaseOrderDevPlan;
import com.jwipc.order.service.IPurchaseOrderDetailService;
import com.jwipc.order.service.IPurchaseOrderDevPlanService;
import com.jwipc.util.DateUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.baomidou.dynamic.datasource.support.DdConstants.SLAVE;
import static com.jwipc.util.DateUtils.yyyyMMdd;
import static com.jwipc.util.DateUtils.yyyyMMddDash;


/**
 * <p> </p>
 *
 * @author BOGON
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@RequiredArgsConstructor
public class UpdateDevPlanLogicImpl implements UpdateDevPlanLogic {
    private final IPurchaseOrderDevPlanService purchaseOrderDevPlanService;
    private final IPurchaseOrderDetailService purchaseOrderDetailService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ApiOperateLog(code = "updateDevPlan", name = "SAP更新订单计划行", direction = ApiDirection.OTHER_TO_SRM,
            thirdSysType = ThirdSysType.SAP)
    @DS(SLAVE)
    public ApiResult processor(UpdateDevPlanDTO updateDevPlanDTO) {
        final List<UpdateDevPlanDTO.Item> itData = updateDevPlanDTO.getIT_DATA();
        try {
            Map<String, PurchaseOrderDetail> purchaseOrderDetailMap = Maps.newHashMap();
            for (UpdateDevPlanDTO.Item itDatum : itData) {
                String lastRequireDate = StrUtil.EMPTY;
                if (StrUtil.isNotEmpty(itDatum.getEINDT())) {
                    lastRequireDate =
                            DateUtil.parse(itDatum.getEINDT(), yyyyMMdd).toString(yyyyMMddDash);
                }else{
                    continue;
                }
                final LambdaUpdateWrapper<PurchaseOrderDevPlan> updateWrapper =
                        new LambdaUpdateWrapper<PurchaseOrderDevPlan>()
                                .set(PurchaseOrderDevPlan::getDay1, itDatum.getDAY1())
                                .set(PurchaseOrderDevPlan::getDay2, itDatum.getDAY2())
                                .set(PurchaseOrderDevPlan::getDay3, itDatum.getDAY3())
                                .set(PurchaseOrderDevPlan::getDay4, itDatum.getDAY4())
                                .set(PurchaseOrderDevPlan::getDay5, itDatum.getDAY5())
                                .set(PurchaseOrderDevPlan::getDay6, itDatum.getDAY6())
                                .set(PurchaseOrderDevPlan::getDay7, itDatum.getDAY7())
                                .set(PurchaseOrderDevPlan::getWeek1, itDatum.getWEEK1())
                                .set(PurchaseOrderDevPlan::getWeek2, itDatum.getWEEK2())
                                .set(PurchaseOrderDevPlan::getWeek3, itDatum.getWEEK3())
                                .set(PurchaseOrderDevPlan::getWeek4, itDatum.getWEEK4())
                                .set(PurchaseOrderDevPlan::getWeek5, itDatum.getWEEK5())
                                .set(PurchaseOrderDevPlan::getWeek6, itDatum.getWEEK6())
                                .set(PurchaseOrderDevPlan::getWeek7, itDatum.getWEEK7())
                                .set(PurchaseOrderDevPlan::getWeek8, itDatum.getWEEK8())
                                .set(PurchaseOrderDevPlan::getMonth1, itDatum.getMONTH1());
                updateWrapper
                        .set(PurchaseOrderDevPlan::getMonth2, itDatum.getMONTH2())
                        .set(PurchaseOrderDevPlan::getMonth3, itDatum.getMONTH3())
                        .set(PurchaseOrderDevPlan::getMonth4, itDatum.getMONTH4())
                        .set(PurchaseOrderDevPlan::getLastRequireDate, lastRequireDate)
                        .eq(PurchaseOrderDevPlan::getPurchaseOrder, itDatum.getEBELN())
                        .eq(PurchaseOrderDevPlan::getLineItem, itDatum.getEBELP())
                        .eq(PurchaseOrderDevPlan::getScheduleLine, itDatum.getETENR());
                final String key = itDatum.getEBELN() + itDatum.getEBELP();
                PurchaseOrderDetail purchaseOrderDetail = purchaseOrderDetailMap.get(
                        key);
                if (Objects.isNull(purchaseOrderDetail)) {
                    purchaseOrderDetail = new PurchaseOrderDetail();
                    purchaseOrderDetail.setOrderCode(itDatum.getEBELN());
                    purchaseOrderDetail.setOrderRow(itDatum.getEBELP());
                    purchaseOrderDetailMap.put(key, purchaseOrderDetail);
                }
                purchaseOrderDevPlanService.update(updateWrapper);
            }
            //更新订单明细的需求日期
            purchaseOrderDetailMap.values().forEach(purchaseOrderDetail -> {
                //先取最早的日期
                final PurchaseOrderDevPlan one = purchaseOrderDevPlanService.getOne(
                        new LambdaQueryWrapper<>(PurchaseOrderDevPlan.class)
                                .eq(PurchaseOrderDevPlan::getPurchaseOrder, purchaseOrderDetail.getOrderCode())
                                .eq(PurchaseOrderDevPlan::getLineItem, purchaseOrderDetail.getOrderRow())
                                .eq(PurchaseOrderDevPlan::getDelFlag,0)
                                .apply("(schedule_delivery_quantity-received_quantity)>0")
                                .orderByAsc(PurchaseOrderDevPlan::getLastRequireDate), false);
                if (Objects.nonNull(one)) {
                    purchaseOrderDetailService.update(new LambdaUpdateWrapper<PurchaseOrderDetail>()
                            .set(PurchaseOrderDetail::getRequireDate,
                                    DateUtils.formatYYYYMMDDDash(one.getLastRequireDate()))
                            .eq(PurchaseOrderDetail::getOrderCode, purchaseOrderDetail.getOrderCode())
                            .eq(PurchaseOrderDetail::getOrderRow, purchaseOrderDetail.getOrderRow()));
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
            //手动回滚事务
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ApiResult.builder().code(RestCode.SAP_ERROR.getCode()).message(e.getMessage()).build();
        }
        return ApiResult.builder().code(RestCode.SAP_SUCCESS.getCode()).build();
    }
}