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

namespace AxCopilot.Services.Agent;

/// <summary>여러 파일을 한 번에 읽어 결합 반환하는 도구.</summary>
public class MultiReadTool : IAgentTool
{
    public string Name => "multi_read";
    public string Description =>
        "Read multiple files in a single call (max 10). " +
        "Returns concatenated contents with file headers. " +
        "More efficient than calling file_read multiple times.";

    public ToolParameterSchema Parameters => new()
    {
        Properties = new()
        {
            ["paths"] = new()
            {
                Type = "array",
                Description = "List of file paths to read (max 10)",
                Items = new() { Type = "string", Description = "File path" },
            },
            ["max_lines"] = new()
            {
                Type = "integer",
                Description = "Max lines per file (default 200)",
            },
        },
        Required = ["paths"],
    };

    public Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default)
    {
        var maxLines = args.TryGetProperty("max_lines", out var ml) ? ml.GetInt32() : 200;
        if (maxLines <= 0) maxLines = 200;

        if (!args.TryGetProperty("paths", out var pathsEl) || pathsEl.ValueKind != JsonValueKind.Array)
            return Task.FromResult(ToolResult.Fail("'paths'는 문자열 배열이어야 합니다."));

        var paths = new List<string>();
        foreach (var p in pathsEl.EnumerateArray())
        {
            var s = p.GetString();
            if (!string.IsNullOrEmpty(s)) paths.Add(s);
        }

        if (paths.Count == 0)
            return Task.FromResult(ToolResult.Fail("읽을 파일이 없습니다."));
        if (paths.Count > 10)
            return Task.FromResult(ToolResult.Fail("최대 10개 파일만 지원합니다."));

        var sb = new StringBuilder();
        var readCount = 0;

        foreach (var rawPath in paths)
        {
            var path = Path.IsPathRooted(rawPath) ? rawPath : Path.Combine(context.WorkFolder, rawPath);

            sb.AppendLine($"═══ {Path.GetFileName(path)} ═══");
            sb.AppendLine($"Path: {path}");

            if (!context.IsPathAllowed(path))
            {
                sb.AppendLine("[접근 차단됨]");
            }
            else if (!File.Exists(path))
            {
                sb.AppendLine("[파일 없음]");
            }
            else
            {
                try
                {
                    var lines = File.ReadLines(path).Take(maxLines).ToList();
                    for (var i = 0; i < lines.Count; i++)
                        sb.AppendLine($"{i + 1}\t{lines[i]}");
                    if (lines.Count >= maxLines)
                        sb.AppendLine($"... (이후 생략, max_lines={maxLines})");
                    readCount++;
                }
                catch (Exception ex)
                {
                    sb.AppendLine($"[읽기 오류: {ex.Message}]");
                }
            }
            sb.AppendLine();
        }

        return Task.FromResult(ToolResult.Ok($"{readCount}/{paths.Count}개 파일 읽기 완료.\n\n{sb}"));
    }
}
