using System.ComponentModel;
using Kompas.Mcp.Core;
using Kompas.Mcp.Core.Modeling;
using Kompas.Mcp.Core.Validation;
using ModelContextProtocol.Server;

namespace Kompas.Mcp.Host.Tools;

/// <summary>Инструменты параметрики: переменные модели.</summary>
[McpServerToolType]
public sealed class VariableTools(KompasSession session, VariableService variables, AutoValidation autoValidation)
{
    [McpServerTool(Name = "set_variable")]
    [Description("Задать переменную модели: создаётся, если её ещё нет, иначе меняется существующая — " +
                 "проверять наличие заранее не нужно. expression — константа («30») или формула со ссылками " +
                 "на другие переменные («width*2+5»); десятичный разделитель — точка. Модель перестраивается, " +
                 "значение пересчитывается. note — комментарий, external=true — внешняя переменная (управляема " +
                 "из сборки). ВАЖНО: переменная двигает геометрию только в параметрической модели (где размеры " +
                 "эскизов связаны с именами переменных); при литеральных размерах значение пересчитается, " +
                 "а форма не изменится. Возвращает вычисленное значение.")]
    public async Task<string> SetVariable(
        [Description("Имя переменной")] string name,
        [Description("Выражение: число или формула (width*2+5)")] string expression,
        [Description("Комментарий (необязательно)")] string? note = null,
        [Description("Внешняя переменная (управляема из сборки)")] bool external = false)
    {
        await session.ConnectAsync();
        var (value, created) = await variables.SetOrCreateVariableAsync(name, expression, note, external);
        var what = created ? "создана" : "изменена";
        return await autoValidation.AnnotateAsync($"Переменная '{name}' {what}: «{expression}» → {value}.");
    }

    [McpServerTool(Name = "delete_variable")]
    [Description("Удалить переменную модели по имени. Нельзя удалить переменную, на которую ссылаются другие (сначала удалите зависимые).")]
    public async Task<string> DeleteVariable(string name)
    {
        await session.ConnectAsync();
        await variables.DeleteVariableAsync(name);
        return $"Переменная '{name}' удалена.";
    }
}
