using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Utility;
using LightlessSync.API.Dto.Group;
using LightlessSync.UI.Handlers;

using System.Numerics;

namespace LightlessSync.UI.Components;

public class SelectTagForSyncshellUi
{
    private readonly TagHandler _tagHandler;
    private readonly UiSharedService _uiSharedService;

    /// <summary>
    /// The group UI is always open for a specific pair. This defines which pair the UI is open for.
    /// </summary>
    /// <returns></returns>
    private GroupFullInfoDto? _group;

    /// <summary>
    /// Should the panel show, yes/no
    /// </summary>
    private bool _show;

    /// <summary>
    /// For the add category option, this stores the currently typed in tag name
    /// </summary>
    private string _tagNameToAdd = "";

    public SelectTagForSyncshellUi(TagHandler tagHandler, UiSharedService uiSharedService)
    {
        _show = false;
        _group = null;
        _tagHandler = tagHandler;
        _uiSharedService = uiSharedService;
    }

    public void Draw()
    {
        if (_group == null)
        {
            return;
        }

        var name = _group.GroupAliasOrGID;
        var popupName = $"Choose Groups for {_group.GroupAliasOrGID}";
        // Is the popup supposed to show but did not open yet? Open it
        if (_show)
        {
            ImGui.OpenPopup(popupName);
            _show = false;
        }

        if (ImGui.BeginPopup(popupName))
        {
            var tags = _tagHandler.GetAllSyncshellTagsSorted();
            var childHeight = tags.Count != 0 ? tags.Count * 25 : 1;
            var childSize = new Vector2(0, childHeight > 100 ? 100 : childHeight) * ImGuiHelpers.GlobalScale;

            ImGui.TextUnformatted($"Select the groups you want {name} to be in.");
            if (ImGui.BeginChild(name + "##listGroups", childSize))
            {
                foreach (var tag in tags)
                {
                    using (ImRaii.PushId($"groups-syncshell-{_group.GID}-{tag}")) DrawGroupName(_group, tag);
                }
                ImGui.EndChild();
            }

            ImGui.Separator();
            ImGui.TextUnformatted($"Create a new group for {name}.");
            if (_uiSharedService.IconButton(FontAwesomeIcon.Plus))
            {
                HandleAddTag();
            }
            ImGui.SameLine();
            ImGui.InputTextWithHint("##category_name", "New Group", ref _tagNameToAdd, 20);
            if (ImGui.IsKeyDown(ImGuiKey.Enter))
            {
                HandleAddTag();
            }
            ImGui.EndPopup();
        }
    }

    public void Open(GroupFullInfoDto group)
    {
        _group = group;
        // Using "_show" here to de-couple the opening of the popup
        // The popup name is derived from the name the user currently sees, which is
        // based on the showUidForEntry dictionary.
        // We'd have to derive the name here to open it popup modal here, when the Open() is called
        _show = true;
    }

    private void DrawGroupName(GroupFullInfoDto group, string name)
    {
        var hasTag = _tagHandler.HasSyncshellTag(group.GID, name);
        if (ImGui.Checkbox(name, ref hasTag))
        {
            if (hasTag)
            {
                _tagHandler.AddTagToSyncshell(group.GID, name);
            }
            else
            {
                _tagHandler.RemoveTagFromSyncshell(group.GID, name);
            }
        }
    }

    private void HandleAddTag()
    {
        if (!_tagNameToAdd.IsNullOrWhitespace())
        {
            _tagHandler.AddSyncshellTag(_tagNameToAdd);
            if (_group != null)
            {
                _tagHandler.AddTagToSyncshell(_group.GID, _tagNameToAdd);
            }
            _tagNameToAdd = string.Empty;
        }
        else
        {
            _tagNameToAdd = string.Empty;
        }
    }
}