// ---------------------------------------------------------------------------
// BT.Framework
// KeyMaker.cs — Dictionary·PlayerPrefs 키 조합 생성 유틸리티
// ---------------------------------------------------------------------------
using System.Runtime.CompilerServices;

namespace BurningTimes.Core.Util
{
    /// <summary>
    /// Dictionary·PlayerPrefs·SaveData 등에서 사용할 합성 키를 일관된 규칙으로 생성하는 유틸리티.
    /// </summary>
    /// <remarks>
    /// <para>설계 문서 §5 Tier 1. 이전 프로젝트에서 `$"{category}_{id}"` 와 `$"{category}:{id}"`
    /// 가 혼재되어 키 충돌·조회 실패가 발생한 경험을 반영, 프레임워크 전체에서 구분자 <c>':'</c>로 고정한다.</para>
    /// <para>구분자 <c>':'</c>를 선택한 이유:</para>
    /// <list type="bullet">
    ///   <item><description>JSON·URL 경로·Redis 네임스페이스 등 외부 시스템 관례와 일치.</description></item>
    ///   <item><description>숫자 ID·GUID 등에 포함되지 않아 파싱 안전.</description></item>
    ///   <item><description>PlayerPrefs 키로 안전하게 사용 가능.</description></item>
    /// </list>
    /// <para>주의: 이미 구분자를 포함한 값이 인자로 들어와도 이스케이프하지 않는다.
    /// 키 역파싱(<see cref="SplitRoot"/>)이 필요한 경우 호출자가 입력을 검증한다.</para>
    /// </remarks>
    public static class KeyMaker
    {
        /// <summary>합성 키에 사용되는 구분자.</summary>
        public const char Separator = ':';

        /// <summary>두 토큰으로 합성 키를 만든다. 예: Make("card", "101") → "card:101".</summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static string Make(string a, string b)
        {
            return a + Separator + b;
        }

        /// <summary>세 토큰으로 합성 키를 만든다.</summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static string Make(string a, string b, string c)
        {
            return a + Separator + b + Separator + c;
        }

        /// <summary>문자열과 정수 ID로 합성 키를 만든다.</summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static string Make(string category, int id)
        {
            return category + Separator + id.ToString(System.Globalization.CultureInfo.InvariantCulture);
        }

        /// <summary>문자열과 두 정수 ID로 합성 키를 만든다. 예: 슬롯별 장비.</summary>
        public static string Make(string category, int idA, int idB)
        {
            return category + Separator + idA.ToString(System.Globalization.CultureInfo.InvariantCulture)
                 + Separator + idB.ToString(System.Globalization.CultureInfo.InvariantCulture);
        }

        /// <summary>다수 토큰으로 합성 키를 만든다(원하는 수만큼 가변). 입력이 없으면 빈 문자열.</summary>
        public static string MakeParams(params string[] tokens)
        {
            if (tokens == null || tokens.Length == 0) return string.Empty;
            return string.Join(Separator.ToString(), tokens);
        }

        /// <summary>키의 최상위(첫 번째 구분자 앞) 토큰을 반환. 구분자가 없으면 전체 반환.</summary>
        public static string SplitRoot(string key)
        {
            if (string.IsNullOrEmpty(key)) return string.Empty;
            int idx = key.IndexOf(Separator);
            return idx < 0 ? key : key.Substring(0, idx);
        }

        /// <summary>키에 <paramref name="prefix"/> 가 붙어 있는지 확인한다(구분자 포함 체크).</summary>
        public static bool StartsWithCategory(string key, string prefix)
        {
            if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(prefix)) return false;
            if (!key.StartsWith(prefix)) return false;
            if (key.Length == prefix.Length) return true; // 완전 일치도 동일 카테고리로 간주
            return key[prefix.Length] == Separator;
        }
    }
}
