using System.Linq;
using Mlaumcherb.Client.Avalonia.зримое;
using Mlaumcherb.Client.Avalonia.холопы;

namespace Mlaumcherb.Client.Avalonia.классы;

public class InstalledVersionCatalog
{
    /// version_id, props
    [JsonRequired] public Dictionary<string, InstalledGameVersionProps> versions { get; set; } = new();

    private IComparer<InstalledGameVersionProps> reverseComparer = new ReverseComparer<InstalledGameVersionProps>();
    
    public static InstalledVersionCatalog Load()
    {
        InstalledVersionCatalog catalog;
        var installedCatalogPath = PathHelper.GetInstalledVersionCatalogPath();
        if (!File.Exists(installedCatalogPath))
        {
            LauncherApp.Logger.LogDebug(nameof(InstalledVersionCatalog), "creating new catalog");
            catalog = new InstalledVersionCatalog();
        }
        else
        {
            LauncherApp.Logger.LogDebug(nameof(InstalledVersionCatalog), "loading catalog from file");
            catalog = JsonConvert.DeserializeObject<InstalledVersionCatalog>(
                          File.ReadAllText(installedCatalogPath))
                      ?? throw new NullReferenceException($"can't deserialize {installedCatalogPath}");
        }

        catalog.CheckInstalledVersions();
        catalog.Save();
        return catalog;
    }

    public void Save()
    {
        var installedCatalogPath = PathHelper.GetInstalledVersionCatalogPath();
        LauncherApp.Logger.LogDebug(nameof(InstalledVersionCatalog), "saving catalog to file");
        var text = JsonConvert.SerializeObject(this, Formatting.Indented);
        File.WriteAllText(installedCatalogPath, text);
        LauncherApp.Logger.LogDebug(nameof(InstalledVersionCatalog), "catalog has been saved");
    }

    /// <summary>
    /// Check if any versions were installed or deleted manually.
    /// </summary>
    public void CheckInstalledVersions()
    {
        var versionsUpdated = new List<InstalledGameVersionProps>();
        Directory.Create(PathHelper.GetVersionsDir());
        foreach (var subdir in Directory.GetDirectories(PathHelper.GetVersionsDir()))
        {
            string id = subdir.LastName().ToString();
            if (!File.Exists(PathHelper.GetVersionDescriptorPath(id)))
                throw new Exception(
                    $"Can't find version descriptor file in directory '{subdir}'. Rename it as directory name.");
            
            if (versions.TryGetValue(id, out var foundProps))
            {
                versionsUpdated.Add(foundProps);
            }
            else
            {
                versionsUpdated.Add(new InstalledGameVersionProps(id, null, null));
            }
        }

        // reverse sort
        versionsUpdated.Sort(reverseComparer);
        // create dictionary from list
        versions = new Dictionary<string, InstalledGameVersionProps>(
            versionsUpdated.Select(props =>
                new KeyValuePair<string, InstalledGameVersionProps>(props.Id, props)
            ));
    }
}