namespace Hc900Crawler.Infrastructure.Control;

public sealed record TempProfileResult(string State, string? InversionPair, double Span, double? SpanRef);

/// <summary>
/// §10 온도 프로파일 역전 판정 (순수함수). 입력=하단→상단 순서의 **조성 트레이** PCT
/// (환류 서브쿨 오염 탑정 D는 호출측에서 제외하고 전달). 정상=단조 감소(A≥B≥C).
/// 상태: 정상 / 약화 / 프로파일붕괴 / 온도역전 / 입력부족.
/// </summary>
public static class TempProfileJudge
{
    public static TempProfileResult Evaluate(
        IReadOnlyList<(string tag, double pct, bool good)> trays,
        double spanRef, double tolInv, double spanWarnFrac, double spanCollapseFrac)
    {
        double? refOut = Num.IsFinite(spanRef) ? spanRef : (double?)null;

        if (trays.Count < 2 || trays.Any(t => !t.good || !Num.IsFinite(t.pct)))
            return new("입력부족", null, double.NaN, refOut);

        // 인접쌍 단조감소 검증: dDown = 하단 − 상단, 정상 > 0. 상단이 tolInv 이상 뜨거우면 역전.
        for (int i = 0; i + 1 < trays.Count; i++)
        {
            double dDown = trays[i].pct - trays[i + 1].pct;
            if (dDown < -tolInv)
                return new("온도역전", $"{trays[i].tag}-{trays[i + 1].tag}",
                           trays[0].pct - trays[^1].pct, refOut);
        }

        double span = trays[0].pct - trays[^1].pct;   // A − C (조성 분리 스팬)
        if (Num.IsFinite(spanRef) && spanRef > 0)
        {
            if (span < spanCollapseFrac * spanRef) return new("프로파일붕괴", null, span, spanRef);
            if (span < spanWarnFrac * spanRef)     return new("약화", null, span, spanRef);
        }
        return new("정상", null, span, refOut);
    }
}
