package com.sw.mes.fb.aio.service.impl;


import com.sw.mes.core.annotation.ServiceLogs;
import com.sw.mes.core.api.system.YbFeignClients;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.config.rabbit.FbInspectDataBaseChangeAsync;
import com.sw.mes.base.factory.init.entity.FactoryModel;
import com.sw.mes.core.utils.MathUtils;
import com.sw.mes.core.utils.NumberUtil;
import com.sw.mes.fb.aio.dao.GrindingBlankingDao;
import com.sw.mes.fb.aio.entity.GrindingBlanking;
import com.sw.mes.fb.aio.service.GrindingBlankingService;
import com.sw.mes.fb.checkout.dao.RecutDetailDao;
import com.sw.mes.base.workinprocess.entity.PlanProcessingOrder;
import com.sw.mes.base.workinprocess.service.PlanProcessingOrderService;
import com.sw.mes.base.workinprocess.service.WipStorageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Slf4j
@Service
@Transactional
public class GrindingBlankingServiceImpl extends BaseServiceImpl<GrindingBlanking> implements GrindingBlankingService {
    GrindingBlankingDao dao;

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

    @Autowired
    private RecutDetailDao recutDetailDao;
    @Autowired
    private WipStorageService wipStorageService;
    @Autowired
    private YbFeignClients ybFeignClients;
    @Autowired
    private PlanProcessingOrderService planProcessingOrderService;
    @Autowired
    private FbInspectDataBaseChangeAsync fbInspectDataBaseChangeAsync;

    @Override
    public void save(GrindingBlanking grindingBlanking) {
        List<PlanProcessingOrder> planProcessingOrders = planProcessingOrderService.findByCodeOrderByIdDesc(grindingBlanking.getSn());
//        if (planProcessingOrders.size() == 0) {
//            throw new BusinessException("工单号【" + grindingBlanking.getSn() + "】不存在");
//        }
        if(!planProcessingOrders.isEmpty()) {
            PlanProcessingOrder planProcessingOrder = planProcessingOrders.get(0);
            if (null != planProcessingOrder && planProcessingOrder.getStatus() == EnumValuesFactory.PlanProcessingOrderStatus.加工中.getKey()) {
                // 查询加工工单信息，判断是否是本站点的加工品
                FactoryModel factoryModel = wipStorageService.getFactoryModel(planProcessingOrder.getWipStorage().getProcessId(), planProcessingOrder.getWipStorage().getProcessName());
                if (factoryModel.getCode().equals(EnumValuesFactory.WipStorageCode.开方.getKey()) &&
                        planProcessingOrder.getWipStorage().getStatus() == EnumValuesFactory.WipStorageStatus.已进站.getKey()
                ) {
                    Result outResult = ybFeignClients.outStation(grindingBlanking.getSn(), EnumValuesFactory.WipStorageCode.开方.getKey(), "A", null);
                    if (outResult.getCode() != ResultCode.SUCCESS.getCode()) {
                        log.error(outResult.getMessage());
                    }
                }
            }
        }
        saveOrUpdate(grindingBlanking);
    }

    @Override
    public void saveOrUpdate(GrindingBlanking grindingBlanking) {
        super.saveOrUpdate(grindingBlanking);
        // SPC异步获取磨削数据
        //fbInspectDataBaseChangeAsync.sendData(grindingBlanking);
    }

    @Override
    public GrindingBlanking findTopByFbSectionNoOrderByIdDesc(String fbSectionNo) {
        return dao.findTopByFbSectionNoOrderByIdDesc(fbSectionNo);
    }

    @Override
    public GrindingBlanking findByEquipNo(String equipNo) {
        return dao.findByEquipNo(equipNo);
    }

    @Override
    @ServiceLogs(description = "计算方棒边长直径")
    public Map<String,Object> calculate(GrindingBlanking eapGrindingRack) {

        Map<String,Object> map = new HashMap<>();
        map.put("sn",eapGrindingRack.getSn());
        try {

            List<BigDecimal> list = new ArrayList<>();
            list.add(eapGrindingRack.getSide1());
            list.add(eapGrindingRack.getSide2());
            list.add(eapGrindingRack.getSide3());
            list.add(eapGrindingRack.getSide4());
            list.add(eapGrindingRack.getSide5());
            list.add(eapGrindingRack.getSide6());
            list.add(eapGrindingRack.getSide7());
            list.add(eapGrindingRack.getSide8());
            list.add(eapGrindingRack.getSide9());
            BigDecimal maxSide = list.stream().filter(Objects::nonNull).max(BigDecimal::compareTo).get();
            BigDecimal mixSide = list.stream().filter(Objects::nonNull).min(BigDecimal::compareTo).get();
            map.put("maxSide", maxSide);
            map.put("mixSide", mixSide);

            List<BigDecimal> list1 = new ArrayList<>();
            list1.add(eapGrindingRack.getSide10());
            list1.add(eapGrindingRack.getSide11());
            list1.add(eapGrindingRack.getSide12());
            list1.add(eapGrindingRack.getSide13());
            list1.add(eapGrindingRack.getAfterhead1());
            list1.add(eapGrindingRack.getAfterhead2());
            list1.add(eapGrindingRack.getAfterhead3());
            list1.add(eapGrindingRack.getAfterhead4());
            list1.add(eapGrindingRack.getAftertail1());
            BigDecimal maxSide1 = list1.stream().filter(Objects::nonNull).max(BigDecimal::compareTo).get();
            BigDecimal mixSide1 = list1.stream().filter(Objects::nonNull).min(BigDecimal::compareTo).get();
            map.put("maxSide1", maxSide1);
            map.put("mixSide1", mixSide1);


            List<BigDecimal> list2 = new ArrayList<>();
            list2.add(maxSide);
            list2.add(mixSide);
            list2.add(maxSide1);
            list2.add(mixSide1);
            // 边距最大值
            BigDecimal maxSide2 = list2.stream().filter(Objects::nonNull).max(BigDecimal::compareTo).get();
            // 边距最小值
            BigDecimal minSide2 = list2.stream().filter(Objects::nonNull).min(BigDecimal::compareTo).get();
            eapGrindingRack.setBeforhud12(maxSide2);
            eapGrindingRack.setBeforhdd12(minSide2);
            map.put("边距最大值", maxSide2);
            map.put("边距最小值", minSide2);


            List<BigDecimal> list3 = new ArrayList<>();
            list3.add(eapGrindingRack.getAftertail2());
            list3.add(eapGrindingRack.getAftertail3());
            list3.add(eapGrindingRack.getAftertail4());
            BigDecimal maxSide3 = list3.stream().filter(Objects::nonNull).max(BigDecimal::compareTo).get();
            BigDecimal mixSide3 = list3.stream().filter(Objects::nonNull).min(BigDecimal::compareTo).get();

            List<BigDecimal> list4 = new ArrayList<>();
            list4.add(eapGrindingRack.getHeadadd13());
            list4.add(eapGrindingRack.getHeadadd24());
            list4.add(eapGrindingRack.getTailadd13());
            BigDecimal maxSide4 = list4.stream().filter(Objects::nonNull).max(BigDecimal::compareTo).get();
            BigDecimal mixSide4 = list4.stream().filter(Objects::nonNull).min(BigDecimal::compareTo).get();

            List<BigDecimal> list5 = new ArrayList<>();
            list5.add(maxSide3);
            list5.add(mixSide3);
            list5.add(maxSide4);
            list5.add(mixSide4);
            // 直径最大值
            BigDecimal maxSide5 = list5.stream().filter(Objects::nonNull).max(BigDecimal::compareTo).get();
            // 直径最小值
            BigDecimal minSide5 = list5.stream().filter(Objects::nonNull).min(BigDecimal::compareTo).get();
            eapGrindingRack.setEapDiameterMax(maxSide5);
            eapGrindingRack.setEapDiameterMin(minSide5);
            map.put("直径最大值", maxSide5);
            map.put("直径最小值", minSide5);
            //
            List<BigDecimal> list6 = new ArrayList<>();
            list6.add(maxSide5);
            list6.add(minSide5);
            Double agv = list6.stream().filter(Objects::nonNull).mapToDouble(BigDecimal::doubleValue).average().getAsDouble();
            // 弧长投影最大值
            BigDecimal maxSide6 = NumberUtil.Object2BigDecimal(MathUtils.keepDecimalDigit4(0.5 * (maxSide2.doubleValue() - Math.sqrt(Math.pow(agv, 2) - Math.pow(maxSide2.doubleValue(), 2)))), null);
            // 弧长投影最小值
            BigDecimal minSide6 = NumberUtil.Object2BigDecimal(MathUtils.keepDecimalDigit4(0.5 * (minSide2.doubleValue() - Math.sqrt(Math.pow(agv, 2) - Math.pow(minSide2.doubleValue(), 2)))), null);
            eapGrindingRack.setBefortud12(maxSide6);
            eapGrindingRack.setBefortdd12(minSide6);
            map.put("弧长投影最大值", maxSide6);
            map.put("弧长投影最小值", minSide6);

            // 玄宽最大值
            BigDecimal maxSide7 = maxSide2.subtract(new BigDecimal("2").multiply(maxSide6));
            // 玄宽最小值
            BigDecimal minSide7 = minSide2.subtract(new BigDecimal("2").multiply(minSide6));
            eapGrindingRack.setBefortud34(maxSide7);
            eapGrindingRack.setBefortdd34(minSide7);
            map.put("玄宽最大值", maxSide7);
            map.put("玄宽最小值", minSide7);

            // 弧长最大值
            BigDecimal maxSide8 = NumberUtil.Object2BigDecimal(MathUtils.keepDecimalDigit4(maxSide6.multiply(new BigDecimal(Math.sqrt(2D)))),null);
            // 弧长最小值
            BigDecimal minSide8 = NumberUtil.Object2BigDecimal(MathUtils.keepDecimalDigit4(minSide6.multiply(new BigDecimal(Math.sqrt(2D)))),null);
            eapGrindingRack.setAfterhud12(maxSide8);
            eapGrindingRack.setAfterhdd12(minSide8);
            map.put("弧长最大值", maxSide8);
            map.put("弧长最小值", minSide8);
        } catch (Exception e){
          e.printStackTrace();
          map.put("异常",e.getMessage());
        }
        return map;
    }
}
