using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Input;
using Avalonia.Markup.Xaml;
using Avalonia.Media;
using Cogwheel;

namespace SessionZero.Cogwheel;

public partial class ConsoleControl : UserControl
{
    public int OutputTrimSize { get; set; } = 200;
    
    private TextBlock? _output;
    private TextBox? _input;
    private ScrollViewer? _outputScrollViewer;
    
    public ConsoleControl()
    {
        InitializeComponent();
        
        _output = this.FindControl<TextBlock>("Output");
        _input = this.FindControl<TextBox>("Input");
        _outputScrollViewer = this.FindControl<ScrollViewer>("OutputScrollView");

        _input?.KeyDown += Input_OnKeyDown;
    }

    private void Input_OnKeyDown(object? sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            SubmitInput();
            e.Handled = true;
        }
    }

    private void SubmitInput()
    {
        var inputText = _input!.Text ?? string.Empty;
        Log(inputText);
        if (inputText.Length > 0) COGWHEEL.RunCommand(inputText);
        _input.Text = string.Empty;
        TrimOutput();
        ScrollToEnd();
    }

    private void TrimOutput()
    {
        var maxInLines = OutputTrimSize * 3;
        while (_output?.Inlines?.Count > maxInLines)
        {
            if (_output?.Inlines?.Count >= 3)
            {
                _output?.Inlines?.RemoveRange(0,3);
            }
            else
            {
                _output?.Inlines?.RemoveAt(0);
            }
        }
    }

    public void Log(string text, Color? color = null)
    {
        if (_output == null)
            return;
        
        _output?.Inlines?.Add(new Run("> ") 
        { 
            Foreground = Brushes.LightGray 
        });
        
        _output?.Inlines?.Add(new Run(text)
        {
            Foreground = color != null ? new SolidColorBrush(color.Value) 
                : Brushes.White
        });
        
        _output?.Inlines?.Add(new LineBreak());
    }

    public void ClearOutput()
    {
        _output?.Inlines?.Clear();
    }

    public void ScrollToEnd()
    {
        _outputScrollViewer?.ScrollToEnd();
    }
}