// ---------------------------------------------------------------------------
// BT.Framework
// FormatEx.cs — 게임 빈출 포맷(수치 축약·시간·확률) 유틸리티
// ---------------------------------------------------------------------------
using System;
using System.Globalization;
using System.Text;

namespace BurningTimes.Core.Util
{
    /// <summary>
    /// 게임에서 자주 쓰이는 수치·시간·확률 포맷 변환을 모은 정적 유틸리티.
    /// </summary>
    /// <remarks>
    /// <para>설계 문서 §5 Tier 1. 로컬라이제이션 컨텍스트가 없는 순수 수치 포맷만 담당한다.
    /// 언어별 라벨(예: "골드")은 <c>BurningTimes.Localization</c>에서 별도로 처리한다.</para>
    /// <para>Invariant 문화권을 사용해 디바이스 로케일과 무관한 일관 출력 보장(C11 코드 범용성).</para>
    /// </remarks>
    public static class FormatEx
    {
        private static readonly string[] s_AbbrevSuffixes = { "", "K", "M", "B", "T" };

        /// <summary>큰 수를 K/M/B/T 단위로 축약한다.</summary>
        /// <param name="value">원본 정수.</param>
        /// <param name="decimals">소수 자리수(기본 1).</param>
        /// <returns>예: 12345 → "12.3K", 1_500_000 → "1.5M".</returns>
        public static string AbbreviateNumber(long value, int decimals = 1)
        {
            if (value == 0) return "0";

            long abs = value < 0 ? -value : value;
            int tier = 0;
            double scaled = abs;
            while (scaled >= 1000.0 && tier < s_AbbrevSuffixes.Length - 1)
            {
                scaled /= 1000.0;
                tier++;
            }

            string sign = value < 0 ? "-" : string.Empty;
            if (tier == 0)
            {
                return sign + abs.ToString(CultureInfo.InvariantCulture);
            }

            string format = decimals > 0 ? "F" + decimals : "F0";
            return sign + scaled.ToString(format, CultureInfo.InvariantCulture) + s_AbbrevSuffixes[tier];
        }

        /// <summary>초 단위 시간을 "mm:ss" 또는 "hh:mm:ss"로 포맷한다.</summary>
        public static string FormatTimeSpan(float seconds)
        {
            if (seconds < 0f) seconds = 0f;
            int total = (int)seconds;
            int h = total / 3600;
            int m = (total % 3600) / 60;
            int s = total % 60;

            if (h > 0)
            {
                return string.Format(CultureInfo.InvariantCulture, "{0:D2}:{1:D2}:{2:D2}", h, m, s);
            }
            return string.Format(CultureInfo.InvariantCulture, "{0:D2}:{1:D2}", m, s);
        }

        /// <summary>0~1 범위의 확률을 퍼센트 문자열로 변환한다. 예: 0.1234 → "12.34%".</summary>
        public static string FormatPercent(float ratio01, int decimals = 2)
        {
            float pct = ratio01 * 100f;
            string format = "F" + decimals;
            return pct.ToString(format, CultureInfo.InvariantCulture) + "%";
        }

        /// <summary>수치 사이에 천 단위 구분자를 삽입한다(Invariant, 쉼표).</summary>
        public static string WithThousands(long value)
        {
            return value.ToString("N0", CultureInfo.InvariantCulture);
        }

        /// <summary>바이트 크기를 B/KB/MB/GB 로 축약한다(Base 1024).</summary>
        public static string FormatBytes(long bytes, int decimals = 2)
        {
            if (bytes < 0) return "-" + FormatBytes(-bytes, decimals);
            string[] units = { "B", "KB", "MB", "GB", "TB" };
            double value = bytes;
            int idx = 0;
            while (value >= 1024.0 && idx < units.Length - 1)
            {
                value /= 1024.0;
                idx++;
            }
            string format = idx == 0 ? "F0" : ("F" + decimals);
            return value.ToString(format, CultureInfo.InvariantCulture) + units[idx];
        }
    }
}
