package com.sw.mes.yb.production.service.impl;


import com.sw.mes.base.factory.inspect.dto.BatchOutgoMarkOperateInfoDto;
import com.sw.mes.base.workinprocess.entity.WipStorage;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import com.sw.mes.core.api.system.FbFeignClients;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.FbCheckOutRecordDto;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.response.Result;
import com.sw.mes.inspect.entity.YbInspectData;
import com.sw.mes.inspect.service.YbInspectDataService;
import com.sw.mes.utils.StringUtils;
import com.sw.mes.yb.pad.entity.SectionNoDetail;
import com.sw.mes.yb.pad.service.SectionNoDetailService;
import com.sw.mes.yb.production.dao.OutgoMarkOperateDao;
import com.sw.mes.yb.production.dto.BatchOutgoMarkOperateDto;
import com.sw.mes.yb.production.dto.CrystalBatchInfoDto;
import com.sw.mes.yb.production.dto.OutgoMarkOperateDto;
import com.sw.mes.yb.production.entity.OutgoMarkOperate;
import com.sw.mes.yb.production.service.OutgoMarkOperateService;
import org.apache.commons.collections.CollectionUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class OutgoMarkOperateServiceImpl extends BaseServiceImpl<OutgoMarkOperate> implements OutgoMarkOperateService {
    OutgoMarkOperateDao dao;

    @Autowired
    private WipStorageService wipStorageService;

    @Autowired
    private ModelMapper modelMapper;


    @Autowired
    private SectionNoDetailService sectionNoDetailService;

    @Autowired
    private YbInspectDataService ybInspectDataService;

    @Autowired
    private FbFeignClients fbFeignClients;

    @Autowired
    public void setDao(OutgoMarkOperateDao dao) {
        super.setBaseDao(dao);
        this.dao = dao;
    }

    @Override
    public void batchOutgoMarkOperate(BatchOutgoMarkOperateInfoDto batchOperationDto) {
        if (CollectionUtils.isEmpty(batchOperationDto.getIdList())) {
            throw new RuntimeException("外发标识Id集合为空！");
        }
        Date date = new Date();
        ArrayList<String> fbSectionList = new ArrayList<>();
        ArrayList<String> ybCrystalNoList = new ArrayList<>();
        for (Long id : batchOperationDto.getIdList()) {
            OutgoMarkOperate outgoMarkOperate = this.get(id);
            if (null == outgoMarkOperate) {
                throw new RuntimeException("原外发标识不存在！");
            }
            if (batchOperationDto.getOperateStatus() == 2) {
                this.delete(id);
            } else {
                WipStorage wipStorage = null;
                if (null != outgoMarkOperate.getStickMark()) {
                    if (outgoMarkOperate.getStickMark() == 1) {
                        wipStorage = wipStorageService.findByProcessingOrderCode(outgoMarkOperate.getSectionNo(), Arrays.asList(EnumValuesFactory.WipStorageStatus.已进站.getKey(), EnumValuesFactory.WipStorageStatus.已出站.getKey()));
                    } else if (outgoMarkOperate.getStickMark() == 0) {
                        wipStorage = wipStorageService.findByProcessingOrderCodeLike(outgoMarkOperate.getCrystalNo() + "%", Arrays.asList(EnumValuesFactory.WipStorageStatus.已进站.getKey(), EnumValuesFactory.WipStorageStatus.已出站.getKey()));
                    }
                }
                if (batchOperationDto.getOperateStatus() == 1) {
                    //方棒检验进站后，不允许解除外发标识
                    if (null != wipStorage && StringUtils.equals(EnumValuesFactory.WipStorageCode.方棒检验.getValue(), wipStorage.getProcessName())
                            && wipStorage.getStatus() == EnumValuesFactory.WipStorageStatus.已进站.getKey()
                            && wipStorage.getStatus() == EnumValuesFactory.WipStorageStatus.已出站.getKey()) {
                        throw new RuntimeException("方棒检验进站后，不允许解除外发标识！");
                    }
                    outgoMarkOperate.setSecureRemark(batchOperationDto.getRemark());
                    outgoMarkOperate.setSecureTime(date);
                    outgoMarkOperate.setSecureUser(BaseContextHandler.getUsername());

                } else if (batchOperationDto.getOperateStatus() == 0) {
                    //晶段在磨削出站-方棒检验待进站前可操作外发标识，方棒检验进站后不允许指定
                    if (null != wipStorage && StringUtils.equals(EnumValuesFactory.WipStorageCode.方棒检验.getValue(), wipStorage.getProcessName())) {
                        throw new RuntimeException("方棒检验进站后，不允许触发外发标识！");
                    }
                    outgoMarkOperate.setOperateRemark(batchOperationDto.getRemark());
                    outgoMarkOperate.setOperateTime(date);
                    outgoMarkOperate.setOperateUser(BaseContextHandler.getUsername());
                }
                outgoMarkOperate.setStatus(batchOperationDto.getOperateStatus());
                this.saveOrUpdate(outgoMarkOperate);
                fbSectionList.add(outgoMarkOperate.getSectionNo());
                ybCrystalNoList.add(outgoMarkOperate.getCrystalNo());
            }
        }

        //        圆棒
        if (CollectionUtils.isNotEmpty(ybCrystalNoList)) {
            //创建成功之后需要把子棒晶段全部赋值外发标识属性
            List<YbInspectData> ybInspectDataList = ybInspectDataService.findByCrystalNo(ybCrystalNoList);
            if (CollectionUtils.isNotEmpty(ybInspectDataList)) {
                for (YbInspectData ybInspectData : ybInspectDataList) {
                    ybInspectData.setOutGoing(0);
                    ybInspectDataService.saveOrUpdate(ybInspectData);
                }
            }
        }
        //        方棒
        if (CollectionUtils.isNotEmpty(fbSectionList)) {
            //创建成功之后需要把子棒晶段全部赋值外发标识属性
            Result<List<FbCheckOutRecordDto>> result = fbFeignClients.findBySectionNoList(fbSectionList);
            if (result.getCode() == 200 && CollectionUtils.isNotEmpty(result.getData())) {
                ArrayList<FbCheckOutRecordDto> checkOutRecordDtoArrayList = new ArrayList<>();
                List<FbCheckOutRecordDto> fbCheckOutRecordDtoList = result.getData();
                for (FbCheckOutRecordDto dto : fbCheckOutRecordDtoList) {
                    dto.setOutGoing(0);
                    checkOutRecordDtoArrayList.add(dto);
                }
                if (CollectionUtils.isNotEmpty(checkOutRecordDtoArrayList)) {
                    fbFeignClients.saveOrUpdateFbCheckOutRecord(checkOutRecordDtoArrayList);
                }
            }
        }
    }

    @Override
    public void batchCreateOutgoMarkOperate(BatchOutgoMarkOperateDto batchOutgoMarkOperateDto) {

        if (CollectionUtils.isEmpty(batchOutgoMarkOperateDto.getBatchInfoDtoList())) {
            throw new RuntimeException("操作单晶不能为空！");
        }
        List<OutgoMarkOperate> saveOutgoMarkOperateList = new ArrayList<>();
        Date date = new Date();
        String username = BaseContextHandler.getUsername();
        for (CrystalBatchInfoDto crystalBatchInfoDto : batchOutgoMarkOperateDto.getBatchInfoDtoList()) {
            OutgoMarkOperate outgoMarkOperate = modelMapper.map(crystalBatchInfoDto, OutgoMarkOperate.class);
            String sectionNo = outgoMarkOperate.getSectionNo();
            if (StringUtils.isBlank(sectionNo)) {
                throw new RuntimeException("单晶编号不能为空！");
            }
//            重复数据校验
            OutgoMarkOperate outgoMarkOperateDb = dao.findByCrystalNoAndSectionNo(crystalBatchInfoDto.getCrystalNo(), crystalBatchInfoDto.getSectionNo());
            if (Objects.nonNull(outgoMarkOperateDb)){
                throw new RuntimeException("该晶段编号:"+crystalBatchInfoDto.getSectionNo()+"和母棒编号:"+crystalBatchInfoDto.getCrystalNo()+"已存在，请检查数据");
            }
            List<WipStorage> byProcessingByOrderCode = wipStorageService.findByProcessingByOrderCode(sectionNo);
            if (CollectionUtils.isEmpty(byProcessingByOrderCode)) {
                throw new RuntimeException("单晶站点信息为空！");
            }
            WipStorage wipStorage = byProcessingByOrderCode.get(0);
            //		磨削出站-方棒检验待进站可以操作外发标识；方棒检验进站后不允许操作
            if (crystalBatchInfoDto.getSiteStatus() != EnumValuesFactory.WipStorageStatus.待进站.getKey()
                    && !StringUtils.equals(EnumValuesFactory.WipStorageCode.方棒检验.getValue(), wipStorage.getProcessName())
                    && !StringUtils.equals(EnumValuesFactory.WipStorageCode.磨倒.getValue(), wipStorage.getProcessName())) {
                throw new RuntimeException("晶段在磨削出站-方棒检验带进站之后不能操作外发标识");
            }
            if (StringUtils.equals(EnumValuesFactory.WipStorageCode.送验.getValue(), wipStorage.getProcessName())) {
                outgoMarkOperate.setStickMark(0);
            } else {
                outgoMarkOperate.setStickMark(1);
            }
            outgoMarkOperate.setSiteStatus(wipStorage.getStatus());
            outgoMarkOperate.setOperateRemark(batchOutgoMarkOperateDto.getOperateRemark());
            outgoMarkOperate.setOperateTime(date);
            outgoMarkOperate.setOperateUser(username);
            outgoMarkOperate.setStatus(0);
            saveOutgoMarkOperateList.add(outgoMarkOperate);
        }
        ArrayList<String> ybCrystalNoList = new ArrayList<>();
        ArrayList<String> fbSectionList = new ArrayList<>();
        if (saveOutgoMarkOperateList.size() != 0) {
            this.saveAll(saveOutgoMarkOperateList);
            for (OutgoMarkOperate outgoMarkOperate : saveOutgoMarkOperateList) {
                ybCrystalNoList.add(outgoMarkOperate.getCrystalNo());
                fbSectionList.add(outgoMarkOperate.getSectionNo());
            }
        }
//        圆棒
        if (CollectionUtils.isNotEmpty(ybCrystalNoList)) {
            //创建成功之后需要把子棒晶段全部赋值外发标识属性
            List<YbInspectData> ybInspectDataList = ybInspectDataService.findByCrystalNo(ybCrystalNoList);
            if (CollectionUtils.isNotEmpty(ybInspectDataList)) {
                for (YbInspectData ybInspectData : ybInspectDataList) {
                    ybInspectData.setOutGoing(1);
                    ybInspectDataService.saveOrUpdate(ybInspectData);
                }
            }
        }
//        方棒
        if (CollectionUtils.isNotEmpty(fbSectionList)) {
            //创建成功之后需要把子棒晶段全部赋值外发标识属性
            Result<List<FbCheckOutRecordDto>> result = fbFeignClients.findBySectionNoList(fbSectionList);
            if (result.getCode() == 200 && CollectionUtils.isNotEmpty(result.getData())) {
                ArrayList<FbCheckOutRecordDto> checkOutRecordDtoArrayList = new ArrayList<>();
                List<FbCheckOutRecordDto> fbCheckOutRecordDtoList = result.getData();
                for (FbCheckOutRecordDto dto : fbCheckOutRecordDtoList) {
                    dto.setOutGoing(1);
                    checkOutRecordDtoArrayList.add(dto);
                }
                if (CollectionUtils.isNotEmpty(checkOutRecordDtoArrayList)) {
                    fbFeignClients.saveOrUpdateFbCheckOutRecord(checkOutRecordDtoArrayList);
                }
            }
        }
    }

    @Override
    public OutgoMarkOperate findByCrystalNoAndStatus(String crystalNo, Integer status) {
        return dao.findByCrystalNoAndStatus(crystalNo, status);
    }

    @Override
    public OutgoMarkOperate findBySectionNoAndStatus(String sectionNo, Integer status) {
        return dao.findBySectionNoAndStatus(sectionNo, status);
    }

    @Override
    public OutgoMarkOperateDto judgeCrystalNoIsOutgo(String sectionNo) {

        if (StringUtils.isNotBlank(sectionNo)) {
            OutgoMarkOperate bySectionNoAndStatus = this.findBySectionNoAndStatus(sectionNo, 0);
            if (null != bySectionNoAndStatus) {
                return modelMapper.map(bySectionNoAndStatus, OutgoMarkOperateDto.class);
            }
            SectionNoDetail bySectionNo = sectionNoDetailService.findBySectionNo(sectionNo);
            if (null != bySectionNo && StringUtils.isNotBlank(bySectionNo.getCrystalNo())) {
                OutgoMarkOperate byCrystalNoAndStatus = this.findByCrystalNoAndStatus(bySectionNo.getCrystalNo(), 0);
                if (null != byCrystalNoAndStatus) {
                    return modelMapper.map(byCrystalNoAndStatus, OutgoMarkOperateDto.class);
                }
            }
        }
        return null;
    }
}
