using LightlessSync.Services.ServerConfiguration;

namespace LightlessSync.UI.Handlers;

public class TagHandler
{
    public const string CustomAllTag = "Lightless_All";
    public const string CustomOfflineTag = "Lightless_Offline";
    public const string CustomOfflineSyncshellTag = "Lightless_OfflineSyncshell";
    public const string CustomOnlineTag = "Lightless_Online";
    public const string CustomUnpairedTag = "Lightless_Unpaired";
    public const string CustomVisibleTag = "Lightless_Visible";
    private readonly ServerConfigurationManager _serverConfigurationManager;

    public TagHandler(ServerConfigurationManager serverConfigurationManager)
    {
        _serverConfigurationManager = serverConfigurationManager;
    }

    /// <summary>
    /// Creation of an pair tag
    /// </summary>
    /// <param name="tag">Name of the tag</param>
    public void AddPairTag(string tag) => _serverConfigurationManager.AddPairTag(tag);

    /// <summary>
    /// Creation of an syncshell tag
    /// </summary>
    /// <param name="tag">Name of the tag</param>
    public void AddSyncshellTag(string tag) => _serverConfigurationManager.AddSyncshellTag(tag);

    /// <summary>
    /// Add pair to tag
    /// </summary>
    /// <param name="uid">UID that will be added to tag/param>
    /// <param name="tagName">Name of the tag</param>
    public void AddPairTagToPairedUid(string uid, string tagName) => _serverConfigurationManager.AddTagForUid(uid, tagName);

    /// <summary>
    /// Add syncshell to tag
    /// </summary>
    /// <param name="name">Syncshell that will be added to tag/param>
    /// <param name="tagName">Name of the tag</param>
    public void AddTagToSyncshell(string name, string tagName) => _serverConfigurationManager.AddTagForSyncshell(name, tagName);

    /// <summary>
    /// Get all pair tags
    /// </summary>
    public List<string> GetAllPairTagsSorted() => [
            .. _serverConfigurationManager.GetServerAvailablePairTags()
                        .Order(StringComparer.OrdinalIgnoreCase)
,
        ];

    /// <summary>
    /// Get all syncshell tags
    /// </summary>
    public List<string> GetAllSyncshellTagsSorted() => [
            .. _serverConfigurationManager.GetServerAvailableSyncshellTags()
                        .Order(StringComparer.OrdinalIgnoreCase)
,
        ];

    /// <summary>
    /// Get all UIDs bound to an given tag
    /// </summary>
    /// <param name="name">Name of the tag</param>
    public HashSet<string> GetOtherUidsForTag(string tag) => _serverConfigurationManager.GetUidsForPairTag(tag);

    /// <summary>
    /// Get all syncshells bound to an given tag
    /// </summary>
    /// <param name="name">Name of the tag</param>
    public HashSet<string> GetOtherSyncshellsForTag(string tag) => _serverConfigurationManager.GetNamesForSyncshellTag(tag);

    /// <summary>
    /// Checking if the UID is connected to any tag
    /// </summary>
    /// <param name="uid">Syncshell that needs to be checked</param>
    public bool HasAnyPairTag(string uid) => _serverConfigurationManager.HasPairTags(uid);

    /// <summary>
    /// Checking if the syncshell is connected to the tag
    /// </summary>
    /// <param name="name">Syncshell that needs to be checked</param>
    public bool HasAnySyncshellTag(string name) => _serverConfigurationManager.HasSyncshellTags(name);

    /// <summary>
    /// Checking if the UID is connected to the tag
    /// </summary>
    /// <param name="uid">UID that needs to be checked</param>
    /// <param name="tagName">Name of the tag</param>
    public bool HasPairTag(string uid, string tagName) => _serverConfigurationManager.ContainsPairTag(uid, tagName);

    /// <summary>
    /// Checking if the syncshell is connected to the tag
    /// </summary>
    /// <param name="name">Syncshell that needs to be checked</param>
    /// <param name="tagName">Name of the tag</param>
    public bool HasSyncshellTag(string name, string tagName) => _serverConfigurationManager.ContainsSyncshellTag(name, tagName);

    /// <summary>
    /// Is this tag opened in the paired clients UI?
    /// </summary>
    /// <param name="tag">the tag</param>
    /// <returns>open true/false</returns>
    public bool IsTagOpen(string tag) => _serverConfigurationManager.ContainsOpenPairTag(tag);

    /// <summary>
    /// Removal of Pair Tags from Storage
    /// </summary>
    /// <param name="tag">Name of the tag</param>
    public void RemovePairTag(string tag) => _serverConfigurationManager.RemovePairTag(tag);

    /// <summary>
    /// Removal of Syncshell Tags from Storage
    /// </summary>
    /// <param name="tag">Name of the tag</param>
    public void RemoveSyncshellTag(string tag) => _serverConfigurationManager.RemoveSyncshellTag(tag);

    /// <summary>
    /// Removal of UID in a Tag
    /// </summary>
    /// <param name="uid">UID of user thats bound to the tag</param>
    /// <param name="tagName">Name of the tag</param>
    public void RemoveTagFromPairedUid(string uid, string tagName) => _serverConfigurationManager.RemoveTagForUid(uid, tagName);

    /// <summary>
    /// Removal of Syncshell in a Tag
    /// </summary>
    /// <param name="name">Syncshell thats bound to the tag</param>
    /// <param name="tagName">Name of the tag</param>
    public void RemoveTagFromSyncshell(string name, string tagName) => _serverConfigurationManager.RemoveTagForSyncshell(name, tagName);

    /// <summary>
    /// Rename of a pair tag
    /// </summary>
    /// <param name="oldName">Old pair tag name</param>
    /// <param name="newName">New pair tag name</param>
    public void RenamePairTag(string oldName, string newName)
    {
        _serverConfigurationManager.RenamePairTag(oldName, newName);
    }

    /// <summary>
    /// Rename of a syncshell tag
    /// </summary>
    /// <param name="oldName">Old syncshell tag name</param>
    /// <param name="newName">New syncshell tag name</param>
    public void RenameSyncshellTag(string oldName, string newName)
    {
        _serverConfigurationManager.RenameSyncshellTag(oldName, newName);
    }

    /// <summary>
    /// Changes the tag to open/close
    /// </summary>
    /// <param name="tag">The Tag that will be modified</param>
    /// <param name="open">True/False</param>
    public void SetTagOpen(string tag, bool open)
    {
        if (open)
        {
            _serverConfigurationManager.AddOpenPairTag(tag);
        }
        else
        {
            _serverConfigurationManager.RemoveOpenPairTag(tag);
        }
    }
}