namespace MiGu.DB.Domains.Wms;

/// <summary>
/// 枚举辅助类（复数命名）：承接 API/DTO 的字符串入参，解析为实体上的枚举。
/// 与同名枚举分离，避免「属性 LocationKind 初始值引用实例属性」一类编译冲突。
/// Server 侧通过 global using 别名（如 StorageStatuses）引用本文件类型。
/// </summary>
public static class AreaLayoutModes
{
    public static readonly HashSet<AreaLayoutMode> All = new() { AreaLayoutMode.Flat, AreaLayoutMode.Grid };

    public static AreaLayoutMode ParseOr(string? value, AreaLayoutMode fallback = AreaLayoutMode.Flat) =>
        Enum.TryParse<AreaLayoutMode>(value, true, out var e) && All.Contains(e) ? e : fallback;
}

public static class LocationKinds
{
    public const LocationKind Grid = LocationKind.Grid;
    public const LocationKind Station = LocationKind.Station;
    public static readonly HashSet<LocationKind> All = new() { Grid, Station };

    public static LocationKind ParseOr(string? value, LocationKind fallback = LocationKind.Station) =>
        Enum.TryParse<LocationKind>(value, true, out var e) && All.Contains(e) ? e : fallback;
}

public static class StorageStatuses
{
    public const StorageStatus Empty = StorageStatus.Empty;
    public const StorageStatus EmptyContainer = StorageStatus.EmptyContainer;
    public const StorageStatus FullContainer = StorageStatus.FullContainer;
    public const StorageStatus Disabled = StorageStatus.Disabled;

    public static readonly HashSet<StorageStatus> All = new()
        { Empty, EmptyContainer, FullContainer, Disabled };

    /// <summary>
    /// 写路径归一：兼容历史字符串 Available/Idle/Occupied。
    /// 库内残留旧值须靠 DataMigrator 刷掉，不能依赖 converter 读侧归一（WHERE 会漏行）。
    /// </summary>
    public static StorageStatus Normalize(string? status) => status switch
    {
        "Available" or "Idle" => Empty,
        "Occupied" => FullContainer,
        _ when Enum.TryParse<StorageStatus>(status, true, out var e) && All.Contains(e) => e,
        _ => Empty
    };
}

public static class ContainerStatuses
{
    public const ContainerStatus EmptyMaterial = ContainerStatus.EmptyMaterial;
    public const ContainerStatus FullMaterial = ContainerStatus.FullMaterial;
    public static readonly HashSet<ContainerStatus> All = new() { EmptyMaterial, FullMaterial };

    public static ContainerStatus ParseOr(string? value, ContainerStatus fallback = ContainerStatus.EmptyMaterial) =>
        Enum.TryParse<ContainerStatus>(value, true, out var e) && All.Contains(e) ? e : fallback;
}

public static class ContainerLocationTypes
{
    public const ContainerLocationType Storage = ContainerLocationType.Storage;
    public const ContainerLocationType Car = ContainerLocationType.Car;
    public static readonly HashSet<ContainerLocationType> All = new() { Storage, Car };

    public static bool IsDefined(string? value) =>
        Enum.TryParse<ContainerLocationType>(value, true, out var e) && All.Contains(e);

    public static ContainerLocationType ParseOr(string? value, ContainerLocationType fallback = ContainerLocationType.Storage) =>
        Enum.TryParse<ContainerLocationType>(value, true, out var e) && All.Contains(e) ? e : fallback;

    public static bool EqualsString(ContainerLocationType value, string? other) =>
        Enum.TryParse<ContainerLocationType>(other, true, out var e) && e == value;
}

public static class ContainerLocationStatuses
{
    public const ContainerLocationStatus Active = ContainerLocationStatus.Active;
    public const ContainerLocationStatus Locked = ContainerLocationStatus.Locked;
    public const ContainerLocationStatus Exception = ContainerLocationStatus.Exception;
    public static readonly HashSet<ContainerLocationStatus> All = new() { Active, Locked, Exception };

    public static bool IsDefined(string? value) =>
        Enum.TryParse<ContainerLocationStatus>(value, true, out var e) && All.Contains(e);

    public static ContainerLocationStatus ParseOr(string? value, ContainerLocationStatus fallback = ContainerLocationStatus.Active) =>
        Enum.TryParse<ContainerLocationStatus>(value, true, out var e) && All.Contains(e) ? e : fallback;
}

public static class ContainerMaterialStatuses
{
    public const ContainerMaterialStatus Bound = ContainerMaterialStatus.Bound;
    public const ContainerMaterialStatus Loaded = ContainerMaterialStatus.Loaded;
    public const ContainerMaterialStatus Unloaded = ContainerMaterialStatus.Unloaded;
    public const ContainerMaterialStatus Adjusted = ContainerMaterialStatus.Adjusted;
    public const ContainerMaterialStatus Frozen = ContainerMaterialStatus.Frozen;

    public static readonly HashSet<ContainerMaterialStatus> ActiveBind = new()
        { Bound, Loaded, Adjusted, Frozen };
}

public static class MaterialLifecycles
{
    public const MaterialLifecycle Active = MaterialLifecycle.Active;
    public const MaterialLifecycle Archived = MaterialLifecycle.Archived;
    public static readonly HashSet<MaterialLifecycle> All = new() { Active, Archived };

    public static MaterialLifecycle ParseOr(string? value, MaterialLifecycle fallback = MaterialLifecycle.Active) =>
        Enum.TryParse<MaterialLifecycle>(value, true, out var e) && All.Contains(e) ? e : fallback;
}

public static class StockEventTypes
{
    public const StockEventType Bind = StockEventType.Bind;
    public const StockEventType Unbind = StockEventType.Unbind;
    public const StockEventType ContainerMove = StockEventType.ContainerMove;
}
