using ClaudeDo.Releases;

namespace ClaudeDo.Installer.Core;

public sealed record DetectedState(
    InstallerMode Mode,
    InstallManifest? Existing,
    GiteaRelease? LatestRelease,
    string? LatestVersion)
{
    /// <summary>True when a release was returned but its tag isn't a parseable
    /// System.Version (e.g. "0.2.0-beta") — so we couldn't decide if it's newer.</summary>
    public bool LatestTagUnparseable { get; init; }
}

public sealed class InstallModeDetector
{
    private readonly IReleaseClient _releases;

    public InstallModeDetector(IReleaseClient releases)
    {
        _releases = releases;
    }

    public async Task<DetectedState> DetectAsync(string installDir, CancellationToken ct)
    {
        var manifest = InstallManifestStore.TryRead(installDir);
        if (manifest is null)
            return new DetectedState(InstallerMode.FreshInstall, null, null, null);

        var release = await _releases.GetLatestReleaseAsync(ct);
        if (release is null)
            return new DetectedState(InstallerMode.Config, manifest, null, null);

        var latestVersion = release.TagName.TrimStart('v', 'V');
        var cmp = VersionComparer.Compare(latestVersion, manifest.Version);
        var newer = cmp.IsNewer;
        var unparseable = cmp.Unparseable;
        if (newer)
            return new DetectedState(InstallerMode.Update, manifest, release, latestVersion);

        return new DetectedState(InstallerMode.Config, manifest, release, latestVersion)
        {
            LatestTagUnparseable = unparseable,
        };
    }

}
