using System.Collections.ObjectModel;
using System.Windows.Input;
using AgentWikiUi.Core;
namespace AgentWikiUi.Gui;
class MessageVm(string role, string text, string author)
{
public string Role { get; } = role;
public string Text { get; } = text;
public string Author { get; } = author;
public bool IsUser => Role == "user";
public bool IsAi => Role == "ai";
public bool IsErr => Role == "err";
}
class ChatItem(string id, string title, DateTime updated, bool active, string engineName)
{
public string Id { get; } = id;
public string Title { get; } = title;
public string When { get; } = $"{engineName} · {updated:d MMM HH:mm}";
public bool IsActive { get; } = active;
}
/// Voce dell'interruttore CLI: un motore non installato è mostrato ma non selezionabile.
class EngineChoice(Engine engine)
{
public Engine Engine { get; } = engine;
public bool Installed { get; } = engine.IsInstalled();
public string Label => Installed ? Engine.Name : $"{Engine.Name} (non installato)";
}
class MainViewModel : ObservableObject
{
static readonly ModelOption Default = new("Predefinito", "");
static readonly ModelOption Custom = new("Altro ID…", "__custom");
const string DefaultEffort = "Predefinito";
public ObservableCollection Messages { get; } = [];
public ObservableCollection Chats { get; } = [];
public EngineChoice[] EngineChoices { get; } = Engines.All.Select(e => new EngineChoice(e)).ToArray();
public ICommand NewChatCommand => newChat;
public ICommand CopyCommand { get; }
public ICommand SendCommand { get; }
public ICommand OpenCommand { get; }
public ICommand DeleteCommand { get; }
public ICommand ToggleSidebarCommand { get; }
/// Conferma di eliminazione, fornita dalla finestra.
public Func> ConfirmDelete { get; set; } = () => Task.FromResult(true);
/// Copia negli appunti, fornita dalla finestra.
public Func CopyText { get; set; } = _ => Task.CompletedTask;
/// Chiesto alla finestra di rimettere il fuoco sul campo messaggio.
public event Action? FocusInput;
// Una chat = un motore. chatId è il nome del file; sessionId è l'id del motore:
// per Claude Code lo sceglie l'app (= chatId), per Codex arriva dall'output dopo il primo messaggio.
string chatId = Guid.NewGuid().ToString();
string? sessionId;
bool started; // true dopo il primo messaggio riuscito: da lì in poi si riprende la sessione
List history = [];
EngineChoice selectedEngine;
ModelOption[] modelChoices = [];
string[] effortChoices = [];
string input = "";
bool busy, sidebarOpen = true;
ModelOption selectedModel = Default;
string customModel = "";
string selectedEffort = DefaultEffort;
readonly RelayCommand