using Insight.Domain.Enums;
using Insight.Remote.Shared.Abstractions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace Insight.Remote.Shared.Services;

public class Runtime : IHostedService
{
    private readonly CancellationTokenSource _cts = new();

    private Task? _desktopTask;
    private Thread? _uiThread;

    private readonly IDesktopApp _desktopApp;
    private readonly IDispatcher _dispatcher;
    private readonly IHostApplicationLifetime _lifetime;
    private readonly ILogger<Runtime> _logger;

    public Runtime(
        IDesktopApp desktopApp,
        IDispatcher dispatcher,
        IHostApplicationLifetime lifetime,
        ILogger<Runtime> logger)
    {
        _desktopApp = desktopApp;
        _dispatcher = dispatcher;
        _lifetime = lifetime;
        _logger = logger;

        _lifetime.ApplicationStopping.Register(_cts.Cancel);
    }

    public async Task StartAsync(CancellationToken cancellationToken)
    {
        // init app (os specific providers)
        _desktopTask = _desktopApp.InitAsync(RemoteControlMode.Attended, _cts.Token);

        // init dispatcher
        if (false) // if mode is attended (interactive)
        {
            // init ui thread
            _uiThread = await _dispatcher.RunAsync(_cts.Token);
        }

        // todo
        // report unattended accesskey to api ($"https://localhost:7024?mode=Unattended&sessionId={appState.SessionId}&accessKey={appState.AccessKey}")
    }

    public async Task StopAsync(CancellationToken cancellationToken)
    {
        _cts.Cancel();

        if (_desktopTask is not null) await _desktopTask;

        if (_uiThread is not null)
        {
            await _dispatcher.ShutdownAsync();

            using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(3));

            while (_uiThread.ThreadState == ThreadState.Running)
            {
                await Task.Delay(100, timeout.Token);
            }
        }
    }
}