package com.fizz.business.service.strip;

import com.fizz.business.constants.enums.DeviceEnum;
import com.fizz.business.domain.msg.AppMeasureEntryMessage;
import com.fizz.business.domain.msg.AppMeasureExitMessage;
import org.springframework.stereotype.Service;


import java.math.BigDecimal;

/**
 * 位置计算服务 —— 根据 entry.stripLocation（焊机参考）和活套长度动态判断设备的比较位置
 */
@Service
public class StripPositionService {

    /**
     * 计算设备在 entry 坐标系的“比较位置”
     *
     * 规则：
     * - device.basePosition < ENL_MIN : 不加活套
     * - ENL_MIN <= device.basePosition < CXL_MIN : 加 celLength
     * - >= CXL_MIN : 加 cxlLength
     */
    public double calculate(DeviceEnum device, BigDecimal celLength, BigDecimal cxlLength) {
        double base = device.getBasePosition();
        double cel = celLength == null ? 0.0 : celLength.doubleValue();
        double cxl = cxlLength == null ? 0.0 : cxlLength.doubleValue();

        double enlMin = findEnlMin();
        double cxlMin = findCxlMin();

        if (base < enlMin) {
            return base;
        } else if (base < cxlMin) {
            return base + cel;
        } else {
            return base + cxl;
        }
    }

    public double calculate(DeviceEnum device,AppMeasureEntryMessage entry,
                            AppMeasureExitMessage exit) {
        BigDecimal cel = entry == null ? null : entry.getCelLength();
        BigDecimal cxl = exit == null ? null : exit.getCxlLength();
        return calculate(device, cel, cxl);
    }

    private double findEnlMin() {
        double min = Double.MAX_VALUE;
        for (DeviceEnum d : DeviceEnum.values()) {
            if (d.name().startsWith("ENL")) {
                min = Math.min(min, d.getBasePosition());
            }
        }
        return min == Double.MAX_VALUE ? 0.0 : min;
    }

    private double findCxlMin() {
        double min = Double.MAX_VALUE;
        for (DeviceEnum d : DeviceEnum.values()) {
            if (d.name().startsWith("CXL")) {
                min = Math.min(min, d.getBasePosition());
            }
        }
        return min == Double.MAX_VALUE ? Double.MAX_VALUE : min;
    }
}