using Connected.Models;
using Connected.Utilities;
using Microsoft.AspNetCore.Components;
using System.Numerics;
using static Connected.Colors;

namespace Connected.Components;
public partial class InputNumber<NumberType>:InputBase where NumberType : INumber<NumberType>
{
	private double _step;
	[Parameter]
	public double Step { 
		get
		{
			return _step;
		}
		set
		{
			_step = value;
			AdjustStep();
		}
	}

	[Parameter]
	public NumberType Value { get; set; }

	[Parameter]
	public int DecimalPlaces { get; set; } =0;


	[Parameter]
    public EventCallback<NumberType> ValueChanged { get; set; }

    public async Task ChangeValueAsync(ChangeEventArgs args)
    {
		if (args.Value is not null)
		{
			NumberType originalValue = (NumberType)Convert.ChangeType(args.Value, typeof(NumberType));
			NumberType value = originalValue;
			if (value.ToString().Length > 0)
			{

				value = AdjustDecimalPlaces(value);
				//await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(value, typeof(NumberType)));
			}
			else
			{
				value = (NumberType)Convert.ChangeType(0, typeof(NumberType));
				//await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(0, typeof(NumberType)));
			}
			Value = value;
			await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(Value, typeof(NumberType)));
		}
	}

	private void AdjustStep()
	{
		if (DecimalPlaces > 0)
		{
			var StepDecmalPlaces = Helper.GetDecimalPlaces(_step);
			if (StepDecmalPlaces > DecimalPlaces)
			{
				double MinStep = 1;
				for (int i = 0; i < DecimalPlaces; i++)
				{
					MinStep = MinStep / 10;
				}
				_step = MinStep;
			}
		}
	}

	private NumberType AdjustDecimalPlaces(NumberType value)
	{
		NumberType result = value;
		if (Helper.NumberHasDecimalPlaces(value))
		{
			if (DecimalPlaces > 0)
			{
				decimal rounded = (decimal)Convert.ChangeType(value, typeof(decimal));
				rounded = Math.Round(rounded, DecimalPlaces);
				result = (NumberType)Convert.ChangeType(rounded, typeof(NumberType));
			}
		}
		return result;
	}

	private async Task Clear()
	{
		await ValueChanged.InvokeAsync((NumberType)Convert.ChangeType(0, typeof(NumberType)));
	}

	#region Lifecycle

	protected override async Task OnInitializedAsync()
	{
		if (DecimalPlaces > 0)
		{
			Value = AdjustDecimalPlaces(Value);
			await ValueChanged.InvokeAsync(Value);
		}
		AdjustStep();
	}

	protected override async Task OnParametersSetAsync()
	{
		if (typeof(NumberType).Name.ToLower().Contains("int"))
		{
			if (Step - (int)Step > 0) Step = (int)Step;
			if (Step < 1) Step = 1;
		}
		await base.OnParametersSetAsync();
    }

    #endregion
}