using System.ComponentModel;
using Kompas.Mcp.Core;
using Kompas.Mcp.Core.Drawings;
using ModelContextProtocol.Server;

namespace Kompas.Mcp.Host.Tools;

/// <summary>Инструменты 2D-чертежа (виды, оформление).</summary>
[McpServerToolType]
public sealed class DrawingTools(KompasSession session, DrawingService drawing)
{
    [McpServerTool(Name = "drawing_create_standard_views")]
    [Description("На активном чертеже создать стандартные ассоциативные виды (спереди, сверху, слева) " +
        "сохранённой 3D-модели (.m3d деталь / .a3d сборка). Активный документ должен быть чертежом " +
        "(document_create drawing); модель должна быть сохранена в файл (document_save_as). " +
        "scale — масштаб (1.0 = 1:1); x,y — точка привязки главного вида на листе (мм). " +
        "Повторный вызов добавит ещё один набор видов — задайте другие x,y, чтобы не накладывались. " +
        "Возвращает число созданных видов.")]
    public async Task<string> CreateStandardViews(
        [Description("Путь к файлу 3D-модели (.m3d/.a3d)")] string partFilePath,
        [Description("Масштаб видов (1.0 = 1:1)")] double scale = 1.0,
        [Description("X привязки главного вида на листе, мм")] double x = 100,
        [Description("Y привязки главного вида на листе, мм")] double y = 150)
    {
        await session.ConnectAsync();
        var r = await drawing.CreateStandardViewsAsync(partFilePath, scale, x, y);
        var numbers = string.Join(", ", r.ViewNumbers);
        return $"Создано {r.Created} стандартных вида на чертеже (всего видов: {r.Total}, масштаб {scale}). " +
               $"Номера созданных видов: {numbers} (для инструментов простановки размеров — параметр viewNumber).";
    }

    [McpServerTool(Name = "drawing_fill_title_block")]
    [Description("Заполнить графы основной надписи (штампа) активного чертежа. Передавайте только нужные поля: " +
        "designation — обозначение документа (графа 2); name — наименование изделия (графа 1); " +
        "material — материал (графа 3). Незаданные/пустые поля пропускаются (нужно хотя бы одно). " +
        "Существующий текст графы перезаписывается. Возвращает число заполненных граф.")]
    public async Task<string> FillTitleBlock(
        [Description("Обозначение документа (графа 2)")] string? designation = null,
        [Description("Наименование изделия (графа 1)")] string? name = null,
        [Description("Материал (графа 3)")] string? material = null)
    {
        await session.ConnectAsync();
        var filled = await drawing.FillTitleBlockAsync(designation, name, material);
        return $"Заполнено граф основной надписи: {filled}.";
    }

    [McpServerTool(Name = "drawing_add_linear_dimension")]
    [Description("Поставить линейный размер на виде активного чертежа между точками (x1,y1)-(x2,y2) " +
        "в ЛОКАЛЬНОЙ СК вида (мм; при масштабе 1:1 = координаты модели на плоскости вида). Размерная " +
        "линия проходит через (x3,y3). orientation: horizontal (|X2-X1|) | vertical (|Y2-Y1|) | parallel " +
        "(длина отрезка). viewNumber — номер вида из drawing_create_standard_views (0 = первый/главный вид). " +
        "Значение измеряется автоматически. Возвращает измеренное значение и номер вида.")]
    public async Task<string> AddLinearDimension(
        [Description("X первой выносной точки (СК вида, мм)")] double x1,
        [Description("Y первой выносной точки")] double y1,
        [Description("X второй выносной точки")] double x2,
        [Description("Y второй выносной точки")] double y2,
        [Description("X положения размерной линии")] double x3,
        [Description("Y положения размерной линии")] double y3,
        [Description("Ориентация: horizontal | vertical | parallel")] string orientation = "horizontal",
        [Description("Номер вида (0 = первый/главный)")] int viewNumber = 0)
    {
        await session.ConnectAsync();
        var o = DimensionOrientations.Parse(orientation);
        var r = await drawing.AddLinearDimensionAsync(viewNumber, x1, y1, x2, y2, x3, y3, o);
        return $"Линейный размер ({orientation}) поставлен на виде {r.ViewNumber}, значение {r.Value:0.###} мм.";
    }

    [McpServerTool(Name = "drawing_add_diametral_dimension")]
    [Description("Поставить диаметральный размер (Ø) окружности на виде активного чертежа. Окружность " +
        "задаётся центром (xc,yc) и радиусом radius в ЛОКАЛЬНОЙ СК вида (мм; при масштабе 1:1 = координаты " +
        "модели на плоскости вида) — задайте параметры реальной окружности вида. angle — направление выноски " +
        "в градусах. viewNumber — номер вида из drawing_create_standard_views (0 = первый/главный). " +
        "Значение (диаметр = 2·radius) измеряется автоматически. Возвращает диаметр и номер вида.")]
    public async Task<string> AddDiametralDimension(
        [Description("X центра окружности (СК вида, мм)")] double xc,
        [Description("Y центра окружности")] double yc,
        [Description("Радиус окружности, мм")] double radius,
        [Description("Направление выноски, градусы")] double angle = 0,
        [Description("Номер вида (0 = первый/главный)")] int viewNumber = 0)
    {
        await session.ConnectAsync();
        var r = await drawing.AddDiametralDimensionAsync(viewNumber, xc, yc, radius, angle);
        return $"Диаметральный размер поставлен на виде {r.ViewNumber}, Ø{r.Value:0.###} мм.";
    }
}
