class RecipeIngredient < ApplicationRecord

  belongs_to :ingredient, optional: true
  belongs_to :recipe, inverse_of: :recipe_ingredients, touch: true

  validates :sort_order, presence: true

  def name
    if self.ingredient_id.present?
      self.ingredient.name
    else
      super
    end
  end

  def display_name
    str = [quantity, units, name].delete_if { |i| i.blank? }.join(' ')
    str << ", #{preparation}" if preparation.present?
    str
  end

  def scale(factor, auto_unit = false)
    if factor.present? && self.quantity.present? && factor != '1'

      value_unit = UnitConversion.parse(self.quantity, self.units)
      value_unit = value_unit.scale(factor)

      if auto_unit
        value_unit = value_unit.auto_unit
      end

      self.quantity = value_unit.pretty_value
      self.units = value_unit.unit.to_s
    end
  end

  def to_metric
    return unless self.quantity.present?
    value_unit = UnitConversion.parse(self.quantity, self.units)
    value_unit = value_unit.to_metric

    self.quantity = value_unit.pretty_value
    self.units = value_unit.unit.to_s
  end

  def to_standard
    return unless self.quantity.present?
    value_unit = UnitConversion.parse(self.quantity, self.units)
    value_unit = value_unit.to_standard

    self.quantity = value_unit.pretty_value
    self.units = value_unit.unit.to_s
  end

  def to_volume
    return unless self.quantity.present?
    if ingredient && ingredient.density
      density = UnitConversion.parse(ingredient.density)
      if density.density?
        value_unit = UnitConversion.parse(self.quantity, self.units)
        value_unit = value_unit.to_volume(density)

        self.quantity = value_unit.pretty_value
        self.units = value_unit.unit.to_s
      end
    end
  end

  def to_mass
    if ingredient
      value_unit = as_value_unit
      density = self.ingredient.density? ? UnitConversion.parse(ingredient.density) : nil

      case
        when value_unit.nil?
        when value_unit.mass?
          self.quantity = value_unit.pretty_value
          self.units = value_unit.unit.to_s
        when value_unit.volume? && density && density.density?
          value_unit = value_unit.to_mass(density)
          self.quantity = value_unit.pretty_value
          self.units = value_unit.unit.to_s
      end
    end
  end

  def custom_unit?
    self.ingredient && self.ingredient.custom_unit_weight(self.units).present?
  end

  def can_convert_to_grams?
    vu = as_value_unit
    vu.present? && (vu.mass? || (vu.volume? && self.ingredient && self.ingredient.density.present?))
  end

  def to_grams
    value_unit = as_value_unit
    gram_unit = value_unit.convert('g', self.ingredient ? self.ingredient.density : nil)
    gram_unit.raw_value
  end

  def as_value_unit
    case
      when self.quantity.blank?
        nil
      when self.custom_unit?
        self.ingredient.custom_unit_weight(self.units).scale(self.quantity)
      when self.units.present?
        UnitConversion.parse(self.quantity, self.units)
      else
        nil
    end
  end

  def log_copy
    copy = RecipeIngredient.new
    copy.ingredient = self.ingredient
    copy.name = self.name
    copy.sort_order = self.sort_order
    copy.quantity = self.quantity
    copy.units = self.units
    copy.preparation = self.preparation

    copy
  end

end
