using System.Text;
using System.Text.Json;

namespace AxCopilot.Services.Agent;

/// <summary>
/// 작업 완료 후 후속 액션을 구조화하여 제안하는 도구.
/// UI가 클릭 가능한 칩으로 렌더링할 수 있도록 JSON 형태로 반환합니다.
/// </summary>
public class SuggestActionsTool : IAgentTool
{
    public string Name => "suggest_actions";

    public string Description =>
        "Suggest 2-5 follow-up actions after completing a task. " +
        "Returns structured JSON that the UI renders as clickable action chips. " +
        "Each action has a label (display text), command (slash command or natural language prompt), " +
        "optional icon (Segoe MDL2 Assets code), and priority (high/medium/low).";

    public ToolParameterSchema Parameters => new()
    {
        Properties = new()
        {
            ["actions"] = new()
            {
                Type = "array",
                Description = "List of action objects. Each object: {\"label\": \"표시 텍스트\", \"command\": \"/slash 또는 자연어\", \"icon\": \"\\uE8A5\" (optional), \"priority\": \"high|medium|low\"}",
                Items = new() { Type = "object", Description = "Action object with label, command, icon, priority" },
            },
            ["context"] = new()
            {
                Type = "string",
                Description = "Current task context summary (optional)",
            },
        },
        Required = ["actions"],
    };

    public Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default)
    {
        try
        {
            if (!args.TryGetProperty("actions", out var actionsEl) || actionsEl.ValueKind != JsonValueKind.Array)
                return Task.FromResult(ToolResult.Fail("actions 배열이 필요합니다."));

            var actions = new List<Dictionary<string, string>>();
            foreach (var item in actionsEl.EnumerateArray())
            {
                var label = item.TryGetProperty("label", out var l) ? l.GetString() ?? "" : "";
                var command = item.TryGetProperty("command", out var c) ? c.GetString() ?? "" : "";
                var icon = item.TryGetProperty("icon", out var i) ? i.GetString() ?? "" : "";
                var priority = item.TryGetProperty("priority", out var p) ? p.GetString() ?? "medium" : "medium";

                if (string.IsNullOrWhiteSpace(label))
                    return Task.FromResult(ToolResult.Fail("각 action에는 label이 필요합니다."));
                if (string.IsNullOrWhiteSpace(command))
                    return Task.FromResult(ToolResult.Fail("각 action에는 command가 필요합니다."));

                // priority 유효성 검사
                var validPriorities = new[] { "high", "medium", "low" };
                if (!validPriorities.Contains(priority))
                    priority = "medium";

                var action = new Dictionary<string, string>
                {
                    ["label"] = label,
                    ["command"] = command,
                    ["priority"] = priority,
                };
                if (!string.IsNullOrEmpty(icon))
                    action["icon"] = icon;

                actions.Add(action);
            }

            if (actions.Count < 1 || actions.Count > 5)
                return Task.FromResult(ToolResult.Fail("actions는 1~5개 사이여야 합니다."));

            var contextSummary = args.TryGetProperty("context", out var ctx) ? ctx.GetString() ?? "" : "";

            // 구조화된 JSON 응답 생성
            var result = new Dictionary<string, object>
            {
                ["type"] = "suggest_actions",
                ["actions"] = actions,
            };
            if (!string.IsNullOrEmpty(contextSummary))
                result["context"] = contextSummary;

            var json = JsonSerializer.Serialize(result, new JsonSerializerOptions
            {
                WriteIndented = true,
                Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
            });

            return Task.FromResult(ToolResult.Ok(json));
        }
        catch (Exception ex)
        {
            return Task.FromResult(ToolResult.Fail($"액션 제안 오류: {ex.Message}"));
        }
    }
}
