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

namespace AxCopilot.Services.Agent;

/// <summary>수학 수식을 계산하는 도구.</summary>
public class MathTool : IAgentTool
{
    public string Name => "math_eval";
    public string Description =>
        "Evaluate a mathematical expression and return the result. " +
        "Supports: +, -, *, /, %, parentheses, and common math operations. " +
        "Use for calculations, unit conversions, and numeric analysis.";

    public ToolParameterSchema Parameters => new()
    {
        Properties = new()
        {
            ["expression"] = new()
            {
                Type = "string",
                Description = "Mathematical expression to evaluate (e.g. '(100 * 1.08) / 3')",
            },
            ["precision"] = new()
            {
                Type = "integer",
                Description = "Decimal places for rounding (default: 6)",
            },
        },
        Required = ["expression"],
    };

    public Task<ToolResult> ExecuteAsync(JsonElement args, AgentContext context, CancellationToken ct = default)
    {
        var expression = args.GetProperty("expression").GetString() ?? "";
        var precision = args.TryGetProperty("precision", out var p) ? p.GetInt32() : 6;

        if (string.IsNullOrWhiteSpace(expression))
            return Task.FromResult(ToolResult.Fail("수식이 비어 있습니다."));

        try
        {
            // DataTable.Compute를 사용한 안전한 수식 평가
            var sanitized = expression
                .Replace("^", " ") // XOR 방지 — ** 패턴은 아래에서 처리
                .Replace("Math.", "")
                .Replace("System.", "");

            // 기본 보안 검사: 알파벳 함수 호출 차단
            if (System.Text.RegularExpressions.Regex.IsMatch(sanitized, @"[a-zA-Z]{3,}"))
                return Task.FromResult(ToolResult.Fail("함수 호출은 지원하지 않습니다. 기본 사칙연산만 가능합니다."));

            var dt = new DataTable();
            var result = dt.Compute(sanitized, null);
            var value = Convert.ToDouble(result);
            var rounded = Math.Round(value, precision);

            return Task.FromResult(ToolResult.Ok(
                $"Expression: {expression}\nResult: {rounded}"));
        }
        catch (Exception ex)
        {
            return Task.FromResult(ToolResult.Fail($"수식 평가 오류: {ex.Message}"));
        }
    }
}
