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

namespace AxCopilot.Services.Agent;

/// <summary>
/// Windows 클립보드 읽기·쓰기 도구.
/// 에이전트가 클립보드를 통해 데이터를 주고받을 수 있게 합니다.
/// </summary>
public class ClipboardTool : IAgentTool
{
    public string Name => "clipboard_tool";
    public string Description =>
        "Read or write the Windows clipboard. Actions: " +
        "'read' — get current clipboard text content; " +
        "'write' — set clipboard text content; " +
        "'has_text' — check if clipboard contains text; " +
        "'has_image' — check if clipboard contains an image.";

    public ToolParameterSchema Parameters => new()
    {
        Properties = new()
        {
            ["action"] = new()
            {
                Type = "string",
                Description = "Action to perform",
                Enum = ["read", "write", "has_text", "has_image"],
            },
            ["text"] = new()
            {
                Type = "string",
                Description = "Text to write to clipboard (required for 'write' action)",
            },
        },
        Required = ["action"],
    };

    public Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default)
    {
        var action = args.GetProperty("action").GetString() ?? "";

        try
        {
            // 클립보드는 STA 스레드에서만 접근 가능
            ToolResult? result = null;
            Application.Current.Dispatcher.Invoke(() =>
            {
                result = action switch
                {
                    "read"      => ReadClipboard(),
                    "write"     => WriteClipboard(args),
                    "has_text"  => ToolResult.Ok(Clipboard.ContainsText() ? "true" : "false"),
                    "has_image" => ToolResult.Ok(Clipboard.ContainsImage() ? "true" : "false"),
                    _           => ToolResult.Fail($"Unknown action: {action}"),
                };
            });
            return Task.FromResult(result ?? ToolResult.Fail("클립보드 접근 실패"));
        }
        catch (Exception ex)
        {
            return Task.FromResult(ToolResult.Fail($"클립보드 오류: {ex.Message}"));
        }
    }

    private static ToolResult ReadClipboard()
    {
        if (!Clipboard.ContainsText())
            return ToolResult.Ok("(clipboard is empty or contains non-text data)");

        var text = Clipboard.GetText();
        if (string.IsNullOrEmpty(text))
            return ToolResult.Ok("(empty)");

        if (text.Length > 10000)
            return ToolResult.Ok(text[..10000] + $"\n\n... (truncated, total {text.Length} chars)");

        return ToolResult.Ok(text);
    }

    private static ToolResult WriteClipboard(JsonElement args)
    {
        if (!args.TryGetProperty("text", out var textProp))
            return ToolResult.Fail("'text' parameter is required for write action");

        var text = textProp.GetString() ?? "";
        Clipboard.SetText(text);
        return ToolResult.Ok($"✓ Clipboard updated ({text.Length} chars)");
    }
}
