package com.foreverwin.mesnac.production.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.foreverwin.mesnac.common.dto.SfcDispatchDto;
import com.foreverwin.mesnac.common.enums.DispatchStatusEnum;
import com.foreverwin.mesnac.common.service.SfcDispatchCommonService;
import com.foreverwin.mesnac.common.util.ExceptionUtil;
import com.foreverwin.mesnac.meapi.dto.SfcDto;
import com.foreverwin.mesnac.meapi.model.Inventory;
import com.foreverwin.mesnac.meapi.service.InventoryService;
import com.foreverwin.mesnac.meapi.service.OperationService;
import com.foreverwin.mesnac.production.mapper.SfcCrossMapper;
import com.foreverwin.mesnac.production.mapper.SfcDataAssembleMapper;
import com.foreverwin.mesnac.production.model.SfcDataAssemble;
import com.foreverwin.mesnac.production.service.SfcDataAssembleService;
import com.foreverwin.modular.core.exception.BaseException;
import com.foreverwin.modular.core.meext.MEServices;
import com.foreverwin.modular.core.util.CommonMethods;
import com.foreverwin.modular.core.util.FrontPage;
import com.sap.me.production.AssembleComponentsRequest;
import com.sap.me.production.AssemblyComponent;
import com.sap.me.production.AssemblyDataField;
import com.sap.me.production.AssemblyServiceInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;

/**
 * <p>
 * 生产执行数据装配 服务实现类
 * </p>
 *
 * @author Philip
 * @since 2021-07-19
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SfcDataAssembleServiceImpl extends ServiceImpl<SfcDataAssembleMapper, SfcDataAssemble> implements SfcDataAssembleService {


    @Autowired
    private SfcDataAssembleMapper sfcDataAssembleMapper;
    @Autowired
    private SfcCrossMapper sfcCrossMapper;
    @Autowired
    private SfcDispatchCommonService sfcDispatchCommonService;
    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private OperationService operationService;

    @Override
    public IPage<SfcDataAssemble> selectPage(FrontPage<SfcDataAssemble> frontPage, SfcDataAssemble sfcDataAssemble) {
        QueryWrapper<SfcDataAssemble> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(sfcDataAssemble);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

    @Override
    public List<SfcDataAssemble> selectList(SfcDataAssemble sfcDataAssemble) {
        QueryWrapper<SfcDataAssemble> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(sfcDataAssemble);
        return super.list(queryWrapper);
    }

    @Override
    public Map<String, Object> loadSfcAssemble(SfcDto sfcDto) {
        //构造参数
        String site = CommonMethods.getSite();
        String user = CommonMethods.getUser();
        String sfc = sfcDto.getSfc();
        String operation = sfcDto.getOperation();
        String resrce = sfcDto.getResrce();
        String workCenter = sfcDto.getWorkCenter();
        String stepId = sfcDto.getStepId();
        SfcDispatchDto sfcDispatchDto = new SfcDispatchDto();
        sfcDispatchDto.setSfc(sfc);
        sfcDispatchDto.setStepId(stepId);
        sfcDispatchDto.setResrce(resrce);
        sfcDispatchDto.setOperation(operation);
        SfcDispatchDto sfcDispatchBySfc = sfcDispatchCommonService.findSfcDispatchBySfc(sfcDispatchDto);
        if (sfcDispatchBySfc == null || !sfcDispatchBySfc.getDispatchStatus().equals(DispatchStatusEnum.START.getCode())) {
            throw new BaseException("未在生产操作面板中执行开始操作！");
        }
        Map<String, Object> resultMap = new HashMap<String, Object>();

        //查询装配数据
        List<Map<String, Object>> assembleList = sfcDataAssembleMapper.querySfcAssemble(sfcDispatchBySfc.getHandle());
        if (assembleList == null) {
            throw new BaseException("没有装配物料");
        }
        resultMap.put("SfcDispatchBO", sfcDispatchBySfc.getHandle());
        resultMap.put("ASSEMBLE_LIST", assembleList);
        return resultMap;
    }


    @Override
    public Map<String, Object> assembleInventory(Map<String, Object> paramMap) throws BaseException {
        String site = CommonMethods.getSite();
        String user = CommonMethods.getUser();
        String inventoryId = (String) paramMap.get("INVENTORY_ID");
        String sfcDispatchBo = (String) paramMap.get("SfcDispatchBo");
        String sfc = (String) paramMap.get("SFC");
        String barCode = inventoryId;
        BigDecimal assembleQty = new BigDecimal((String) paramMap.get("QTY"));


        SfcDispatchDto sfcDispatch = new SfcDispatchDto();
        sfcDispatch.setHandle(sfcDispatchBo);
        SfcDispatchDto sfcDataMain = sfcDispatchCommonService.findSfcDispatchBySfc(sfcDispatch);

        //判断条码是否存在
        Inventory inv = inventoryService.getById("InventoryBO:" + site + "," + inventoryId);
        if (inv == null) {
            throw new BaseException("物料条码[" + barCode + "]不存在！");
        }
        //获取需装配数据，判断是为拆机还是装配
        List<Map<String, Object>> assembleList = sfcDataAssembleMapper.querySfcAssemble(sfcDispatchBo);
        String isFlag = "N";//是否在装配列表中
        String isAssemble = "";//装配情况，按颜色区分，GREEN：已装配/拆机完成，YELLOW：未装配/拆机完成，WHITE：未进行装配/拆机完成
        String item = "";//物料
        String itemBo = "";
        String bomCompBo = "";
        double seq = 0;
        BigDecimal qty = BigDecimal.ZERO;
        BigDecimal assembledQty = BigDecimal.ZERO;


        //for循环构造数据
        isFlag = "N";
        for (int i = 0; i < assembleList.size(); i++) {
            //装配
            if (assembleList.get(i).get("ITEM_BO").equals(inv.getItemBo())) {
                isFlag = "Y";
                qty = (new BigDecimal(String.valueOf(assembleList.get(i).get("QTY"))));
                assembledQty = (new BigDecimal(String.valueOf(assembleList.get(i).get("ASSEMBLE_QTY"))));
                item = (String) assembleList.get(i).get("ITEM");
                isAssemble = (String) assembleList.get(i).get("IS_ASSEMBLE");
                seq = (new BigDecimal(String.valueOf(assembleList.get(i).get("SEQ")))).doubleValue();
                itemBo = (String) assembleList.get(i).get("ITEM_BO");
                bomCompBo = (String) assembleList.get(i).get("BOM_COMPONENT_BO");
            }
        }

        if (isFlag.equals("N")) {
            throw new BaseException("物料条码[" + barCode + "]不在装配列表中！");
        }

        if (isAssemble.equals("GREEN")) {
            throw new BaseException("物料[" + item + "]已装配完成，无需再进行装配！");
        }
        //装配
        if (inv.getQtyOnHand().doubleValue() <= 0) {
            throw new BaseException("物料条码[" + barCode + "]已无库存数量，无法装配！");
        }
        //标准物料消耗
        AssembleComponentsRequest assembleComponentsRequest = new AssembleComponentsRequest();
        List<AssemblyComponent> componentList = new ArrayList<AssemblyComponent>();
        List<AssemblyDataField> adf = new ArrayList<>();
        AssemblyComponent ac = new AssemblyComponent();
        String[] str = {"INVENTORY_ID_SFC", "SLOT_QTY"};
        for (int j = 0; j < str.length; j++) {
            AssemblyDataField ad = new AssemblyDataField();
            ad.setAttribute(str[j]);
            String value = inv.getInventoryId();
            if ("SLOT_QTY".equals(str[j])) {
                value = String.valueOf(assembleQty);
            }
            ad.setValue(value);
            adf.add(ad);
        }
        ac.setActualComponentRef(inv.getItemBo());
        ac.setTimeBased(false);
        ac.setBomComponentRef(bomCompBo);
        ac.setAssemblyDataFields(adf);
        ac.setQty(assembleQty);
        ac.setSetErpSentFlag(false);
        componentList.add(ac);

        assembleComponentsRequest.setResourceRef("ResourceBO:" + site + "," + sfcDataMain.getResrce());
        assembleComponentsRequest.setStepId(sfcDataMain.getStepId());
        String operationBo = operationService.getCurrentRevisionRef(site, sfcDataMain.getOperation()).getHandle();
        assembleComponentsRequest.setOperationRef(operationBo);
        assembleComponentsRequest.setEvent("baseFinished:AssemblyPoint");
        assembleComponentsRequest.setComponentList(componentList);
        assembleComponentsRequest.setSfcRef("SFCBO:" + site + "," + sfc);
        try {
            AssemblyServiceInterface assemblyService = null;
            assemblyService = MEServices.create("com.sap.me.production", "AssemblyService", site);
            assemblyService.assembleByComponents(assembleComponentsRequest);
        } catch (Exception e) {
            ExceptionUtil.throwException(e);
        }


        SfcDataAssemble assemble = new SfcDataAssemble();
        assemble.setHandle("SfcDataAssembleBO:" + site + "," + UUID.randomUUID().toString());
        assemble.setSite(site);
        assemble.setSfcDispatchBo(sfcDispatchBo);
        assemble.setStatus("A");
        assemble.setInventoryBo(inv.getHandle());
        assemble.setSeq(seq);
        assemble.setItemBo(inv.getItemBo());
        assemble.setAssembleQty(assembleQty);
        assemble.setCreatedUser(user);
        assemble.setCreatedDateTime(LocalDateTime.now());
        assemble.setModifiedDateTime(LocalDateTime.now());
        assemble.setModifyUser(user);
        sfcDataAssembleMapper.insert(assemble);

        return null;
    }


}