package com.sw.mes.sap.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.sw.mes.base.factory.init.entity.Equipment;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.SapGrCDto;
import com.sw.mes.core.entity.TurnstoreTrayItem;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.sap.SapServer;
import com.sw.mes.third.entity.SapGi;
import com.sw.mes.third.entity.SapGr;
import com.sw.mes.third.entity.SapWorkHourOutput;
import com.sw.mes.third.service.SapGiService;
import com.sw.mes.third.service.SapGrService;
import com.sw.mes.third.service.SapWorkHourOutputService;
import com.sw.mes.yb.production.entity.LongCrystal;
import com.sw.mes.yb.production.service.LongCrystalService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;

@Slf4j
@Transactional
@Service
public class SapServerImpl implements SapServer {
    @Autowired
    private SapGrService sapGrService;
    @Autowired
    private SapGiService sapGiService;
    @Autowired
    private SapWorkHourOutputService sapWorkHourOutputService;
    @Autowired
    private LongCrystalService longCrystalService;
    @Autowired
    private EquipmentService equipmentService;

    /**
     * 发送GR
     *
     * @param turnstoreTrayItemList
     */
    @Override
    @Async
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void sendGr(List<TurnstoreTrayItem> turnstoreTrayItemList) {
        try {
            List<SapGrCDto> sapGrCdtos = new ArrayList<>();
            List<SapGi> sapGis = new ArrayList<>();
            for (TurnstoreTrayItem turnstoreTrayItem : turnstoreTrayItemList) {
                SapGrCDto sapGrCdto = new SapGrCDto();
                sapGrCdto.setCheckName(turnstoreTrayItem.getCheckoutName());
                sapGrCdto.setMaterialNumber(turnstoreTrayItem.getItemNo());
                sapGrCdto.setSectionNo(turnstoreTrayItem.getSectionNo());
                sapGrCdto.setWeight(turnstoreTrayItem.getTheoryWeight());
                sapGrCdto.setOrderNo(turnstoreTrayItem.getOrderNo());
                sapGrCdtos.add(sapGrCdto);
                if (!"一次检验".equals(turnstoreTrayItem.getCheckoutName())) {
                    // 上班复检GI
                    SapGr sapGr = sapGrService.getSapGrsAndNotGi(turnstoreTrayItem.getSectionNo(), 0);
                    if (sapGr != null) {
                        int count = sapGrService.updateStatus(sapGr.getId());
                        if (count > 0) {
                            //防止报重复GI
                            if (sapGis.stream().noneMatch(sapGi -> (sapGi.getSectionno() != null && sapGi.getSectionno().equals(sapGr.getSectionno())))) {
                                SapGi sapGi = new SapGi();
                                sapGi.setAufnr(turnstoreTrayItem.getOrderNo());
                                sapGi.setMenge(sapGr.getMenge());
                                sapGi.setMatnr(turnstoreTrayItem.getItemNo());
                                sapGi.setMatnrmat(sapGr.getMatnr());
                                sapGi.setSectionno(sapGr.getSectionno());
                                sapGi.setGrId(sapGr.getId());
                                sapGi.setType(0);
                                sapGi.setLgort("Q023");
                                sapGi.setCharg("9999999999");
                                sapGi.setWerks("1031");
                                sapGi.setConsumeType(0);
                                sapGis.add(sapGi);
                            }
                        }
                    }
                }
            }
            if (sapGis.size() > 0) {
                sapGiService.saveBatch(sapGis);
            }
            sapGrService.addYbGr(sapGrCdtos);
        } catch (Exception e) {
            log.error("sapGr发生错误：" + e.getMessage());
        }
    }

    /**
     * @param longCrystal         长棒信息
     * @param planProcessingOrder 炉次开始时间
     */
    @Async
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
    public void addWorkHour(LongCrystal longCrystal, PlanProcessingOrder planProcessingOrder) {
        try {
            Date nowDate = new Date();
            Date startDate = DateUtil.toDate(DateUtil.getCurrentMonthEndTimeX(DateUtil.addMonth(nowDate, -1), " 09:00:00"), DateUtil.longFormat);
            SapWorkHourOutput sapWorkHourOutput = sapWorkHourOutputService.findByLotIdCurrentMonth(longCrystal.getLotId(), DateUtil.formatDate(new Date(), "yyyyMM"));
            BigDecimal weight = longCrystal.getWeight();
            LinkedHashMap<String, BigDecimal> codeMap = new LinkedHashMap<>();
            SapWorkHourOutput sapWorkHourOutputNew;
            if (sapWorkHourOutput == null) {
                sapWorkHourOutputNew = new SapWorkHourOutput();
                SapWorkHourOutput sapWorkHourOutputOld = sapWorkHourOutputService.findByLotId(longCrystal.getLotId());
                if (sapWorkHourOutputOld != null) {
                    if (sapWorkHourOutputOld.getEndTime() == null) {
                        sapWorkHourOutputNew.setStartTime(startDate);
                        sapWorkHourOutputOld.setEndTime(startDate);
                        sapWorkHourOutputService.saveOrUpdate(sapWorkHourOutputOld);
                    } else {
                        sapWorkHourOutputNew.setStartTime(sapWorkHourOutputOld.getEndTime());
                    }
                } else {
                    if (planProcessingOrder.getCreateTime().getTime() < startDate.getTime()) {
                        sapWorkHourOutputNew.setStartTime(startDate);
                    } else {
                        sapWorkHourOutputNew.setStartTime(planProcessingOrder.getCreateTime());
                    }
                }
            } else {
                // 当前棒子的订单与之前的一样
                if (longCrystal.getOrderNo().equals(sapWorkHourOutput.getSapOrderNo())) {
                    //直接讲产量增加到之前的工时产量上
                    sapWorkHourOutputNew = sapWorkHourOutput;
                    codeMap = JSON.parseObject(sapWorkHourOutputNew.getCode(), new TypeReference<LinkedHashMap<String, BigDecimal>>() {
                    });
                    //当前棒子的重量加上之前棒子的重量
                    weight = weight.add(sapWorkHourOutputNew.getWeight());
                }
                // 当前棒子的订单与之前的不一样，需要切换工时产量
                else {
                    //结束之前的工时产量
                    sapWorkHourOutput.setEndTime(nowDate);
                    sapWorkHourOutputService.saveOrUpdate(sapWorkHourOutput);
                    //开启新的工时产量
                    sapWorkHourOutputNew = new SapWorkHourOutput();
                    sapWorkHourOutputNew.setStartTime(nowDate);
                }
            }
            codeMap.put(longCrystal.getCrystalNo(), longCrystal.getWeight());

            sapWorkHourOutputNew.setWeight(weight);
            sapWorkHourOutputNew.setCode(JSON.toJSONString(codeMap));
            sapWorkHourOutputNew.setEquipmentCode(longCrystal.getEquipmentCode());
            Equipment equipment = equipmentService.get(planProcessingOrder.getEquipmentId());
            if (equipment != null && equipment.getDevice() != null) {
                sapWorkHourOutputNew.setDeviceCode(equipment.getDevice().getCode());
            }
            sapWorkHourOutputNew.setLotId(longCrystal.getLotId());
            sapWorkHourOutputNew.setLotNo(longCrystal.getLotNo());
            sapWorkHourOutputNew.setProcessName(EnumValuesFactory.WipStorageCode.长晶.getValue());
            sapWorkHourOutputNew.setProcessCode(EnumValuesFactory.WipStorageCode.长晶.getKey());
            sapWorkHourOutputNew.setSapOrderNo(longCrystal.getOrderNo());
            sapWorkHourOutputNew.setSapProductNo(longCrystal.getProductCode());
            sapWorkHourOutputNew.setIssend(0);
            sapWorkHourOutputNew.setGmtUpdate(nowDate);
            sapWorkHourOutputNew.setUserUpdate(BaseContextHandler.getUsername());
            if (planProcessingOrder.getStatus() == EnumValuesFactory.PlanProcessingOrderStatus.加工完成.getKey()) {
                sapWorkHourOutputNew.setEndTime(nowDate);
            }
            sapWorkHourOutputService.saveOrUpdate(sapWorkHourOutputNew);
        } catch (Exception e) {
            log.error("sapWorkHour发生错误：" + e.getMessage());
        }
    }
}
