class AuditOverrider < Audited::Audit
  before_save :payjunction_credentials_changes
  before_save :admissions_registration_fields_changes
  before_save :employee_fields_changes
  before_save :save_type
  before_save :save_restore_id
  before_save :student_restore

  before_create { self.user_type = 'User' }

  scope :not_created, -> { where.not(action: 'create') }
  scope :by_auditable_type, ->(type) { where(auditable_type: type) }
  scope :by_auditable_id, ->(id) { where(auditable_id: id) }
  scope :by_associate_type, ->(type) { where(associated_type: type) }
  scope :by_associate_id, ->(id) { where(associated_id: id) }

  def revision
    return super if action.to_sym == :update

    auditable_type.constantize.new(audited_changes)
  end

  private
    def admissions_registration_fields_changes
      return unless auditable_type == 'Admission::RegistrationField'

      audited_changes['field'] = revision.field if audited_changes['field']
    end

    def payjunction_credentials_changes
      return unless auditable_type == 'PayjunctionCredentials'

      audited_changes['username'] = [] if audited_changes['username']
      audited_changes['password'] = [] if audited_changes['password']
    end

    def employee_fields_changes
      return unless auditable_type == 'Employee'

      audited_changes['PIN'] = [] if audited_changes['PIN']
    end

    def save_type
      return if auditable_type == 'Student'

      audited_changes['type'] = auditable.type if auditable['type']
    end

    def save_restore_id
      return unless action.to_sym == :destroy

      audited_changes['id'] = auditable.id
    end

    def student_restore
      return unless action.to_sym == :destroy
      return unless auditable_type == 'Student'

      audited_changes[:restore_ids] = {}
      Student::RESTORE_ASSOCIATIONS.each do |association|
        value = if Student.reflect_on_association(association).macro == :has_one
          auditable.send(association)&.id
        else
          auditable.send("#{association.to_s.singularize}_ids")
        end

        audited_changes[:restore_ids][association] = value
      end
    end
end
