using System.Collections.ObjectModel;
using Avalonia.Threading;
using ClawdDotNet.App;
using ClawdDotNet.Core.Config;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;

namespace ClawdDotNet.Desktop.ViewModels;

public sealed record ChatEntryItemViewModel(
    string Role,
    string Sender,
    string Text,
    DateTime Timestamp,
    bool IsUser
);

/// <summary>
/// Ansichtsmodell für die native Chat-Seite (Avalonia UI statt WebView2).
/// </summary>
public sealed partial class ChatPageViewModel : PageViewModel
{
    private readonly AppHost? _host;

    public ObservableCollection<AgentConfig> AvailableAgents { get; } = [];
    public ObservableCollection<ChatEntryItemViewModel> ChatEntries { get; } = [];

    [ObservableProperty]
    private AgentConfig? _selectedAgent;

    [ObservableProperty]
    private string _inputPrompt = "";

    [ObservableProperty]
    private bool _isSending;

    [ObservableProperty]
    private string _statusText = "Bereit";

    public ChatPageViewModel() : this(null) { }

    public ChatPageViewModel(AppHost? host) : base("Chat")
    {
        _host = host;

        if (host is not null)
        {
            foreach (var agent in host.Instance.Agents)
                AvailableAgents.Add(agent);

            SelectedAgent = AvailableAgents.FirstOrDefault();

            if (host.Engine is not null)
            {
                host.Engine.OnChatEntryAdded += OnEngineChatEntryAdded;
            }
        }
        else
        {
            StatusText = "Entwurfsmodus";
        }
    }

    partial void OnSelectedAgentChanged(AgentConfig? value)
    {
        LoadChatHistory();
    }

    private void LoadChatHistory()
    {
        ChatEntries.Clear();
        if (_host?.Engine is null || SelectedAgent is null) return;

        var history = _host.Engine.GetChatHistory(SelectedAgent.AgentId);
        foreach (var entry in history)
        {
            var isUser = entry.Role.Equals("user", StringComparison.OrdinalIgnoreCase);
            ChatEntries.Add(new ChatEntryItemViewModel(
                entry.Role,
                isUser ? "Du" : SelectedAgent.DisplayName,
                entry.Content,
                entry.Timestamp,
                isUser
            ));
        }

        StatusText = $"Chat-Verlauf für '{SelectedAgent.DisplayName}' geladen ({ChatEntries.Count} Nachrichten).";
    }

    private void OnEngineChatEntryAdded(string agentId, string role, string text, string? toolName)
    {
        if (SelectedAgent is null || SelectedAgent.AgentId != agentId) return;

        Dispatcher.UIThread.Post(() =>
        {
            var isUser = role.Equals("user", StringComparison.OrdinalIgnoreCase);
            var sender = isUser ? "Du" : (string.IsNullOrWhiteSpace(toolName) ? SelectedAgent.DisplayName : $"Tool: {toolName}");

            ChatEntries.Add(new ChatEntryItemViewModel(
                role, sender, text, DateTime.Now, isUser
            ));
        });
    }

    [RelayCommand]
    private async Task SendMessageAsync()
    {
        if (_host?.Engine is null || SelectedAgent is null)
        {
            StatusText = "Engine nicht aktiv oder kein Agent ausgewählt.";
            return;
        }

        var text = InputPrompt.Trim();
        if (string.IsNullOrWhiteSpace(text)) return;

        InputPrompt = "";
        IsSending = true;
        StatusText = $"{SelectedAgent.DisplayName} denkt nach…";

        try
        {
            var agent = SelectedAgent;
            var instanceId = _host.Instance.InstanceId;

            var result = await Task.Run(() =>
                _host.Engine.ChatAsync(agent, text, instanceId, CancellationToken.None));

            StatusText = $"{agent.DisplayName} fertig ({result.Status}, {result.TokensUsed:N0} Tokens).";
        }
        catch (Exception ex)
        {
            StatusText = $"Fehler: {ex.Message}";
        }
        finally
        {
            IsSending = false;
        }
    }

    [RelayCommand]
    private void Abort()
    {
        if (_host?.Engine is null || SelectedAgent is null) return;
        _host.Engine.AbortChat(SelectedAgent.AgentId);
        StatusText = "Chat abgebrochen.";
        IsSending = false;
    }

    [RelayCommand]
    private void ClearHistory()
    {
        if (_host?.Engine is null || SelectedAgent is null) return;
        _host.Engine.ClearChatHistory(SelectedAgent.AgentId);
        ChatEntries.Clear();
        StatusText = "Verlauf geleert.";
    }
}
