using System;
using System.Text;
using VCommon.Reflection;

namespace VCommon
{
    [Flags]
    public enum TimeSpanPart //TODO: TimeSpanPart I18N
    {
        [EnumMeta("")]
        None = 0,

        [EnumMeta("")]
        Default = Days | Hours | Minutes | Seconds,

        [EnumMeta("")]
        Full = Days | Hours | Minutes | Seconds | Milliseconds,

        [EnumMeta("天")]
        Days = 1 << 0,

        [EnumMeta("小时")]
        Hours = 1 << 1,

        [EnumMeta("分钟")]
        Minutes = 1 << 2,

        [EnumMeta("秒")]
        Seconds = 1 << 3,

        [EnumMeta("毫秒")]
        Milliseconds = 1 << 4,
    }

    public static class TimeSpanFormatter
    {
        private static string FormatNumber(int value, TimeSpanPart part)
        {
            return value + EnumMeta<TimeSpanPart>.Meta[part].Text; //TODO: I18N: value > 1 add `s' suffix
        }

        public static string ToReadableString(this TimeSpan me, TimeSpanPart parts = TimeSpanPart.Default, bool showZero = false)
        {
            var abs = me.Duration();

            if (Math.Abs(abs.TotalMilliseconds) < 1) return "0";

            var result = new StringBuilder();

            void DoPart(TimeSpanPart part)
            {
                if (!parts.HasFlag(part)) return;
                var partValue = DynamicMemberAccess<TimeSpan, int>.Read(abs, part.ToString());
                if (0 < partValue || 0 == partValue && showZero)
                    result.Append(FormatNumber(partValue, DynamicMemberAccess<TimeSpanPart, TimeSpanPart>.ReadStatic(part.ToString())));
            }

            DoPart(TimeSpanPart.Days);
            DoPart(TimeSpanPart.Hours);
            DoPart(TimeSpanPart.Minutes);
            DoPart(TimeSpanPart.Seconds);
            DoPart(TimeSpanPart.Milliseconds);

            return result.ToString();
        }
    }
}
