using System.IO;
using System.Text.Json;
using NexusShell.Models;

namespace NexusShell.Services;

public sealed class NexusFavoritesService
{
    private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };

    private readonly NexusFileSystemService _fileSystem;
    private readonly string _favoritesPath;
    private List<NexusFavoriteEntry> _entries = [];

    public NexusFavoritesService(NexusFileSystemService fileSystem)
    {
        _fileSystem = fileSystem;
        _favoritesPath = Path.Combine(_fileSystem.NexusRoot, "files-favorites.json");
        Load();
    }

    public event EventHandler? FavoritesChanged;

    public IReadOnlyList<NexusNavItem> GetFavoriteNavItems()
    {
        EnsureDefaults();
        var items = new List<NexusNavItem>();
        foreach (var favorite in _fileSystem.GetDefaultFavorites())
        {
            var entry = _entries.FirstOrDefault(e => e.Id == favorite.Id);
            var isPinned = entry?.IsPinned ?? true;
            if (!isPinned)
            {
                continue;
            }

            items.Add(new NexusNavItem
            {
                Id = favorite.Id,
                Label = favorite.Label,
                TargetPath = _fileSystem.ResolveLocationId(favorite.Id),
                IconPath = NexusLucideIcons.ForFavoriteId(favorite.Id),
                IsPinned = true,
                ShowPinToggle = true,
                Section = "Favoritter",
            });
        }

        return items;
    }

    public IReadOnlyList<NexusNavItem> GetUnpinnedFavoriteNavItems()
    {
        EnsureDefaults();
        var items = new List<NexusNavItem>();
        foreach (var favorite in _fileSystem.GetDefaultFavorites())
        {
            var entry = _entries.FirstOrDefault(e => e.Id == favorite.Id);
            if (entry is null || entry.IsPinned)
            {
                continue;
            }

            items.Add(new NexusNavItem
            {
                Id = favorite.Id,
                Label = favorite.Label,
                TargetPath = _fileSystem.ResolveLocationId(favorite.Id),
                IconPath = NexusLucideIcons.ForFavoriteId(favorite.Id),
                IsPinned = false,
                ShowPinToggle = true,
                Section = "Favoritter",
            });
        }

        return items;
    }

    public bool IsPinned(string favoriteId)
    {
        EnsureDefaults();
        return _entries.FirstOrDefault(e => e.Id == favoriteId)?.IsPinned ?? true;
    }

    public void TogglePin(string favoriteId)
    {
        EnsureDefaults();
        var entry = _entries.FirstOrDefault(e => e.Id == favoriteId);
        if (entry is null)
        {
            _entries.Add(new NexusFavoriteEntry { Id = favoriteId, IsPinned = false });
        }
        else
        {
            entry.IsPinned = !entry.IsPinned;
        }

        Save();
        FavoritesChanged?.Invoke(this, EventArgs.Empty);
    }

    private void EnsureDefaults()
    {
        if (_entries.Count > 0)
        {
            return;
        }

        _entries = _fileSystem.GetDefaultFavorites()
            .Select(f => new NexusFavoriteEntry { Id = f.Id, IsPinned = true })
            .ToList();
        Save();
    }

    private void Load()
    {
        if (!File.Exists(_favoritesPath))
        {
            return;
        }

        try
        {
            var json = File.ReadAllText(_favoritesPath);
            _entries = JsonSerializer.Deserialize<List<NexusFavoriteEntry>>(json) ?? [];
        }
        catch
        {
            _entries = [];
        }
    }

    private void Save()
    {
        Directory.CreateDirectory(_fileSystem.NexusRoot);
        var json = JsonSerializer.Serialize(_entries, JsonOptions);
        File.WriteAllText(_favoritesPath, json);
    }
}
