using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
using LightlessSync.UI;
using LightlessSync.API.Data.Extensions;
using LightlessSync.API.Dto.Group;
using LightlessSync.UI.Handlers;
using LightlessSync.UI.Style;
using LightlessSync.UI.Models;
using LightlessSync.WebAPI;
using System.Collections.Immutable;
using System.Numerics;

namespace LightlessSync.UI.Components;

public class DrawGroupedGroupFolder : IDrawFolder
{
    private readonly string _tag;
    private readonly IEnumerable<GroupFolder> _groups;
    private readonly TagHandler _tagHandler;
    private readonly UiSharedService _uiSharedService;
    private readonly ApiController _apiController;
    private readonly SelectSyncshellForTagUi _selectSyncshellForTagUi;
    private readonly RenameSyncshellTagUi _renameSyncshellTagUi;
    private bool _wasHovered = false;
    private float _menuWidth;
    private bool _rowClickArmed;

    public IImmutableList<DrawUserPair> DrawPairs => _groups.SelectMany(g => g.GroupDrawFolder.DrawPairs).ToImmutableList();
    public int OnlinePairs => _groups.SelectMany(g => g.GroupDrawFolder.DrawPairs).Where(g => g.Pair.IsOnline).DistinctBy(g => g.Pair.UserData.UID).Count();
    public int TotalPairs => _groups.Sum(g => g.GroupDrawFolder.TotalPairs);

    public DrawGroupedGroupFolder(IEnumerable<GroupFolder> groups, TagHandler tagHandler, ApiController apiController, UiSharedService uiSharedService, SelectSyncshellForTagUi selectSyncshellForTagUi, RenameSyncshellTagUi renameSyncshellTagUi, string tag)
    {
        _groups = groups;
        _tagHandler = tagHandler;
        _uiSharedService = uiSharedService;
        _selectSyncshellForTagUi = selectSyncshellForTagUi;
        _renameSyncshellTagUi = renameSyncshellTagUi;
        _tag = tag;
        _apiController = apiController;
    }

    public void Draw()
    {
        string _id = "__folder_syncshells";
        if (_tag != "")
        {
            _id = $"__folder_{_tag}";
        }

        using var id = ImRaii.PushId(_id);
        var color = ImRaii.PushColor(ImGuiCol.ChildBg, ImGui.GetColorU32(ImGuiCol.FrameBgHovered), _wasHovered);
        var allowRowClick = string.IsNullOrEmpty(_tag);
        var suppressRowToggle = false;
        using (ImRaii.Child("folder__" + _id, new System.Numerics.Vector2(UiSharedService.GetWindowContentRegionWidth() - ImGui.GetCursorPosX(), ImGui.GetFrameHeight())))
        {
            ImGui.Dummy(new Vector2(0f, ImGui.GetFrameHeight()));
            using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, new Vector2(0f, 0f)))
                ImGui.SameLine();

            var icon = _tagHandler.IsTagOpen(_id) ? FontAwesomeIcon.CaretDown : FontAwesomeIcon.CaretRight;
            ImGui.AlignTextToFramePadding();

            _uiSharedService.IconText(icon);
            if (ImGui.IsItemClicked())
            {
                _tagHandler.SetTagOpen(_id, !_tagHandler.IsTagOpen(_id));
                suppressRowToggle = true;
            }

            ImGui.SameLine();
            ImGui.AlignTextToFramePadding();

            if (_tag != "")
            {
                _uiSharedService.IconText(FontAwesomeIcon.FolderPlus);
            } 
            else
            {
                _uiSharedService.IconText(FontAwesomeIcon.UsersRectangle);
            }

            using (ImRaii.PushStyle(ImGuiStyleVar.ItemSpacing, ImGui.GetStyle().ItemSpacing with { X = ImGui.GetStyle().ItemSpacing.X / 2f }))
                {
                    ImGui.SameLine();
                    ImGui.AlignTextToFramePadding();
                    ImGui.TextUnformatted("[" + OnlinePairs.ToString() + "]");
                }
            UiSharedService.AttachToolTip(OnlinePairs + " online in all of your joined syncshells" + Environment.NewLine +
                TotalPairs + " pairs combined in all of your joined syncshells");
            ImGui.SameLine();
            ImGui.AlignTextToFramePadding();
            if (_tag != "")
            {
                ImGui.TextUnformatted(_tag);

                ImGui.SameLine();
                DrawPauseButton();
                ImGui.SameLine();
                DrawMenu(ref suppressRowToggle);
            } else
            {
                ImGui.TextUnformatted("All Syncshells");

                ImGui.SameLine();
                DrawPauseButton();
            }
        }
        color.Dispose();
        var rowHovered = ImGui.IsItemHovered();
        _wasHovered = rowHovered;

        if (allowRowClick)
        {
            if (rowHovered && ImGui.IsMouseClicked(ImGuiMouseButton.Left) && !suppressRowToggle)
            {
                _rowClickArmed = true;
            }

            if (_rowClickArmed && rowHovered && ImGui.IsMouseReleased(ImGuiMouseButton.Left))
            {
                _tagHandler.SetTagOpen(_id, !_tagHandler.IsTagOpen(_id));
                _rowClickArmed = false;
            }

            if (!ImGui.IsMouseDown(ImGuiMouseButton.Left))
            {
                _rowClickArmed = false;
            }
        }
        else
        {
            _rowClickArmed = false;
        }

        if (_wasHovered)
        {
            Selune.RegisterHighlight(ImGui.GetItemRectMin(), ImGui.GetItemRectMax(), spanFullWidth: true);
        }

        ImGui.Separator();

        if (_tagHandler.IsTagOpen(_id))
        {
            using var indent = ImRaii.PushIndent(20f);
            foreach (var entry in _groups)
            {
                entry.GroupDrawFolder.Draw();
            }
        }
    }

    protected void DrawPauseButton()
    {
        if (DrawPairs.Count > 0)
        {
            var isPaused = _groups.Select(g => g.GroupFullInfo).All(g => g.GroupUserPermissions.IsPaused());
            FontAwesomeIcon pauseIcon = isPaused ? FontAwesomeIcon.Play : FontAwesomeIcon.Pause;

            var pauseButtonSize = _uiSharedService.GetIconButtonSize(pauseIcon);
            var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();
            if (_tag != "")
            {
                var spacingX = ImGui.GetStyle().ItemSpacing.X;
                var menuButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.EllipsisV);
                ImGui.SameLine(windowEndX - pauseButtonSize.X - menuButtonSize.X - spacingX);
            }
            else
            {
                ImGui.SameLine(windowEndX - pauseButtonSize.X);
            }


            if (_uiSharedService.IconButton(pauseIcon))
            {
                ChangePauseStateGroups();
            }
        }
    }

    protected void ChangePauseStateGroups()
    {
        foreach(var group in _groups)
        {
            var perm = group.GroupFullInfo.GroupUserPermissions;
            perm.SetPaused(!perm.IsPaused());
            _ = _apiController.GroupChangeIndividualPermissionState(new GroupPairUserPermissionDto(group.GroupFullInfo.Group, new(_apiController.UID), perm));
        }
    }

    protected void DrawMenu(ref bool suppressRowToggle)
    {
        var barButtonSize = _uiSharedService.GetIconButtonSize(FontAwesomeIcon.EllipsisV);
        var windowEndX = ImGui.GetWindowContentRegionMin().X + UiSharedService.GetWindowContentRegionWidth();

        ImGui.SameLine(windowEndX - barButtonSize.X);
        if (_uiSharedService.IconButton(FontAwesomeIcon.EllipsisV))
        {
            suppressRowToggle = true;
            ImGui.OpenPopup("User Flyout Menu");
        }
        if (ImGui.BeginPopup("User Flyout Menu"))
        {
            using (ImRaii.PushId($"buttons-syncshell-{_tag}")) GroupMenu(_menuWidth);
            _menuWidth = ImGui.GetWindowContentRegionMax().X - ImGui.GetWindowContentRegionMin().X;
            ImGui.EndPopup();
        }
    }

    protected void GroupMenu(float menuWidth)
    {
        ImGui.TextUnformatted("Syncshell Group Menu");
        if (_uiSharedService.IconTextButton(FontAwesomeIcon.Users, "Select Syncshells", menuWidth, isInPopup: true))
        {
            _selectSyncshellForTagUi.Open(_tag);
        }
        if (_uiSharedService.IconTextButton(FontAwesomeIcon.Edit, "Rename Syncshell Group", menuWidth, isInPopup: true))
        {
            _renameSyncshellTagUi.Open(_tag);
        }
        if (_uiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Delete Syncshell Group", menuWidth, isInPopup: true) && UiSharedService.CtrlPressed())
        {
            _tagHandler.RemoveSyncshellTag(_tag);
        }
        UiSharedService.AttachToolTip("Hold CTRL to remove this Group permanently.");
    }
}
