Editor/Commands/Tools/CreateModelTool.cs
// Copyright Braxnet 2025 unless specified otherwise
// https://braxnet.online

using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
using Editor;
using Sandbox;

namespace Braxnet.Commands.Tools;

[MCPTool( "create_model", "Create Model", "Create a new vmdl model" )]
public class CreateModelTool : IMCPTool
{
	public string Name => "create_model";
	public string Title => "Create Model";
	public string Description => "Create a new vmdl model";

	public JsonElement InputSchema => JsonSerializer.SerializeToElement( new
	{
		type = "object",
		properties = new
		{
			meshPath = new { type = "string", description = "Path to the mesh file (obj, fbx, etc.)" },
			modelPath = new { type = "string", description = "Path to the vmdl file to create" },
		},
		required = new[] { "meshPath", "modelPath" }
	} );

	public JsonElement OutputSchema => default;

	public async Task<CallToolResult> ExecuteAsync( Dictionary<string, object> arguments, string sessionId )
	{
		var result = new CallToolResult();

		if ( arguments == null )
		{
			result.IsError = true;
			result.Content.Add( new TextContent { Text = "No arguments provided" } );
			return result;
		}

		var meshPath = arguments.GetValueOrDefault( "meshPath" )?.ToString();
		var modelPath = arguments.GetValueOrDefault( "modelPath" )?.ToString();

		if ( string.IsNullOrEmpty( meshPath ) || string.IsNullOrEmpty( modelPath ) )
		{
			result.IsError = true;
			result.Content.Add( new TextContent { Text = "Both meshPath and modelPath are required" } );
			return result;
		}

		if ( !meshPath.ToLower().EndsWith( ".obj" ) && !meshPath.ToLower().EndsWith( ".fbx" ) )
		{
			result.IsError = true;
			result.Content.Add( new TextContent
			{
				Text = "Unsupported mesh file format. Only .obj and .fbx are allowed."
			} );
			return result;
		}

		if ( !modelPath.EndsWith( ".vmdl" ) )
		{
			result.IsError = true;
			result.Content.Add( new TextContent { Text = "Model path must end with .vmdl" } );
			return result;
		}

		await GameTask.MainThread();

		var meshAsset = AssetSystem.FindByPath( meshPath );
		if ( meshAsset == null )
		{
			result.IsError = true;
			result.Content.Add( new TextContent { Text = $"Mesh asset file not found: {meshPath}" } );
			return result;
		}

		var modelAsset = EditorUtility.CreateModelFromMeshFile( meshAsset );

		if ( modelAsset == null )
		{
			result.IsError = true;
			result.Content.Add( new TextContent { Text = "Failed to create model from mesh file." } );
			return result;
		}

		result.Content.Add( new TextContent { Text = $"Model created successfully at: {modelPath}" } );

		result.StructuredContent = new Dictionary<string, string>
		{
			{ "modelPath", modelPath }, { "meshPath", meshPath }
		};

		result.IsError = false;

		return result;
	}
}