using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;

namespace PolyTrader.Modules.Supervisor.Agent
{
    /// <summary>
    /// Ein read-only-Analyse-Tool des Supervisors: Name, Beschreibung, JSON-Schema der Parameter und
    /// die Ausführung. Tools LESEN ausschließlich (Journal, Events, Trades, Logs, KPIs) – es gibt
    /// bewusst keinen Mechanismus, der handeln, canceln oder schreiben könnte.
    /// </summary>
    public sealed record SupervisorTool(
        string Name,
        string Description,
        string ParametersJsonSchema,
        Func<JsonElement, string> Execute);

    /// <summary>
    /// Transport-agnostische Tool-Registry (S-2): heute vom In-Prozess-Agenten genutzt, später
    /// zusätzlich über MCP-Light exponierbar (S-4). Ausführung ist fehlertolerant – eine Tool-Exception
    /// wird als Fehlertext an das Modell zurückgegeben, nie geworfen.
    /// </summary>
    public sealed class SupervisorToolRegistry
    {
        private readonly Dictionary<string, SupervisorTool> _tools = new(StringComparer.OrdinalIgnoreCase);

        public IReadOnlyList<SupervisorTool> Tools => _tools.Values.ToList();

        public void Register(SupervisorTool tool) => _tools[tool.Name] = tool;

        public string Execute(string name, string argumentsJson)
        {
            if (!_tools.TryGetValue(name, out var tool))
                return $"FEHLER: Unbekanntes Tool '{name}'. Verfügbar: {string.Join(", ", _tools.Keys)}";

            try
            {
                using var doc = JsonDocument.Parse(string.IsNullOrWhiteSpace(argumentsJson) ? "{}" : argumentsJson);
                return tool.Execute(doc.RootElement.Clone());
            }
            catch (JsonException ex)
            {
                return $"FEHLER: Ungültige Tool-Argumente (kein JSON): {ex.Message}";
            }
            catch (Exception ex)
            {
                return $"FEHLER bei Tool '{name}': {ex.Message}";
            }
        }

        // ----- Argument-Helfer für Tool-Implementierungen -----

        public static string? GetString(JsonElement args, string name) =>
            args.ValueKind == JsonValueKind.Object && args.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.String
                ? v.GetString() : null;

        public static int? GetInt(JsonElement args, string name) =>
            args.ValueKind == JsonValueKind.Object && args.TryGetProperty(name, out var v) && v.ValueKind == JsonValueKind.Number
                ? v.GetInt32() : (int?)null;
    }
}
