package com.aps.macroplanner.variable;

import com.google.ortools.linearsolver.MPSolver;
import com.aps.macroplanner.data.*;
import com.aps.macroplanner.model.MacroPlannerModel;

import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;

/**
 * 供应松弛变量构建器 — 创建 SupplyTargetQtyUnder, MinSupplyQtyUnder, MaxSupplyQtyOver 变量。
 *
 * <h3>SupplyTargetQtyUnder[specName]</h3>
 * <ul><li>含义: 供应目标不足的量</li><li>范围: [0, +∞)</li></ul>
 *
 * <h3>MinSupplyQtyUnder[specName]</h3>
 * <ul><li>含义: 最小供应不足的量</li><li>范围: [0, +∞)</li></ul>
 *
 * <h3>MaxSupplyQtyOver[specName]</h3>
 * <ul><li>含义: 最大供应超出的量</li><li>范围: [0, +∞)</li></ul>
 *
 * <p><b>注意:</b> 每个供应规格必须有唯一的名称, 否则会导致松弛变量被覆盖,
 * 多个约束共享同一个松弛变量, 造成数学模型错误。</p>
 */
public class SupplySlackVariableBuilder {

    private static final Logger LOG = Logger.getLogger(SupplySlackVariableBuilder.class.getName());

    public static void create(MacroPlannerModel model, TestDataBuilder data) {
        double inf = MPSolver.infinity();
        Set<String> seenNames = new HashSet<>();

        for (SupplySpec spec : data.getSupplySpecs()) {
            String name = spec.getName();

            // 检测重复名称: 如果已存在则覆盖, 导致多个约束共享同一个松弛变量
            if (!seenNames.add(name)) {
                LOG.warning(String.format(
                        "⚠️ 供应规格名称重复: '%s' 已存在! "
                                + "这将导致不同供应规格的约束共享同一个松弛变量, 造成数学模型错误。"
                                + "请确保每个 SupplySpec 有唯一的名称。",
                        name));
            }

            model.getSupplyTargetQtyUnderVars().put(name,
                    model.getSolver().makeNumVar(0.0, inf, "SupTargetUnder_" + name));
            model.getMinSupplyQtyUnderVars().put(name,
                    model.getSolver().makeNumVar(0.0, inf, "MinSupUnder_" + name));
            if (spec.hasMaxQuantity()) {
                model.getMaxSupplyQtyOverVars().put(name,
                        model.getSolver().makeNumVar(0.0, inf, "MaxSupOver_" + name));
            }
        }
    }
}