module Runby
  # Represents a speed consisting of a distance and a unit of time in which that distance was covered
  class Speed
    include Comparable

    attr_reader :distance

    def initialize(distance_or_multiplier, units = :km)
      case distance_or_multiplier
        when Distance
          init_from_distance distance_or_multiplier
        when String
          init_from_string distance_or_multiplier
        when Numeric
          init_from_multiplier(distance_or_multiplier, units)
        when Speed
          init_from_clone distance_or_multiplier
        else
          raise 'Unable to initialize Runby::Speed'
      end
    end

    def to_s(format: :long)
      distance = @distance.to_s(format: format)
      case format
        when :short then "#{distance}/ph"
        when :long then "#{distance} per hour"
      end
    end

    def as_pace
      time = Runby::RunbyTime.from_minutes(60.0 / @distance.multiplier)
      Runby::Pace.new(time, @distance.uom)
    end

    def self.try_parse(description)
      # TODO: hard coding
      distance = Distance.new(:mi, 7)
      speed = Speed.new distance
      { speed: speed }
    end

    def <=>(other)
      if other.is_a? Speed
        @distance <=> other.distance
      elsif other.is_a? String
        # TODO: Parse as Speed when Speed.parse is available
        to_s(format: :short) <=> other || to_s(format: :long) <=> other
      end
    end

    private

    def init_from_clone(other_speed)
      @distance = Distance.new(other_speed.distance)
    end

    def init_from_distance(distance)
      @distance = distance
    end

    def init_from_multiplier(multiplier, uom)
      @distance = Distance.new(uom, multiplier)
    end

    def init_from_string(str)
      results = Speed.try_parse(str)
      unless results[:error]
        init_from_clone results[:speed]
        return
      end
      results = Distance.try_parse(str)
      unless results[:error]
        init_from_distance results[:distance]
        return
      end
      raise "'#{str}' is not recognized as a Speed"
    end
  end
end