using Godot;
using Sfs3.Client.Entities;
using System;
using System.Collections.Generic;

public partial class BuddyList : VBoxContainer
{
	private Action<string> startChatAction;
	private Action<string> blockAction;
	private Action<string> removeAction;
	private Action<string> addAction;

	private readonly Dictionary<string, Node> itemNodes = [];

	public Action<string> StartChatAction
	{
		get => startChatAction;
		set => startChatAction = value;
    }

	public Action<string> BlockAction
	{
		get => blockAction;
		set => blockAction = value;
    }

	public Action<string> RemoveAction
	{
		get => removeAction;
		set => removeAction = value;
    }

	public Action<string> AddAction
	{
		get => addAction;
		set => addAction = value;
    }

	public void AddListItem(Buddy buddy, bool toTop = false)
	{
		// Check if buddy list item already exist
		// This could happen if a temporary buddy is added permanently
		BuddyListItem item = GetListItem(buddy.Name);

        if (item != null)
        {
            item.Update(buddy);
        }
        else
		{
			// Instantiate BuddyListItem and add to dictionary
			Node itemNode = ResourceLoader.Load<PackedScene>("res://scenes/sub/BuddyListItem.tscn").Instantiate();
			itemNodes.Add(buddy.Name, itemNode);

			// Init buddy list item
			item = GetListItem(buddy.Name);
			item.Update(buddy);

			// Set unread messages counter
			// (buddy could have sent messages while user was in the game scene)
			SetItemChatMsgCounter(buddy.Name, BuddyChatHistoryManager.GetUnreadMessagesCount(buddy.Name));

			// Add node to scene
			AddChild(itemNode);

			if (toTop)
				MoveListItemToTop(buddy.Name);

			// Add listeners to buttons
			item.chatButton.Pressed += () => { startChatAction?.Invoke(buddy.Name); };
			item.blockButton.Pressed += () => { blockAction?.Invoke(buddy.Name); };
			item.unblockButton.Pressed += () => { blockAction?.Invoke(buddy.Name); };
			item.removeButton.Pressed += () => { removeAction?.Invoke(buddy.Name); };
			item.addButton.Pressed += () => { addAction?.Invoke(buddy.Name); };
        }
	}

    public void MoveListItemToTop(string buddyName)
    {
		if (itemNodes.TryGetValue(buddyName, out Node item))
			MoveChild(item, 0);
    }

    public void UpdateListItem(Buddy buddy)
    {
        // Get reference to buddy list item corresponding to Buddy
        BuddyListItem item = GetListItem(buddy.Name);

        if (item != null)
        {
            // Check if the update was caused by a block/unblock request
            if (buddy.IsBlocked != item.BuddyBlocked)
            {
				// Move buddy to the bottom of the list if blocked, to top otherwise
				if (buddy.IsBlocked)
					MoveChild(item, GetChildCount() - 1);
                else
                    MoveListItemToTop(buddy.Name);
            }

            // Update buddy list item
            item.Update(buddy);
        }
    }

	private BuddyListItem GetListItem(string buddyName)
    {
        if (itemNodes.TryGetValue(buddyName, out Node item))
			return item.GetNode<BuddyListItem>(".");
		else
			return null;
    }

	public void SetItemState(Buddy buddy)
	{
		GetListItem(buddy.Name)?.Update(buddy);
	}
	
	public void RemoveListItem(string buddyName)
    {
		bool success = itemNodes.TryGetValue(buddyName, out Node item);

		if (success)
		{
			RemoveChild(item);

			itemNodes.Remove(buddyName);
		}
    }

    public void SetItemChatMsgCounter(string buddyName, int cnt)
    {
		BuddyListItem item = GetListItem(buddyName);

		item.UpdateUnreadMsgCounter(cnt);
    }
}
