package com.usky.vpp.util;

import com.usky.vpp.enums.ElectricSeasonEnum;
import com.usky.vpp.enums.TimeSegmentEnum;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 分时电费计算（平段基准价 × 季节浮动系数 × 电量）
 */
public final class ElectricFeeCalcUtil {

    private static final BigDecimal PEAK_RATE_SUMMER_WINTER = new BigDecimal("1.50");
    private static final BigDecimal PEAK_RATE_NORMAL = new BigDecimal("1.30");
    private static final int SCALE = 4;

    private ElectricFeeCalcUtil() {
    }

    public static BigDecimal calcSegmentFee(BigDecimal flatUnitPrice,
                                            ElectricSeasonEnum season,
                                            TimeSegmentEnum segment,
                                            BigDecimal useKwh) {
        if (flatUnitPrice == null || useKwh == null || useKwh.compareTo(BigDecimal.ZERO) <= 0) {
            return BigDecimal.ZERO.setScale(SCALE, RoundingMode.HALF_UP);
        }
        BigDecimal segUnitPrice = resolveSegmentUnitPrice(flatUnitPrice, season, segment);
        return segUnitPrice.multiply(useKwh).setScale(SCALE, RoundingMode.HALF_UP);
    }

    public static BigDecimal resolveSegmentUnitPrice(BigDecimal flatUnitPrice,
                                                     ElectricSeasonEnum season,
                                                     TimeSegmentEnum segment) {
        if (flatUnitPrice == null || segment == null) {
            return BigDecimal.ZERO;
        }
        switch (segment) {
            case FLAT:
                return flatUnitPrice;
            case VALLEY:
                return flatUnitPrice.multiply(TimeSegmentEnum.VALLEY.getRateFactor());
            case PEAK:
                return flatUnitPrice.multiply(peakRate(season));
            case SPIKE:
                return flatUnitPrice.multiply(peakRate(season))
                        .multiply(TimeSegmentEnum.SPIKE.getRateFactor());
            default:
                throw new IllegalArgumentException("未知时段");
        }
    }

    private static BigDecimal peakRate(ElectricSeasonEnum season) {
        if (ElectricSeasonEnum.SUMMER == season || ElectricSeasonEnum.WINTER_SPIKE == season) {
            return PEAK_RATE_SUMMER_WINTER;
        }
        return PEAK_RATE_NORMAL;
    }
}
