using Kompas6Constants;

namespace Kompas.Mcp.Core.Drawings;

/// <summary>Ориентация линейного размера (обёртка над <see cref="ksLineDimensionOrientationEnum"/>).</summary>
public enum DimensionOrientation
{
    /// <summary>Горизонтальный (измеряет |X2−X1|).</summary>
    Horizontal,
    /// <summary>Вертикальный (измеряет |Y2−Y1|).</summary>
    Vertical,
    /// <summary>Параллельный отрезку P1→P2 (реальная длина).</summary>
    Parallel,
}

/// <summary>Конверсии углов размеров (2D-API КОМПАС использует радианы).</summary>
public static class DimensionAngles
{
    /// <summary>Градусы → радианы (угол выноски в API задаётся в радианах).</summary>
    public static double ToRadians(double degrees)
    {
        if (!double.IsFinite(degrees))
            throw new ArgumentException("Угол должен быть конечным числом.", nameof(degrees));
        var result = degrees * (Math.PI / 180.0);
        if (!double.IsFinite(result)) // защита от переполнения на экстремальных degrees
            throw new ArgumentOutOfRangeException(nameof(degrees), "Угол слишком велик (переполнение при переводе в радианы).");
        return result;
    }
}

/// <summary>Маппинг ориентации размера ↔ перечисление КОМПАС и разбор строки.</summary>
public static class DimensionOrientations
{
    public static ksLineDimensionOrientationEnum ToKompas(DimensionOrientation orientation) => orientation switch
    {
        DimensionOrientation.Horizontal => ksLineDimensionOrientationEnum.ksLinDHorizontal,
        DimensionOrientation.Vertical => ksLineDimensionOrientationEnum.ksLinDVertical,
        DimensionOrientation.Parallel => ksLineDimensionOrientationEnum.ksLinDParallel,
        _ => throw new ArgumentOutOfRangeException(nameof(orientation), orientation, "Неизвестная ориентация размера."),
    };

    /// <summary>Разобрать строку ориентации (англ./рус.) в <see cref="DimensionOrientation"/>.</summary>
    public static DimensionOrientation Parse(string value)
    {
        ArgumentNullException.ThrowIfNull(value);
        return value.Trim().ToLowerInvariant() switch
        {
            "horizontal" or "h" or "горизонтальный" or "горизонтальная" => DimensionOrientation.Horizontal,
            "vertical" or "v" or "вертикальный" or "вертикальная" => DimensionOrientation.Vertical,
            "parallel" or "p" or "параллельный" or "параллельная" => DimensionOrientation.Parallel,
            _ => throw new ArgumentException(
                $"Неизвестная ориентация размера '{value}'. Допустимо: horizontal, vertical, parallel.",
                nameof(value)),
        };
    }
}
