package com.yeejoin.amos.fas.business.util;

import com.yeejoin.amos.fas.business.bo.RpnCalculationBo;
import com.yeejoin.amos.fas.common.enums.RpnChangeLogTypeEum;
import com.yeejoin.amos.fas.dao.entity.Fmea;
import com.yeejoin.amos.fas.dao.entity.FmeaEquipmentPoint;
import com.yeejoin.amos.fas.dao.entity.FmeaPointInputitem;
import com.yeejoin.amos.fas.dao.entity.RiskLevel;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author DELL
 */
public class RpnUtils {
    /**
     * 计算风险值
     *
     * @param fmeas
     * @return RpnCalculationBo
     */
    public static RpnCalculationBo calRpnAndRpni(List<Fmea> fmeas) {
        BigDecimal maxSidValue = new BigDecimal("0");
        BigDecimal maxDidValue = new BigDecimal("0");
        BigDecimal totalOidValue = new BigDecimal("0");
        BigDecimal totalNewOidValue = new BigDecimal("0");
        long count = 0L;
        for (Fmea fmea : fmeas) {
            if (fmea.getEvaluationDid() != null && fmea.getEvaluationSid() != null && fmea.getEvaluationOid() != null && fmea.getNewEvaluationOid() != null) {
                BigDecimal didValue = new BigDecimal(fmea.getDidValue());
                BigDecimal sidValue = new BigDecimal(fmea.getSidValue());
                BigDecimal oidValue = new BigDecimal(fmea.getOidValue());
                BigDecimal newOidValue = new BigDecimal(fmea.getNewOidValue());
                if (didValue.compareTo(maxDidValue) == 1) {
                    maxDidValue = didValue;
                }
                if (sidValue.compareTo(maxSidValue) == 1) {
                    maxSidValue = sidValue;
                }
                totalOidValue = totalOidValue.add(oidValue);
                totalNewOidValue = totalNewOidValue.add(newOidValue);
                count++;
            }
        }
        RpnCalculationBo rpnValue = new RpnCalculationBo();
        rpnValue.setSize(count);
        if (count == 0) {
            return rpnValue;
        }
        BigDecimal averageOidValue = totalOidValue.divide(BigDecimal.valueOf(count), 2, BigDecimal.ROUND_HALF_UP);
        BigDecimal averageNewOidValue = totalNewOidValue.divide(BigDecimal.valueOf(count), 2, BigDecimal.ROUND_HALF_UP);
        BigDecimal rpn = maxDidValue.multiply(maxSidValue).multiply(averageNewOidValue).setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal rpni = maxDidValue.multiply(maxSidValue).multiply(averageOidValue).setScale(2, BigDecimal.ROUND_HALF_UP);
        rpnValue.setRpn(rpn);
        rpnValue.setRpni(rpni);
        return rpnValue;
    }

    /**
     * 计算最大故障率
     *
     * @param equipmentPoints
     * @param pointInputitems
     * @return
     */
    public static Double getMaxRate(List<FmeaEquipmentPoint> equipmentPoints, List<FmeaPointInputitem> pointInputitems) {
        Double pointInputitemRate = null;
        if (!CollectionUtils.isEmpty(pointInputitems)) {
            int totalPointInputitem = pointInputitems.size();
            int pointInputitemUnNormal = 0;
            for (FmeaPointInputitem pointInputitem : pointInputitems) {
                if (pointInputitem.getState() == 1) {
                    pointInputitemUnNormal++;
                }
            }
            pointInputitemRate = pointInputitemUnNormal * 1.0 / totalPointInputitem;
        }
        Double equipmentPointRate = null;
        if (!CollectionUtils.isEmpty(equipmentPoints)) {
            int totalEquipmentPoint = equipmentPoints.size();
            int equipmentPointUnNormal = 0;
            for (FmeaEquipmentPoint equipmentPoint : equipmentPoints) {
                if (equipmentPoint.getState() == 1) {
                    equipmentPointUnNormal++;
                }
            }
            equipmentPointRate = equipmentPointUnNormal * 1.0 / totalEquipmentPoint;
        }
        if (equipmentPointRate == null) {
            if (pointInputitemRate == null) {
                return null;
            } else {
                return pointInputitemRate;
            }
        } else {
            if (pointInputitemRate == null) {
                return equipmentPointRate;
            } else {
                if (pointInputitemRate < equipmentPointRate) {
                    return equipmentPointRate;
                } else {
                    return pointInputitemRate;
                }
            }
        }
    }

    /**
     * 获得风险等级
     *
     * @param rpni
     * @param levels
     * @return
     */
    public static RiskLevel getBetweenLevel(BigDecimal rpni, List<RiskLevel> levels) {
        if (CollectionUtils.isEmpty(levels)) {
            return null;
        }
        for (RiskLevel level : levels) {
            int downResult = level.getDownLimit().compareTo(rpni);
            int topResult = level.getTopLimit().compareTo(rpni);
            if (downResult == -1 && topResult != -1) {
                return level;
            }
        }
        return null;
    }

    /**
     * 获取风险变化类型
     *
     * @param rpn 实时
     * @param rpni 固有
     * @return int
     */
    public static int getChangeType(BigDecimal rpn, BigDecimal rpni) {
        if (rpn.subtract(rpni).doubleValue() > 0) {
            return RpnChangeLogTypeEum.upper.getCode();
        } else if (rpn.subtract(rpni).doubleValue() < 0) {
            return RpnChangeLogTypeEum.down.getCode();
        } else {
            return RpnChangeLogTypeEum.unChange.getCode();
        }

    }

    /**
     *  计算变化类型
     * @param oldLevel 原有等级
     * @param newLevel 现有等级
     * @return up、no、down
     */
    public static String calChangeTypeByLevel(Integer oldLevel, Integer newLevel){
        int level = oldLevel - newLevel;
        String changeType;
        if (level > 0) {
            changeType = "up";
        } else if (level == 0) {
            changeType = "no";
        } else {
            changeType = "down";
        }
        return changeType;
    }

    /**
     * 计算闪烁频率
     * @param rpnr 实时
     * @param rpni 固有
     * @param changeType 变化类型
     * @return int
     */
    public static int calRiskPointFrequency(BigDecimal rpnr,BigDecimal rpni, String changeType) {
        BigDecimal rg = rpnr.subtract(rpni);
        int frequency = 0;
        if ("up".equals(changeType) && rg.intValue() > 0) {
            frequency = 3;
        } else if ("no".equals(changeType) && rg.intValue() > 0) {
            frequency = 1;
        }
        return frequency;
    }
}
