class ReactOnRails::Locales::Base

def convert

def convert
  file_names.each do |name|
    template = send(:"template_#{name}")
    path = file(name)
    generate_file(template, path)
  end
end

def default_locale

def default_locale
  @default_locale ||= I18n.default_locale.to_s || "en"
end

def exist_files

def exist_files
  @exist_files ||= files.select { |file| File.exist?(file) }
end

def file(name)

def file(name)
  "#{i18n_dir}/#{name}.#{file_format}"
end

def file_format; end

def file_format; end

def file_names

def file_names
  %w[translations default]
end

def files

def files
  @files ||= file_names.map { |n| file(n) }
end

def files_are_outdated

def files_are_outdated
  latest_yml = locale_files.map { |file| File.mtime(file) }.max
  earliest = exist_files.map { |file| File.mtime(file) }.min
  latest_yml > earliest
end

def flatten(translations)

def flatten(translations)
  translations.each_with_object({}) do |(k, v), h|
    if v.is_a? Hash
      flatten(v).map { |hk, hv| h[:"#{k}.#{hk}"] = hv }
    elsif v.is_a?(String)
      h[k] = v.gsub("%{", "{")
    elsif !v.is_a?(Array)
      h[k] = v
    end
  end
end

def flatten_defaults(val)

def flatten_defaults(val)
  flatten(val).each_with_object({}) do |(k, v), h|
    key = format(k)
    h[key] = { id: k, defaultMessage: v }
  end
end

def format(input)

def format(input)
  input.to_s.tr(".", "_").camelize(:lower).to_sym
end

def generate_file(template, path)

def generate_file(template, path)
  result = ERB.new(template).result
  File.write(path, result)
end

def generate_translations

def generate_translations
  translations = {}
  defaults = {}
  locale_files.each do |f|
    safe_load_options = ReactOnRails.configuration.i18n_yml_safe_load_options || {}
    translation = YAML.safe_load(File.open(f), **safe_load_options)
    key = translation.keys[0]
    val = flatten(translation[key])
    translations = translations.deep_merge(key => val)
    defaults = defaults.deep_merge(flatten_defaults(val)) if key == default_locale
  rescue Psych::Exception => e
    raise ReactOnRails::Error, <<~MSG
      Error parsing #{f}: #{e.message}
      Consider fixing unsafe YAML or permitting with config.i18n_yml_safe_load_options
    MSG
  end
  [translations.to_json, defaults.to_json]
end

def i18n_dir

def i18n_dir
  @i18n_dir ||= ReactOnRails.configuration.i18n_dir
end

def i18n_yml_dir

def i18n_yml_dir
  @i18n_yml_dir ||= ReactOnRails.configuration.i18n_yml_dir
end

def initialize

def initialize
  return if i18n_dir.nil?
  return unless obsolete?
  @translations, @defaults = generate_translations
  convert
end

def locale_files

def locale_files
  @locale_files ||= if i18n_yml_dir.present?
                      Dir["#{i18n_yml_dir}/**/*.yml"]
                    else
                      ReactOnRails::Utils.truthy_presence(
                        Rails.application && Rails.application.config.i18n.load_path
                      ).presence
                    end
end

def obsolete?

def obsolete?
  return true if exist_files.empty?
  files_are_outdated
end

def template_default

def template_default
  <<-JS.strip_heredoc
    import { defineMessages } from 'react-intl';
    const defaultLocale = '#{default_locale}';
    const defaultMessages = defineMessages(#{@defaults});
    export { defaultMessages, defaultLocale };
  JS
end

def template_translations

def template_translations
  <<-JS.strip_heredoc
    export const translations = #{@translations};
  JS
end