1# frozen_string_literal: true
2
3module ChronicDurationAttribute
4  extend ActiveSupport::Concern
5
6  class_methods do
7    def chronic_duration_attr_reader(virtual_attribute, source_attribute)
8      define_method(virtual_attribute) do
9        chronic_duration_attributes[virtual_attribute] || output_chronic_duration_attribute(source_attribute)
10      end
11    end
12
13    def chronic_duration_attr_writer(virtual_attribute, source_attribute, parameters = {})
14      chronic_duration_attr_reader(virtual_attribute, source_attribute)
15
16      define_method("#{virtual_attribute}=") do |value|
17        chronic_duration_attributes[virtual_attribute] = value.presence || parameters[:default].presence.to_s
18
19        begin
20          new_value = value.present? ? ChronicDuration.parse(value).to_i : parameters[:default].presence
21          assign_attributes(source_attribute => new_value)
22        rescue ChronicDuration::DurationParseError
23          # ignore error as it will be caught by validation
24        end
25      end
26
27      validates virtual_attribute, allow_nil: true, duration: { message: parameters[:error_message] }
28    end
29
30    alias_method :chronic_duration_attr, :chronic_duration_attr_writer
31  end
32
33  def chronic_duration_attributes
34    @chronic_duration_attributes ||= {}
35  end
36
37  def output_chronic_duration_attribute(source_attribute)
38    value = attributes[source_attribute.to_s]
39    ChronicDuration.output(value, format: :short) if value
40  end
41end
42