using System;

namespace AsbCloudApp.Data
{
    /// <summary>
    /// DTO времени
    /// </summary>
    public class TimeDto : IComparable<TimeDto>
    {
        private int hour = 0;
        private int minute = 0;
        private int second = 0;

        /// <summary>
        /// час
        /// </summary>
        public int Hour
        {
            get => hour;
            set
            {
                if (value > 23 || value < 0)
                    throw new ArgumentOutOfRangeException(nameof(Hour), "hour should be in [0; 23]");
                hour = value;
            }
        }

        /// <summary>
        /// минута
        /// </summary>
        public int Minute
        {
            get => minute;
            set
            {
                if (value > 59 || value < 0)
                    throw new ArgumentOutOfRangeException(nameof(minute), "minute should be in [0; 59]");
                minute = value;
            }
        }

        /// <summary>
        /// секунда
        /// </summary>
        public int Second
        {
            get => second;
            set
            {
                if (value > 59 || value < 0)
                    throw new ArgumentOutOfRangeException(nameof(second), "second should be in [0; 59]");
                second = value;
            }
        }

        /// <summary>
        /// Кол-во секунд с начала суток
        /// </summary>
        public int TotalSeconds => (Hour * 60 + minute) * 60 + second;

        /// <inheritdoc/>
        public TimeDto()
        { }

        /// <inheritdoc/>
        public TimeDto(int hour = 0, int minute = 0, int second = 0)
        {
            this.hour = hour;
            this.minute = minute;
            this.second = second;
        }

        /// <inheritdoc/>
        public TimeDto(TimeOnly time)
        {
            hour = time.Hour;
            minute = time.Minute;
            second = time.Second;
        }

        /// <inheritdoc/>
        public TimeDto(DateTime fullDate)
        {
            hour = fullDate.Hour;
            minute = fullDate.Minute;
            second = fullDate.Second;
        }

        /// <summary>
        /// Makes System.TimeOnly
        /// </summary>
        /// <returns>System.TimeOnly</returns>
        public TimeOnly MakeTimeOnly() => new(Hour, Minute, Second);

        /// <inheritdoc/>
        public override string ToString()
        {
            var str = $"{Hour:00}:{Minute:00}:{Second:00}";
            return str;
        }

        /// <inheritdoc/>
        public static bool operator ==(TimeDto a, TimeDto b) => a?.TotalSeconds == b?.TotalSeconds;

        /// <inheritdoc/>
        public static bool operator !=(TimeDto a, TimeDto b) => !(a == b);

        /// <inheritdoc/>
        public static bool operator <=(TimeDto a, TimeDto b) => a.TotalSeconds <= b.TotalSeconds;

        /// <inheritdoc/>
        public static bool operator >=(TimeDto a, TimeDto b) => a.TotalSeconds >= b.TotalSeconds;

        /// <inheritdoc/>
        public static bool operator <(TimeDto a, TimeDto b) => a.TotalSeconds < b.TotalSeconds;

        /// <inheritdoc/>
        public static bool operator >(TimeDto a, TimeDto b) => a.TotalSeconds > b.TotalSeconds;

        /// <inheritdoc/>
        public int CompareTo(TimeDto? other)
            => TotalSeconds - other?.TotalSeconds??0;

        /// <inheritdoc/>
        public override bool Equals(object? obj)
        {
            if (ReferenceEquals(this, obj))
            {
                return true;
            }

            if (obj is null)
            {
                return false;
            }

            if (obj is TimeDto objTime)
            {
                return objTime == this;
            }

            return false;
        }

        /// <inheritdoc/>
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
    }
}