using Godot;
using System;

/**
 * Script attached to the main node in the BuddyChatPanel scene.
 */
public partial class BuddyChatPanel : PanelContainer
{
	[Export]
	public RichTextLabel messagesLabel;
	[Export]
	public LineEdit messageInput;
	[Export]
	public Button sendButton;
	[Export]
	public TextureButton closeButton;
	[Export]
	public bool showCloseButton = true;
	[Export]
	public Label withNameLabel;
	[Export]
	public bool disabled;

	private Action<string> sendMessageAction;

	private string userName;
	private string displayName;
	private string lastSenderName;

	public override void _Ready()
	{
		closeButton.Visible = showCloseButton;
		Disabled = disabled;
	}

	public Action<string> SendMessageAction
	{
		get => sendMessageAction;
		set => sendMessageAction = value;
	}

	public string UserName => userName;
	public string DisplayName => displayName;

	public bool Disabled
	{
		get => disabled;

		set
		{
			disabled = value;

			messageInput.Editable = !value;
			sendButton.Disabled = value;
		}
	}

	public void SetUser(string name, string nickname = null)
	{
		userName = name;

		// Display name
		displayName = nickname != null && nickname.Length > 0 ? nickname : name;

		if (displayName != null)
			withNameLabel.Text = "with\n" + displayName;
		else
			withNameLabel.Text = "";
	}

	public void SetVisible()
	{
		Visible = true;
	}

	public void ResetAndHide()
	{
		// Reset
		Reset();

		// Hide
		Visible = false;
	}

	public void Reset()
	{
		// Remove all messages
		messagesLabel.Clear();

		messageInput.Text = "";
		lastSenderName = null;
		Disabled = false;

		SetUser(null);
	}

	public void SetFocus()
	{
		messageInput.GrabFocus();
	}

	/**
	 * Display a chat message.
	 */
	public void PrintChatMessage(string message, string senderName, bool isMe)
	{
		// Print sender name, unless they are the same of the last message
		if (senderName != lastSenderName)
		{
			messagesLabel.AppendText("[color=#ff6c00]" + Escape(senderName) + "[/color]\n");
			lastSenderName = senderName;
		}

		// Print chat message
		messagesLabel.AppendText(Escape(message) + "\n");
	}

	/**
	 * Display a system message.
	 */
	public void PrintSystemMessage(string message)
	{
		messagesLabel.AppendText("[color=#ff6c00][i]" + Escape(message) + "[/i][/color]\n");
	}

	//----------------------------------------------------------
	// UI event listeners
	//----------------------------------------------------------
	#region
	public void OnCloseButtonClick()
	{
		ResetAndHide();
	}

	public void OnSendButtonClick()
	{
		SendMessage();
	}

	public void OnMessageInputSubmit(string msg)
	{
		SendMessage();
	}
	#endregion

	//----------------------------------------------------------
	// Helper methods
	//----------------------------------------------------------
	#region
	private void SendMessage()
	{
		if (sendMessageAction != null && messageInput.Text != "")
		{
			sendMessageAction.Invoke(messageInput.Text);

			messageInput.Text = "";

			SetFocus();
		}
	}

	/**
	 * Prevent user provided text from being interpreted as BBCode markup.
	 */
	private static string Escape(string text)
	{
		return text == null ? "" : text.Replace("[", "[lb]");
	}
	#endregion
}
