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;
    }

    /// <inheritdoc/>
    public TimeDto(DateTimeOffset 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();
    }
}