using Serilog;

namespace TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS
{
	public class Battery : IBattery
	{
		private Battery() { }

		/// <summary>
		/// Holds the current charging level of the battery in percent, double.NaN if unknown.
		/// </summary>
		public double CurrentChargePercent { get; private set; } = double.NaN;

		/// <summary>
		/// Holds the current chargeing level of the battery in bars, null if unkonwn.
		/// </summary>
		public int? CurrentChargeBars { get; private set; } = null;

		/// <summary>
		/// Holds the maximum chargeing level of the battery in bars, null if unkonwn.
		/// </summary>
		public int? MaxChargeBars { get; private set; } = null;

		/// <summary>
		/// Holds whether backend is aware of battery charging level.
		/// </summary>
		public bool? IsBackendAccessible { get; private set; } = null;

		/// <summary>
		/// Holds whether to display battery level or not.
		/// </summary>
		public bool? IsHidden { get; private set; } = null;

		public class Builder
		{
			/// <summary>
			/// Holds the current chargeing level of the battery in bars.
			/// </summary>
			public int? CurrentChargeBars { get; set; } = null;

			/// <summary>
			/// Holds the maximum chargeing level of the battery in bars.
			/// </summary>
			public int? MaxChargeBars { get; set; } = null;

			/// <summary>
			/// Holds the current charging level of the battery in percent.
			/// </summary>
			public double CurrentChargePercent { get; set; } = double.NaN;

			/// <summary>
			/// Holds whether backend is aware of battery charging level.
			/// </summary>
			public bool? IsBackendAccessible { get; set; } = null;

			/// <summary>
			/// Holds whether to display battery level or not.
			/// </summary>
			public bool? IsHidden { get; set; } = null;

			public Battery Build()
			{
				if (!double.IsNaN(CurrentChargePercent)
					&& (CurrentChargePercent < 0 || 100 < CurrentChargePercent))
				{
					// Invalid filling level detected
					CurrentChargePercent = double.NaN;
				}

				if (CurrentChargeBars < 0)
				{
					// Current value of bars must never be smaller zero.
					CurrentChargeBars = null;
				}

				if (MaxChargeBars < 0)
				{
					// Max value of bars must never be smaller zero.
					MaxChargeBars = null;
				}

				if (CurrentChargeBars != null
					&& MaxChargeBars == null)
				{
					// If current charge bars is set, max charge must be set as well.
					Log.ForContext<Battery>().Error($"Current bars value can not be set to {CurrentChargeBars} if max bars is not se.");
					CurrentChargeBars = null;
				}

				if (CurrentChargeBars != null
					&& MaxChargeBars != null
					&& CurrentChargeBars > MaxChargeBars)
				{
					// If current charge bars must never be larger than max charge bars.
					Log.ForContext<Battery>().Error($"Invalid current bars value {CurrentChargeBars} detected. Value must never be largen than max value bars {MaxChargeBars}.");
					CurrentChargeBars = null;
				}

				return new Battery
				{
					CurrentChargeBars = CurrentChargeBars,
					MaxChargeBars = MaxChargeBars,
					CurrentChargePercent = CurrentChargePercent,
					IsBackendAccessible = IsBackendAccessible,
					IsHidden = IsHidden
				};
			}
		}
	}
}