class ReeDatetime::DistanceOfTimeInWords

def call(start_time, end_time, **opts)

def call(start_time, end_time, **opts)
  opts = DEFAULT.merge(opts)
  distance_in_minutes = ((end_time.to_time.to_i - start_time.to_time.to_i) / 60.0).round
  distance_in_seconds = (end_time.to_time.to_i - start_time.to_time.to_i).round
  raise ArgumentError, "end_time small than start_time" if distance_in_seconds < 0
  
  case distance_in_minutes
  when 0..1
    return distance_in_minutes == 0 ?
           t('datetime.human.distance_in_words.less_than_x_minutes', count: 1, locale: opts[:locale], default_by_locale: :en) :
           t('datetime.human.distance_in_words.x_minutes', count: distance_in_minutes, locale: opts[:locale], default_by_locale: :en) unless opts[:include_seconds]
    case distance_in_seconds
    when 0..4   then t('datetime.human.distance_in_words.less_than_x_seconds', count: 5, locale: opts[:locale], default_by_locale: :en)
    when 5..9   then t('datetime.human.distance_in_words.less_than_x_seconds', count: 10, locale: opts[:locale], default_by_locale: :en)
    when 10..19 then t('datetime.human.distance_in_words.less_than_x_seconds',count: 20, locale: opts[:locale], default_by_locale: :en)
    when 20..39 then t('datetime.human.distance_in_words.half_a_minute', locale: opts[:locale], default_by_locale: :en)
    when 40..59 then t('datetime.human.distance_in_words.less_than_x_minutes', count: 1, locale: opts[:locale], default_by_locale: :en)
    else             t('datetime.human.distance_in_words.x_minutes', count: 1, locale: opts[:locale], default_by_locale: :en)
    end
  when 2...45           then t('datetime.human.distance_in_words.x_minutes', count: distance_in_minutes, locale: opts[:locale], default_by_locale: :en)
  when 45...90          then t('datetime.human.distance_in_words.about_x_hours', count: 1, locale: opts[:locale], default_by_locale: :en)
    # 90 mins up to 24 hours
  when 90...1440        then t('datetime.human.distance_in_words.about_x_hours',
                               count: (distance_in_minutes.to_f / 60.0).round, locale: opts[:locale], default_by_locale: :en)
    # 24 hours up to 42 hours
  when 1440...2520      then t('datetime.human.distance_in_words.x_days', count: 1, locale: opts[:locale], default_by_locale: :en)
    # 42 hours up to 30 days
  when 2520...43200     then t('datetime.human.distance_in_words.x_days', count: (distance_in_minutes.to_f / 1440.0).round, locale: opts[:locale], default_by_locale: :en)
    # 30 days up to 60 days
  when 43200...86400    then t('datetime.human.distance_in_words.about_x_months', count: (distance_in_minutes.to_f / 43200.0).round, locale: opts[:locale], default_by_locale: :en)
    # 60 days up to 365 days
  when 86400...525600   then t('datetime.human.distance_in_words.x_months', count: (distance_in_minutes.to_f / 43200.0).round, locale: opts[:locale], default_by_locale: :en)
  else
    start_year = start_time.year
    start_year += 1 if start_time.month >= 3
    end_year = end_time.year
    end_year -= 1 if end_time.month < 3
    leap_years = (start_year > end_year) ? 0 : (start_year..end_year).count { |x| Date.leap?(x) }
    minute_offset_for_leap_year = leap_years * 1440
    # Discount the leap year days when calculating year distance.
    # e.g. if there are 20 leap year days between 2 dates having the same day
    # and month then based on 365 days calculation
    # the distance in years will come out to over 80 years when in written
    # English it would read better as about 80 years.
    minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
    remainder = (minutes_with_offset % MINUTES_IN_YEAR)
    distance_in_years = (minutes_with_offset.div MINUTES_IN_YEAR)
    if remainder < MINUTES_IN_QUARTER_YEAR
      t('datetime.human.distance_in_words.about_x_years', count: distance_in_years, locale: opts[:locale], default_by_locale: :en)
    elsif remainder < MINUTES_IN_THREE_QUARTERS_YEAR
      t('datetime.human.distance_in_words.over_x_years', count: distance_in_years, locale: opts[:locale], default_by_locale: :en)
    else
      t('datetime.human.distance_in_words.almost_x_years', count: distance_in_years + 1, locale: opts[:locale], default_by_locale: :en)
    end
  end
end