using Connected.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using System.ComponentModel.DataAnnotations;
using System.Security.Cryptography;

namespace Connected.Components;
public partial class MultilineInput : InputBase
{
	#region Parameters

	private int MinRows { get; set; } = 1;

	/// <summary>
	/// Number of rows
	/// </summary>
	[Parameter]
	public int Rows
	{
		get
		{
			return _numRows;
		}
		set
		{
			if (value >= MinRows) _numRows= value;
			else _numRows = MinRows;
		}
	}

	private int _numRows = 1;

	/// <summary>
	/// Value of the TextInput. Used for @bind-Value
	/// </summary>
	[Parameter]
	public string Value { get; set; } = string.Empty;

	#endregion

	#region Events, Methods

	/// <summary>
	/// Event triggered when value changes
	/// </summary>
	[Parameter]
	public EventCallback<string> ValueChanged { get; set; }

	/// <summary>
	/// Method that triggers oninput -> when value inside the component changes
	/// </summary>
	/// <param name="args"></param>
	/// <returns></returns>
	private async Task ChangeValueAsync(ChangeEventArgs args)
	{
		int oldRows = Rows;
		await ValueChanged.InvokeAsync(args?.Value?.ToString());

		int newRows = GetNumberOfLines(args.Value.ToString());

		if (newRows == MinRows)
		{
			Rows = MinRows;
			ChangeAttribute("rows", Rows);
			StateHasChanged();
		}
		else
		{
			Rows = Math.Max(MinRows, newRows);
			if (oldRows < Rows)
			{
				ChangeAttribute("rows", Rows);
				StateHasChanged();
			}
		}
	}

	private int GetNumberOfLines(string s)
	{
		int result = Math.Max(s.Split("\r\n").Length, 1);
		result = Math.Max(s.Split("\r").Length, result);
		result = Math.Max(s.Split("\n").Length, result);
		return result;
	}

	/// <summary>
	/// Clear the value of the TextInput
	/// </summary>
	/// <returns></returns>
	private async Task Clear()
	{
		await ValueChanged.InvokeAsync(string.Empty);
	}

	#endregion

	#region Lifecycle

	private void AddAttribute(string key, object value)
	{
		if (!InputAttributes.ContainsKey(key))
			InputAttributes.Add(key, value);
	}

	private void ChangeAttribute(string key, object value)
	{
		if (InputAttributes.ContainsKey(key)) InputAttributes.Remove(key);
		InputAttributes.Add(key, value);
	}

	protected override void OnInitialized()
	{
		base.OnInitialized();
		MinRows = Rows;
		AddAttribute("rows", MinRows);
	}

	#endregion
}