using Connected.Annotations;
using Connected.Extensions;
using Connected.Utilities;
using Microsoft.AspNetCore.Components;

namespace Connected.Components;

partial class AvatarGroup : UIComponent
{
	private bool _childrenNeedUpdates = false;
	private int _spacing = 3;
	private List<Avatar> _avatars = new();

	private CssBuilder CompiledClassList
	{
		get
		{
			return new CssBuilder("avatar-group")
				.AddClass($"avatar-group-outlined", Outlined)
				.AddClass($"avatar-group-outlined-{OutlineColor.ToDescription()}", Outlined)
				.AddClass(ClassList);
		}
	}

	private CssBuilder CompiledMaxAvatarClassList
	{
		get
		{
			return new CssBuilder("avatar-group-max-avatar")
			  .AddClass($"ms-n{Spacing}")
			 .AddClass(MaxAvatarClass);
		}
	}
		
	/// <summary>
	/// Spacing between avatars where 0 is none and 16 max.
	/// </summary>
	[Parameter]
	public int Spacing
	{
		get => _spacing;
		set
		{
			if (value != _spacing)
			{
				_spacing = value;
				_childrenNeedUpdates = true;
			}
		}
	}

	/// <summary>
	/// A space separated list of class names, added on top of the default class list.
	/// </summary>
	[Parameter]
	public string? ClassList { get; set; }

	/// <summary>
	/// Outlines the grouped avatars to distinguish them, useful when avatars are the same color or uses images.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Appearance)]
	public bool Outlined { get; set; } = true;

	/// <summary>
	/// Sets the color of the outline if its used.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Appearance)]
	public ThemeColor OutlineColor { get; set; } = ThemeColor.Surface;

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

	/// <summary>
	/// If true, MaxAvatar border-radius is set to 0.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Appearance)]
	public bool MaxSquare { get; set; }

	/// <summary>
	/// If true, MaxAvatar will be rounded.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Appearance)]
	public bool MaxRounded { get; set; }

	/// <summary>
	/// Color for the MaxAvatar.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Appearance)]
	public ThemeColor MaxColor { get; set; } = ThemeColor.Default;

	/// <summary>
	/// Size of the MaxAvatar.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Appearance)]
	public Size MaxSize { get; set; } = Size.Medium;

	/// <summary>
	/// Variant of the MaxAvatar.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Appearance)]
	public Variant MaxVariant { get; set; } = Variant.Filled;

	private int _max = 3;

	/// <summary>
	/// Max avatars to show before showing +x avatar, default value 0 has no max.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Behavior)]
	public int Max
	{
		get => _max;
		set
		{
			if (value != _max)
			{
				_max = value;
				_childrenNeedUpdates = true;
			}
		}
	}

	/// <summary>
	/// Custom class/classes for MaxAvatar
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Appearance)]
	public string MaxAvatarClass { get; set; }

	/// <summary>
	/// Child content of the component.
	/// </summary>
	[Parameter]
	[Category(CategoryTypes.AvatarGroup.Behavior)]
	public RenderFragment ChildContent { get; set; }

	internal void AddAvatar(Avatar avatar)
	{
		_avatars.Add(avatar);
		StateHasChanged();
	}

	internal void RemoveAvatar(Avatar avatar)
	{
		_avatars.Remove(avatar);
	}

	internal CssBuilder GetAvatarSpacing() => new CssBuilder()
	  .AddClass($"ms-n{Spacing}");

	internal StyleBuilder GetAvatarZindex(Avatar avatar) => new StyleBuilder()
		.AddStyle("z-index", $"{_avatars.Count - _avatars.IndexOf(avatar)}");

	internal bool MaxGroupReached(Avatar avatar)
	{
		if (_avatars.IndexOf(avatar) < Max)
			return true;
		else
			return false;
	}

	protected override void OnParametersSet()
	{
		base.OnParametersSet();

		if (_childrenNeedUpdates == true)
		{
			foreach (var avatar in _avatars)
			{
				avatar.ForceRedraw();
			}

			_childrenNeedUpdates = false;
		}
	}
}
