// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.ComponentModel.Design;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Threading;
using Task = System.Threading.Tasks.Task;

namespace Microsoft.TypeAgent.VisualStudio;

internal sealed class ChatToolWindowCommand
{
    public const int CommandId = 0x0100;
    public static readonly Guid CommandSet = new Guid("c2a30f9d-8c64-4f3e-ad2a-af2f3b4e6f12");

    private readonly AsyncPackage _package;

    private ChatToolWindowCommand(AsyncPackage package, OleMenuCommandService commandService)
    {
        _package = package ?? throw new ArgumentNullException(nameof(package));
        commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));

        var menuCommandID = new CommandID(CommandSet, CommandId);
        var menuItem = new MenuCommand(Execute, menuCommandID);
        commandService.AddCommand(menuItem);
    }

    public static async Task InitializeAsync(AsyncPackage package)
    {
        await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);
        var commandService = (OleMenuCommandService?)await package.GetServiceAsync(typeof(IMenuCommandService));
        if (commandService is null)
        {
            return;
        }
        _ = new ChatToolWindowCommand(package, commandService);
    }

    private void Execute(object sender, EventArgs e)
    {
        _package.JoinableTaskFactory.RunAsync(async () =>
        {
            // Marshal to the UI thread explicitly so the VSTHRD010 analyzer
            // can see the IVsWindowFrame access is main-thread-safe.
            await _package.JoinableTaskFactory.SwitchToMainThreadAsync(_package.DisposalToken);
            var window = await _package.ShowToolWindowAsync(typeof(ChatToolWindow), 0, create: true, cancellationToken: _package.DisposalToken);
            if (window?.Frame is IVsWindowFrame frame)
            {
                Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(frame.Show());
            }
        }).FileAndForget("typeagent/vsix/show-tool-window");
    }
}
