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

namespace NexusShell.Services;

public sealed class ProfileService
{
    private readonly string _folder;
    private readonly string _tokensPath;
    private readonly string _profilePath;

    public ProfileService()
    {
        _folder = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
            "NinjaNexus");
        Directory.CreateDirectory(_folder);
        _tokensPath = Path.Combine(_folder, "tokens.enc");
        _profilePath = Path.Combine(_folder, "profile.json");
    }

    public string? AccessToken { get; private set; }

    public LocalUserProfile? CurrentProfile { get; private set; }

    public void SetAccessToken(string token) => AccessToken = token;

    public void SaveProfile(LocalUserProfile profile)
    {
        CurrentProfile = profile;
        var json = JsonSerializer.Serialize(profile, JsonOptions);
        File.WriteAllText(_profilePath, json);
    }

    public LocalUserProfile? LoadProfile()
    {
        if (!File.Exists(_profilePath))
        {
            return CurrentProfile;
        }

        var json = File.ReadAllText(_profilePath);
        CurrentProfile = JsonSerializer.Deserialize<LocalUserProfile>(json, JsonOptions);
        return CurrentProfile;
    }

    public void SaveTokens(StoredTokens tokens)
    {
        var json = JsonSerializer.Serialize(tokens, JsonOptions);
        var bytes = Encoding.UTF8.GetBytes(json);
        var protectedBytes = ProtectedData.Protect(bytes, null, DataProtectionScope.CurrentUser);
        File.WriteAllBytes(_tokensPath, protectedBytes);
    }

    public StoredTokens? LoadTokens()
    {
        if (!File.Exists(_tokensPath))
        {
            return null;
        }

        var protectedBytes = File.ReadAllBytes(_tokensPath);
        var bytes = ProtectedData.Unprotect(protectedBytes, null, DataProtectionScope.CurrentUser);
        var json = Encoding.UTF8.GetString(bytes);
        return JsonSerializer.Deserialize<StoredTokens>(json, JsonOptions);
    }

    public void AddRecentApp(string appId)
    {
        var profile = LoadProfile() ?? new LocalUserProfile();
        profile.RecentAppIds.Remove(appId);
        profile.RecentAppIds.Insert(0, appId);
        profile.RecentAppIds = profile.RecentAppIds.Take(5).ToList();
        SaveProfile(profile);
    }

    public void ClearSession()
    {
        AccessToken = null;
        CurrentProfile = null;
        if (File.Exists(_tokensPath))
        {
            File.Delete(_tokensPath);
        }
        if (File.Exists(_profilePath))
        {
            File.Delete(_profilePath);
        }
    }

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