using System.IO;
using System.Text.Json;
using Nexus.Contracts.Apps;

namespace NexusShell.Services;

public sealed class AppCatalogService
{
    private AppManifest? _manifest;

    public IReadOnlyList<AppEntry> Apps => _manifest?.Apps ?? [];

    public void Load()
    {
        var path = Path.Combine(AppContext.BaseDirectory, "Assets", "apps.manifest.json");
        if (!File.Exists(path))
        {
            _manifest = new AppManifest();
            return;
        }

        var json = File.ReadAllText(path);
        _manifest = JsonSerializer.Deserialize<AppManifest>(json, JsonOptions) ?? new AppManifest();
    }

    public AppEntry? GetById(string appId) =>
        Apps.FirstOrDefault(a => string.Equals(a.Id, appId, StringComparison.OrdinalIgnoreCase));

    public IEnumerable<AppEntry> Search(string query)
    {
        if (string.IsNullOrWhiteSpace(query))
        {
            return Apps;
        }

        return Apps.Where(a =>
            a.Name.Contains(query, StringComparison.OrdinalIgnoreCase) ||
            a.Category.Contains(query, StringComparison.OrdinalIgnoreCase) ||
            a.Description.Contains(query, StringComparison.OrdinalIgnoreCase) ||
            a.Status.Contains(query, StringComparison.OrdinalIgnoreCase));
    }

    public IEnumerable<AppEntry> GetPinned() => Apps.Where(a => a.Pinned);

    public IEnumerable<AppEntry> GetRecent(IEnumerable<string> recentIds)
    {
        foreach (var id in recentIds)
        {
            var app = GetById(id);
            if (app is not null)
            {
                yield return app;
            }
        }
    }

    private static readonly JsonSerializerOptions JsonOptions = new()
    {
        PropertyNameCaseInsensitive = true,
    };
}
