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.enums.HandleEnum;
import com.foreverwin.mesnac.common.service.SfcDispatchCommonService;
import com.foreverwin.mesnac.common.util.ExceptionUtil;
import com.foreverwin.mesnac.common.util.StringUtil;
import com.foreverwin.mesnac.meapi.dto.RouterStepDto;
import com.foreverwin.mesnac.meapi.dto.SfcDto;
import com.foreverwin.mesnac.meapi.model.Router;
import com.foreverwin.mesnac.meapi.model.WorkCenter;
import com.foreverwin.mesnac.meapi.service.RouterService;
import com.foreverwin.mesnac.meapi.service.RouterStepService;
import com.foreverwin.mesnac.meapi.service.ShopOrderService;
import com.foreverwin.mesnac.meapi.service.WorkCenterService;
import com.foreverwin.mesnac.production.dto.SplitSfcDto;
import com.foreverwin.mesnac.production.mapper.SfcCrossMapper;
import com.foreverwin.mesnac.production.mapper.SplitSfcMapper;
import com.foreverwin.mesnac.production.model.SplitSfc;
import com.foreverwin.mesnac.production.model.StepOperation;
import com.foreverwin.mesnac.production.service.SplitSfcService;
import com.foreverwin.modular.core.exception.BaseException;
import com.foreverwin.modular.core.exception.BusinessException;
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.nonconformance.*;
import com.sap.me.production.SplitSerializeServiceInterface;
import com.sap.me.production.SplitSfcDetail;
import com.sap.me.production.SplitSfcRequest;
import com.sap.me.production.SplitSfcResponse;
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.ArrayList;
import java.util.Collection;
import java.util.List;
/**
 * <p>
 * 产品条码拆分表 服务实现类
 * </p>
 *
 * @author Philip
 * @since 2021-07-20
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class SplitSfcServiceImpl extends ServiceImpl<SplitSfcMapper, SplitSfc> implements SplitSfcService {


    @Autowired
    private SplitSfcMapper splitSfcMapper;
    @Autowired
    private SfcDispatchCommonService sfcDispatchCommonService;
    @Autowired
    private WorkCenterService workCenterService;
    @Autowired
    private ShopOrderService shopOrderService;
    @Autowired
    private RouterService routerService;
    @Autowired
    private RouterStepService routerStepService;
    @Autowired
    private SfcCrossMapper sfcCrossMapper;
    @Override
    public IPage<SplitSfc> selectPage(FrontPage<SplitSfc> frontPage, SplitSfc splitSfc) {
        QueryWrapper<SplitSfc> queryWrapper = new QueryWrapper<>();
        queryWrapper.setEntity(splitSfc);
        return super.page(frontPage.getPagePlus(), queryWrapper);
    }

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

    @Override
    public SfcDto getSfcData(SfcDto dto) {
        String site = CommonMethods.getSite();
        String handle = HandleEnum.SFC.getHandle(site, dto.getSfc());
        if (StringUtil.isBlank(dto.getSfc())){
            throw new BaseException("产品条码不能为空");
        }
        if (StringUtil.isBlank(dto.getAbnormalNo())){
            throw new BaseException("异常单号不能为空");
        }
        //根据sfc找工单等信息
        SfcDto sfcData = splitSfcMapper.getSfcData(handle);
        if (sfcData==null){
            throw new BaseException("未找到产品条码信息");
        }
        String operation = sfcData.getOperation();
        //查询质量异常记录数量
        SplitSfcDto sfcDto=splitSfcMapper.getAbnormalQty(site,dto.getSfc(),operation,dto.getAbnormalNo());
        if (sfcDto==null){
            throw new BaseException("未找到闭环关闭的质量异常");
        }
        sfcData.setQty(Double.valueOf(sfcDto.getNcQty()));
        sfcData.setAbnormalNo(sfcDto.getAbnormalNo());
        return sfcData;
    }
    @Override
    public SfcDto getGoodSfcData(String sfc) {
        String site = CommonMethods.getSite();
        String handle = HandleEnum.SFC.getHandle(site, sfc);
        //根据sfc找工单等信息
        SfcDto sfcData = splitSfcMapper.getSfcData(handle);
        if (sfcData==null){
            throw new BaseException("未找到产品条码信息");
        }
        if (!sfcData.getStatus().equals("401")&&!sfcData.getStatus().equals("402")){
            throw new BaseException("产品状态不可拆分");
        }
        if (sfcData.getQty()==1){
            throw new BaseException("数量为1不可拆分");
        }
        return sfcData;
    }
    @Override
    public SplitSfc goodSfcSplit(SfcDto sfcDto){
        String site = CommonMethods.getSite();
        String sfc = sfcDto.getSfc();
        BigDecimal splitQty = new BigDecimal(sfcDto.getQty());

        //根据sfc找工单等信息
        SfcDto sfcData =getGoodSfcData(sfc);
        if (sfcData==null){
            throw new BaseException("未找到产品条码信息");
        }
        String operation = sfcData.getOperation();
        SplitSfcRequest splitSfcRequest=new SplitSfcRequest();
        try {
            SplitSerializeServiceInterface splitService =  MEServices.create("com.sap.me.production", "SplitSerializeService",site);
            //拆sfc
            List<SplitSfcDetail> newList=new ArrayList<>();
            SplitSfcDetail splitDetail=new SplitSfcDetail();
            splitDetail.setQuantity(splitQty);
            newList.add(splitDetail);
            splitSfcRequest.setNewSfcList(newList);
            splitSfcRequest.setSfcRef(HandleEnum.SFC.getHandle(site,sfc));
            Collection<SplitSfcResponse> splitSfcResponses = splitService.splitSfc(splitSfcRequest);
            SplitSfcResponse splitSfcResponse = splitSfcResponses.iterator().next();
            String newSfcRef = splitSfcResponse.getNewSfcRef();

            SplitSfc splitSfc=new SplitSfc();
            String newSfc = StringUtil.trimHandle(newSfcRef);
            splitSfc.setHandle(HandleEnum.SPLIT_SFC.getHandle(site,newSfc));
            splitSfc.setSite(site);
            splitSfc.setSfc(sfc);
            splitSfc.setSplitSfc(newSfc);
            splitSfc.setSplitQty(splitQty);
            splitSfc.setCreateUser(CommonMethods.getUser());
            splitSfc.setCreatedDateTime(LocalDateTime.now());
            save(splitSfc);
            String workCenter = null;
            if (operation.contains("_")) {
                workCenter = operation.split("_")[0];
            } else {
                workCenter = operation;
            }
            String workCenterBo = HandleEnum.WORK_CENTER.getHandle(site, workCenter);
            WorkCenter workCenterModel = workCenterService.getById(workCenterBo);
            if (workCenterModel == null) {
                throw BusinessException.build("生产车间【" +workCenter+ "】不存在");
            }
            Router routerBySfcBo = routerService.getRouterBySfcBo(HandleEnum.SFC.getHandle(site, sfc));
            sfcDispatchCommonService.saveSfcDispatch(site,CommonMethods.getUser(),workCenter,newSfc, sfcData.getShopOrder(),routerBySfcBo.getHandle());
            return splitSfc;
        } catch (Exception e) {
            ExceptionUtil.throwException(e);
        }
        return null;
    }
    @Override
    public SplitSfc splitSfc(SfcDto sfcDto){
        String site = CommonMethods.getSite();
        String sfc = sfcDto.getSfc();
        String abnormalNo = sfcDto.getAbnormalNo();
        if (StringUtil.isBlank(abnormalNo)){
            throw new BaseException("异常单号不能为空");
        }
        String handle = HandleEnum.SFC.getHandle(site, sfc);
        BigDecimal splitQty = new BigDecimal(sfcDto.getQty());

        //根据sfc找工单等信息
        SfcDto sfcData = splitSfcMapper.getSfcData(handle);
        String operation = sfcData.getOperation();
        if (sfcData==null){
            throw new BaseException("未找到产品条码信息");
        }
        //查询质量异常记录数量 处置工艺路线及不良代码
        SplitSfcDto splitSfcDto=splitSfcMapper.getAbnormalQty(site,sfc,operation, abnormalNo);
        String routerBo = splitSfcDto.getRouterBo();
        String ncCode = splitSfcDto.getNcCode();
        if (StringUtil.isBlank(ncCode)){
            throw new BaseException("异常处置未选择不良代码");
        }
        BigDecimal sfcQty = new BigDecimal(sfcData.getQty());
        if (new BigDecimal(splitSfcDto.getNcQty()).compareTo(sfcQty)>=0){
            throw new BaseException("质量异常数量大于等于于产品条码的数量，不能拆分");
        }
        if (splitQty.compareTo(new BigDecimal(splitSfcDto.getNcQty()))>0){
            throw new BaseException("拆分数量大于质量异常数量的数量，不能拆分");
        }
        String[] splitNcCode = ncCode.split(",");

        SplitSfcRequest splitSfcRequest=new SplitSfcRequest();
        try {
            SplitSerializeServiceInterface splitService =  MEServices.create("com.sap.me.production", "SplitSerializeService",site);
            NCProductionServiceInterface ncProductionService =  MEServices.create("com.sap.me.nonconformance", "NCProductionService",site);
            //拆sfc
            List<SplitSfcDetail> newList=new ArrayList<>();
            SplitSfcDetail splitDetail=new SplitSfcDetail();
            splitDetail.setQuantity(splitQty);
            newList.add(splitDetail);
            splitSfcRequest.setNewSfcList(newList);
            splitSfcRequest.setSfcRef(HandleEnum.SFC.getHandle(site,sfc));
            Collection<SplitSfcResponse> splitSfcResponses = splitService.splitSfc(splitSfcRequest);
            SplitSfcResponse splitSfcResponse = splitSfcResponses.iterator().next();
            String newSfcRef = splitSfcResponse.getNewSfcRef();
            String newSfc = StringUtil.trimHandle(newSfcRef);

            if(StringUtil.notBlank(routerBo)){
                //记录不合格
                CreateNCRequest createNCRequest=new CreateNCRequest();
                createNCRequest.setQty(splitQty);
                createNCRequest.setSfcRef(newSfcRef);
                ProductionContext productionContext=new ProductionContext();
                StepIdentifier stepIdentifier=new StepIdentifier();
                stepIdentifier.setStepId(sfcData.getStepId());
                stepIdentifier.setOperationId(sfcData.getOperation());
                productionContext.setStepIdentifier(stepIdentifier);
                List<StepOperation> resourceBySfc = sfcCrossMapper.getResourceBySfc(site, sfc);
                if (resourceBySfc.isEmpty()){
                    throw new BaseException("产品不在工作中");
                }
                productionContext.setResourceRef(resourceBySfc.get(0).getResourceBo());
                createNCRequest.setProdCtx(productionContext);
                createNCRequest.setNcCodeRef(HandleEnum.NC_CODE.getHandle(site,splitNcCode[0]));
                ncProductionService.createNC(createNCRequest);
                //不合格处置特殊工艺路线
                DispositionMultipleSfcsRequest dispositionSfcsRequest=new DispositionMultipleSfcsRequest();
                List<String> sfcs=new ArrayList<>();
                sfcs.add(newSfcRef);
                dispositionSfcsRequest.setSfcs(sfcs);
                dispositionSfcsRequest.setBypassStepValidation(true);
                DispositionSelection dispositionSelection=new DispositionSelection();
                Router maxRevisionRouter = routerService.getMaxRevisionRouter(site, StringUtil.trimHandle(routerBo));
                dispositionSelection.setRouterRef(maxRevisionRouter.getHandle());
                dispositionSfcsRequest.setDispositionSelection(dispositionSelection);
                dispositionSfcsRequest.setProdCtx(new ProductionContext());
                ncProductionService.dispositionMultipleSfcs(dispositionSfcsRequest);
                String workCenter;
                List<RouterStepDto> routerOperationByRouterBo = routerStepService.findRouterOperationByRouterBo(site, maxRevisionRouter.getHandle());
                if (routerOperationByRouterBo.isEmpty()){
                    throw new BaseException("处置工艺路线没有步骤");
                }
                String routerOperation = routerOperationByRouterBo.get(0).getOperation();
                if (routerOperation.contains("_")) {
                    workCenter = routerOperation.split("_")[0];
                } else {
                    workCenter = routerOperation;
                }
                String workCenterBo = HandleEnum.WORK_CENTER.getHandle(site, workCenter);
                WorkCenter workCenterModel = workCenterService.getById(workCenterBo);
                if (workCenterModel == null) {
                    throw BusinessException.build("生产车间【" +workCenter+ "】不存在");
                }
                sfcDispatchCommonService.saveSfcDispatch(site,CommonMethods.getUser(),workCenter,newSfc, sfcData.getShopOrder(),maxRevisionRouter.getHandle());
            }
            SplitSfc splitSfc=new SplitSfc();
            splitSfc.setHandle(HandleEnum.SPLIT_SFC.getHandle(site,newSfc));
            splitSfc.setSite(site);
            splitSfc.setSfc(sfc);
            splitSfc.setSplitSfc(newSfc);
            splitSfc.setSplitQty(splitQty);
            splitSfc.setRouter(StringUtil.trimHandle(routerBo));
            splitSfc.setCreateUser(CommonMethods.getUser());
            splitSfc.setCreatedDateTime(LocalDateTime.now());
            save(splitSfc);
            return splitSfc;
        } catch (Exception e) {
            ExceptionUtil.throwException(e);
        }
        return null;
    }

}