using System.Diagnostics;
using System.Reflection;

namespace Mlaumcherb.Client.Avalonia.сеть.Update;

public class UpdateHelper
{
    private readonly string _executableName = "млаумчерб.exe";
    private readonly IOPath executablePathActual;
    private readonly IOPath executablePathOld;
    private readonly IOPath executablePathNew;

    private readonly GiteaConfig _giteaConfig;
    
    public class GiteaConfig
    {
        [JsonRequired] public required string serverUrl { get; set; }
        [JsonRequired] public required string user { get; set; }
        [JsonRequired] public required string repo { get; set; }
        
        public string GetRepoUrl() => $"{serverUrl}/{user}/{repo}";
    }
    
    
    public UpdateHelper(GiteaConfig giteaConfig)
    {
        _giteaConfig = giteaConfig;
        executablePathActual = _executableName;
        executablePathOld = _executableName + ".old";
        executablePathNew = _executableName + ".new";
        Gitea = new GiteaClient(giteaConfig.serverUrl);
    }

    public GiteaClient Gitea { get; }

    public void DeleteBackupFiles()
    {
        if(File.Exists(executablePathOld))
            File.Delete(executablePathOld);
    }
    
    public async Task<bool> IsUpdateAvailable()
    {
        var latest = await Gitea.GetLatestRelease(_giteaConfig.user, _giteaConfig.repo);
        if (!Version.TryParse(latest.tag_name, out var latestVersion))
            throw new Exception($"Can't parse version of latest release: {latest.tag_name}");

        Version? currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
        if(currentVersion is null)
            throw new Exception($"Can't get current version from {Assembly.GetExecutingAssembly().GetName()}");

        return currentVersion < latestVersion;
    }

    public async Task UpdateSelf()
    {
        if(File.Exists(executablePathNew))
            File.Delete(executablePathNew);
        
        var latest = await Gitea.GetLatestRelease(_giteaConfig.user, _giteaConfig.repo);
        var asset = latest.FindAssetByName(_executableName);
        if(asset == null)
            throw new Exception($"Can't find updated executable on gitea: {_executableName}");
        await asset.Download(executablePathNew);
        
        File.Move(executablePathActual, executablePathOld, true);
        File.Move(executablePathNew, executablePathActual, true);
    }

    public void RestartSelf()
    {
        Process.Start(executablePathActual.ToString());
        Thread.Sleep(500);
        Environment.Exit(0);
    }
}