using System.Diagnostics.CodeAnalysis;
using Connected.Annotations;
using Connected.Extensions;
using Connected.Utilities;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;

namespace Connected.Components;

public partial class Badge : UIComponent
{
	protected string CompiledClassList =>
	new CssBuilder("badge-root")
	  .AddClass(AdditionalClassList)
	.Build();
	protected string WrapperClass =>
	new CssBuilder("badge-wrapper")
		.AddClass($"badge-{Origin.ToDescription().Replace("-", " ")}")
	.Build();

	protected string BadgeClassName =>
	new CssBuilder("badge")
		.AddClass("badge-dot", Dot)
		.AddClass("badge-bordered", Bordered)
		.AddClass("badge-icon", !string.IsNullOrEmpty(Icon) && !Dot)
		.AddClass($"badge-{Origin.ToDescription().Replace("-", " ")}")
		.AddClass($"elevation-{Elevation.ToString()}")
		.AddClass("theme-" + Color.ToDescription(), Color != ThemeColor.Default)
		.AddClass("badge-default", Color == ThemeColor.Default)
		.AddClass("badge-overlap", Overlap)
		.AddClass(BadgeClass)
	.Build();

	/// <summary>
	/// The placement of the badge.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Appearance)]
	public Origin Origin { get; set; } = Origin.TopRight;

	/// <summary>
	/// The higher the number, the heavier the drop-shadow.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Appearance)]
	public int Elevation { set; get; } = 0;

	/// <summary>
	/// The visibility of the badge.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Behavior)]
	public bool Visible { get; set; } = true;

	/// <summary>
	/// The color of the badge.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Appearance)]
	public ThemeColor Color { get; set; } = ThemeColor.Default;

	/// <summary>
	/// Aligns the badge to bottom.
	/// </summary>
	[ExcludeFromCodeCoverage]
	[Obsolete("Use Origin instead.", true)]
	[Parameter] public bool Bottom { get; set; }

	/// <summary>
	/// Aligns the badge to left.
	/// </summary>
	[ExcludeFromCodeCoverage]
	[Obsolete("Use Origin instead.", true)]
	[Parameter] public bool Left { get => Start; set { Start = value; } }

	/// <summary>
	/// Aligns the badge to the start (Left in LTR and right in RTL).
	/// </summary>
	[ExcludeFromCodeCoverage]
	[Obsolete("Use Origin instead.", true)]
	[Parameter] public bool Start { get; set; }

	/// <summary>
	/// Reduces the size of the badge and hide any of its content.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Behavior)]
	public bool Dot { get; set; }

	/// <summary>
	/// Overlaps the childcontent on top of the content.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Appearance)]
	public bool Overlap { get; set; }

	/// <summary>
	/// Applies a border around the badge.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Appearance)]
	public bool Bordered { get; set; }

	/// <summary>
	/// Sets the Glyph to use in the badge.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Behavior)]
	public string Icon { get; set; }

	/// <summary>
	/// Max value to show when content is integer type.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Behavior)]
	public int Max { get; set; } = 99;

	/// <summary>
	/// Content you want inside the badge. Supported types are string and integer.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Behavior)]
	public object Content { get; set; }

	/// <summary>
	/// Badge class names, separated by space.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Appearance)]
	public string BadgeClass { get; set; }

	/// <summary>
	/// Child content of component, the content that the badge will apply to.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.Badge.Behavior)]
	public RenderFragment ChildContent { get; set; }

	/// <summary>
	/// Button click event if set.
	/// </summary>
	[Parameter] public EventCallback<MouseEventArgs> OnClick { get; set; }

	private string _content;

	internal Task HandleBadgeClick(MouseEventArgs e)
	{
		if (OnClick.HasDelegate)
			return OnClick.InvokeAsync(e);

		return Task.CompletedTask;
	}

	protected override void OnParametersSet()
	{
		if (Content is string stringContent)
		{
			_content = stringContent;
		}
		else if (Content is int numberContent)
		{
			if (numberContent > Max)
			{
				_content = Max + "+";
			}
			else
			{
				_content = numberContent.ToString();
			}
		}
		else
		{
			_content = null;
		}
	}
}
