class ApplicationRecord < ActiveRecord::Base
  include FindOrBuildable

  self.abstract_class = true

  after_find :encode_strings_to_utf8

  before_save :encode_strings_to_latin1

  after_save :encode_strings_to_utf8

  def self.associations_for(context)
    yield Associator.new(self, context)
  end

  def self.extract_inserts_into_active_record(sql_statements)
    objects = []
    model_by_table = ApplicationRecord.subclasses.index_by(&:table_name)

    sql_statements.each do |statement|
      table = statement.match(/\bINTO\b\s*(\w+)/).to_a.last
      model = model_by_table[table]
      next unless model

      column_str, value_str = statement.gsub(/\s|'/, '').scan(/\((.*?)\)/)
      columns, values = [column_str.first.split(','), value_str.first.split(',')]
      params = Hash[columns.zip(values)]
      object = model.new(params)
      object.nullify_dependent_associations
      objects << object
    end

    objects
  end

  def h
    Rails.application.routes.url_helpers
  end

  def encode_strings_to_utf8
    attributes.each do |prop, value|
      next unless value.is_a?(String)

      encoded_value = begin
        value.encode('iso-8859-1', 'utf-8').force_encoding('utf-8')
      rescue
        value
      end

      self[prop] = encoded_value if encoded_value.valid_encoding?
    end
  end

  def encode_strings_to_latin1
    changes.each do |prop, values|
      next unless (value = values.last).is_a?(String)

      self[prop] = value.encode('utf-8', 'iso-8859-1')
    end
  end

  def nullify_dependent_associations
    self.class.reflect_on_all_associations(:belongs_to).each do |association|
      next unless send("#{association.foreign_key}?")
      next if send(association.name)

      self[association.foreign_key] = nil
    end
  end
end
