using System.Text;

namespace AxCopilot.Services.Agent;

/// <summary>
/// Phase 19-D-EXT: ��킬 인수 치환.
/// $ARGUMENTS, $name (명명된 인수), {0} (인덱스 기반) 치환을 처리합니다.
/// </summary>
public static class SkillArgumentSubstitution
{
    /// <summary>
    /// 스킬 본문에서 인수 플레이스홀더를 치환합니다.
    /// </summary>
    /// <param name="body">스킬 본문 텍스트</param>
    /// <param name="namedArgs">프론트매터 arguments 필드 (명명된 인수 목록)</param>
    /// <param name="userInput">사용자가 전달한 인수 문자열</param>
    public static string Substitute(string body, IReadOnlyList<string>? namedArgs, string userInput)
    {
        if (string.IsNullOrEmpty(body)) return body;

        var result = body;

        // 1. $ARGUMENTS → 전체 인수 문자열
        result = result.Replace("$ARGUMENTS", userInput);

        // 2. 명명된 인수 ($name 구문)
        if (namedArgs != null && namedArgs.Count > 0)
        {
            var parts = SplitArguments(userInput);
            for (var i = 0; i < namedArgs.Count; i++)
            {
                var argName = namedArgs[i];
                var argValue = i < parts.Count ? parts[i] : "";
                result = result.Replace($"${argName}", argValue);
            }
        }

        // 3. 인덱스 기반 인수 ({0}, {1}, ...)
        var indexParts = SplitArguments(userInput);
        for (var i = 0; i < indexParts.Count; i++)
            result = result.Replace($"{{{i}}}", indexParts[i]);

        return result;
    }

    /// <summary>
    /// 공백으로 분리하되 따옴표로 감싼 인수는 하나로 처리합니다.
    /// 예: 'hello world' foo → ["hello world", "foo"]
    /// </summary>
    public static List<string> SplitArguments(string input)
    {
        if (string.IsNullOrWhiteSpace(input)) return new();

        var parts = new List<string>();
        var current = new StringBuilder();
        var inQuote = false;
        var quoteChar = '\0';

        foreach (var ch in input)
        {
            if (!inQuote && (ch == '"' || ch == '\''))
            {
                inQuote = true;
                quoteChar = ch;
                continue;
            }
            if (inQuote && ch == quoteChar)
            {
                inQuote = false;
                continue;
            }
            if (ch == ' ' && !inQuote && current.Length > 0)
            {
                parts.Add(current.ToString());
                current.Clear();
                continue;
            }
            current.Append(ch);
        }

        if (current.Length > 0) parts.Add(current.ToString());
        return parts;
    }
}
