using ClaudeDo.Releases;
using ClaudeDo.Ui.Localization;
using CommunityToolkit.Mvvm.ComponentModel;

namespace ClaudeDo.Ui.Services;

public enum UpdateCheckStatus
{
    NeverChecked,
    CheckFailed,
    UpToDate,
    UpdateAvailable,
}

public sealed partial class UpdateCheckService : ObservableObject
{
    private readonly IReleaseClient _releases;

    public OperationStatus Op { get; } = new();

    [ObservableProperty] private bool _isUpdateAvailable;
    [ObservableProperty] private string? _latestVersion;
    [ObservableProperty] private string _currentVersion;
    [ObservableProperty] private UpdateCheckStatus _lastCheckStatus = UpdateCheckStatus.NeverChecked;

    public UpdateCheckService(IReleaseClient releases, string currentVersion)
    {
        _releases = releases;
        _currentVersion = currentVersion;
    }

    public async Task CheckNowAsync(CancellationToken ct)
    {
        using var op = Op.Begin(Loc.T("ops.updateCheck.checking"));

        GiteaRelease? rel;
        try
        {
            rel = await _releases.GetLatestReleaseAsync(ct);
        }
        catch
        {
            LastCheckStatus = UpdateCheckStatus.CheckFailed;
            IsUpdateAvailable = false;
            return;
        }

        if (rel is null)
        {
            LastCheckStatus = UpdateCheckStatus.CheckFailed;
            IsUpdateAvailable = false;
            return;
        }

        var latest = (rel.TagName ?? "").TrimStart('v', 'V');
        var cmp = VersionComparer.Compare(latest, CurrentVersion);
        if (cmp.IsNewer)
        {
            LatestVersion = latest;
            IsUpdateAvailable = true;
            LastCheckStatus = UpdateCheckStatus.UpdateAvailable;
        }
        else
        {
            IsUpdateAvailable = false;
            LastCheckStatus = UpdateCheckStatus.UpToDate;
        }
    }
}
