using System.Globalization;

namespace TakeoutSaaS.Application.App.Products;

/// <summary>
/// 商品时段规则映射辅助。
/// </summary>
internal static class ProductScheduleMapping
{
    /// <summary>
    /// 解析状态字符串。
    /// </summary>
    public static bool TryParseStatus(string? status, out bool isEnabled)
    {
        var normalized = status?.Trim().ToLowerInvariant();
        switch (normalized)
        {
            case "enabled":
                isEnabled = true;
                return true;
            case "disabled":
                isEnabled = false;
                return true;
            default:
                isEnabled = true;
                return false;
        }
    }

    /// <summary>
    /// 状态转字符串。
    /// </summary>
    public static string ToStatusText(bool isEnabled)
    {
        return isEnabled ? "enabled" : "disabled";
    }

    /// <summary>
    /// 解析时间文本。
    /// </summary>
    public static bool TryParseTime(string? value, out TimeSpan parsed)
    {
        return TimeSpan.TryParseExact(
            (value ?? string.Empty).Trim(),
            "hh\\:mm",
            CultureInfo.InvariantCulture,
            out parsed);
    }

    /// <summary>
    /// 时间转字符串。
    /// </summary>
    public static string ToTimeText(TimeSpan value)
    {
        return value.ToString("hh\\:mm", CultureInfo.InvariantCulture);
    }

    /// <summary>
    /// 归一化星期列表（1-7）。
    /// </summary>
    public static bool TryNormalizeWeekDays(IEnumerable<int>? weekDays, out List<int> normalized)
    {
        normalized = (weekDays ?? [])
            .Distinct()
            .Where(day => day is >= 1 and <= 7)
            .OrderBy(day => day)
            .ToList();

        return normalized.Count > 0;
    }

    /// <summary>
    /// 星期列表转位掩码。
    /// </summary>
    public static int ToWeekDaysMask(IReadOnlyCollection<int> weekDays)
    {
        var mask = 0;
        foreach (var day in weekDays)
        {
            mask |= 1 << (day - 1);
        }

        return mask;
    }

    /// <summary>
    /// 位掩码转星期列表（1-7）。
    /// </summary>
    public static IReadOnlyList<int> FromWeekDaysMask(int mask)
    {
        var days = new List<int>(7);
        for (var day = 1; day <= 7; day++)
        {
            if ((mask & (1 << (day - 1))) != 0)
            {
                days.Add(day);
            }
        }

        return days;
    }
}
