using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.Win32;
using Windows.ApplicationModel;
using YMhut.Box.Core.App;

namespace YMhut.Box.WinUI.Services;

public sealed class WindowsStartupService : IStartupService
{
    private const string RunKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
    private const string ValueName = "YMhut Box";
    private const string StartupTaskId = "YMhutBoxStartupTask";

    public bool IsEnabled()
    {
        if (TryGetPackagedStartupTask(out var startupTask))
        {
            return startupTask.State == StartupTaskState.Enabled;
        }

        using var key = Registry.CurrentUser.OpenSubKey(RunKeyPath, false);
        return key?.GetValue(ValueName) is string value && value.Contains("YMhutBox", StringComparison.OrdinalIgnoreCase);
    }

    public void SetEnabled(bool enabled)
    {
        if (TryGetPackagedStartupTask(out var startupTask))
        {
            try
            {
                if (enabled)
                {
                    if (startupTask.State != StartupTaskState.Enabled)
                    {
                        _ = startupTask.RequestEnableAsync().AsTask().GetAwaiter().GetResult();
                    }
                }
                else if (startupTask.State == StartupTaskState.Enabled)
                {
                    startupTask.Disable();
                }
            }
            catch
            {
            }

            return;
        }

        using var key = Registry.CurrentUser.OpenSubKey(RunKeyPath, true) ?? Registry.CurrentUser.CreateSubKey(RunKeyPath, true);
        if (enabled)
        {
            var exe = InstallLayoutPaths.ResolveInstalledExecutablePath();
            key.SetValue(ValueName, $"\"{exe}\"");
        }
        else
        {
            key.DeleteValue(ValueName, false);
        }
    }

    private static bool TryGetPackagedStartupTask(out StartupTask startupTask)
    {
        startupTask = null!;
        try
        {
            _ = Package.Current;
            startupTask = StartupTask.GetAsync(StartupTaskId).AsTask().GetAwaiter().GetResult();
            return startupTask is not null;
        }
        catch
        {
            return false;
        }
    }
}
