using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;

namespace Lumi.Companion.App;

public partial class App : Application
{
    private TrayIcon? _trayIcon;
    private MainWindow? _mainWindow;

    public override void Initialize() => AvaloniaXamlLoader.Load(this);

    public override void OnFrameworkInitializationCompleted()
    {
        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            desktop.ShutdownMode = ShutdownMode.OnExplicitShutdown;
            var paths = CompanionPaths.ForCurrentUser();
            var settings = new CompanionSettingsStore(paths.SettingsPath);
            var runtime = new CompanionRuntime(paths, settings);
            _mainWindow = new MainWindow(runtime, settings);
            desktop.MainWindow = _mainWindow;
            ConfigureTray(desktop, runtime);
            runtime.UpdateRestartRequested += async () =>
            {
                _mainWindow.AllowExit();
                _trayIcon?.Dispose();
                await runtime.DisposeAsync();
                desktop.Shutdown();
            };
            Program.InstanceCoordinator!.ActivationRequested += () => Dispatcher.UIThread.Post(ShowMainWindow);
            if (!Program.LaunchInBackground) _mainWindow.Show();
            _ = runtime.InitializeAsync();
        }
        base.OnFrameworkInitializationCompleted();
    }

    private void ConfigureTray(IClassicDesktopStyleApplicationLifetime desktop, CompanionRuntime runtime)
    {
        var open = new NativeMenuItem("Open Lumi Companion");
        var test = new NativeMenuItem("Run transcription test");
        var health = new NativeMenuItem("Health: Starting") { IsEnabled = false };
        var update = new NativeMenuItem("Updates: Checking…") { IsEnabled = false };
        var web = new NativeMenuItem("Open Lumi WebUI");
        var quit = new NativeMenuItem("Quit");
        open.Click += (_, _) => ShowMainWindow();
        test.Click += async (_, _) =>
        {
            ShowMainWindow();
            _mainWindow?.ShowPage(CompanionPage.Test);
            await runtime.RunTestAsync();
        };
        web.Click += (_, _) => runtime.OpenLumiWebUi();
        update.Click += (_, _) => { ShowMainWindow(); _mainWindow?.ShowPage(CompanionPage.Overview); };
        quit.Click += async (_, _) =>
        {
            if (runtime.State.RequiresQuitConfirmation) ShowMainWindow();
            if (_mainWindow is null || !await _mainWindow.ConfirmQuitAsync()) return;
            _mainWindow.AllowExit();
            _trayIcon?.Dispose();
            await runtime.DisposeAsync();
            desktop.Shutdown();
        };

        _trayIcon = new TrayIcon
        {
            Icon = LumiIconFactory.Create(TrayHealth.Ready),
            ToolTipText = "Lumi Companion — starting",
            IsVisible = true,
            Menu = new NativeMenu { Items = { open, test, web, health, update, new NativeMenuItemSeparator(), quit } }
        };
        _trayIcon.Clicked += (_, _) => ShowMainWindow();
        TrayIcon.SetIcons(this, new TrayIcons { _trayIcon });
        runtime.StateChanged += state => Dispatcher.UIThread.Post(() =>
        {
            if (_trayIcon is null) return;
            _trayIcon.Icon = LumiIconFactory.Create(state.Health);
            _trayIcon.ToolTipText = state.UpdateAvailable ? $"Lumi Companion — update {state.AvailableVersion} available" : $"Lumi Companion — {state.Summary}";
            health.Header = $"Health: {state.Summary}";
            update.Header = state.UpdateAvailable ? $"Update available: {state.AvailableVersion}" : "Updates: Current";
            update.IsEnabled = state.UpdateAvailable;
            test.Header = state.TestRunning || state.BenchmarkRunning ? "Transcription test running…" : "Run transcription test";
            test.IsEnabled = !state.TestRunning && !state.BenchmarkRunning;
        });
    }

    private void ShowMainWindow()
    {
        if (_mainWindow is null) return;
        _mainWindow.Show();
        _mainWindow.WindowState = WindowState.Normal;
        _mainWindow.Activate();
    }
}
