using CMSMicroservice.Domain.Entities.Configuration;

namespace CMSMicroservice.Application.AppVersionCQ.Queries.GetAppVersion;

/// <summary>
/// Handler برای دریافت آخرین نسخه اپلیکیشن
/// </summary>
public class GetAppVersionQueryHandler : IRequestHandler<GetAppVersionQuery, AppVersionDto?>
{
    private readonly IApplicationDbContext _context;

    public GetAppVersionQueryHandler(IApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<AppVersionDto?> Handle(GetAppVersionQuery request, CancellationToken cancellationToken)
    {
        var appVersion = await _context.AppVersions
            .Where(v => v.AppName == request.AppName && v.IsActive && !v.IsDeleted)
            .FirstOrDefaultAsync(cancellationToken);

        if (appVersion == null)
        {
            return new AppVersionDto
            {
                Found = false,
                AppName = request.AppName
            };
        }

        // مقایسه ورژن کلاینت با حداقل نسخه مورد نیاز
        bool requiresUpdate = false;
        if (!string.IsNullOrEmpty(request.CurrentClientVersion) && !string.IsNullOrEmpty(appVersion.MinRequiredVersion))
        {
            requiresUpdate = CompareVersions(request.CurrentClientVersion, appVersion.MinRequiredVersion) < 0;
        }

        return new AppVersionDto
        {
            Found = true,
            AppName = appVersion.AppName,
            CurrentVersion = appVersion.CurrentVersion,
            MinRequiredVersion = appVersion.MinRequiredVersion,
            RequiresFullCacheClear = appVersion.RequiresFullCacheClear,
            RequiresUpdate = requiresUpdate,
            UpdateMessage = appVersion.UpdateMessage,
            ReleaseNotes = appVersion.ReleaseNotes,
            LastUpdated = appVersion.LastModified ?? appVersion.Created
        };
    }

    /// <summary>
    /// مقایسه دو نسخه (مثلاً 1.2.3 با 1.3.0)
    /// برگشت: منفی = اولی کوچکتر، مثبت = اولی بزرگتر، صفر = برابر
    /// </summary>
    private static int CompareVersions(string version1, string version2)
    {
        var v1Parts = version1.Split('.').Select(s => int.TryParse(s, out var n) ? n : 0).ToArray();
        var v2Parts = version2.Split('.').Select(s => int.TryParse(s, out var n) ? n : 0).ToArray();

        var maxLen = Math.Max(v1Parts.Length, v2Parts.Length);
        
        for (int i = 0; i < maxLen; i++)
        {
            var v1 = i < v1Parts.Length ? v1Parts[i] : 0;
            var v2 = i < v2Parts.Length ? v2Parts[i] : 0;
            
            if (v1 != v2)
                return v1.CompareTo(v2);
        }

        return 0;
    }
}
